_replicate db does not exists in couchDb on Android - couchdb

I am trying to setup replication between android tablet and a system. I use CouchDbInstance object to setup replication
This is my code
/**
* #param builder
* #param couchDbInstance
* #return the #Link{ReplicationStatus} for the replication command #Link {ReplicationCommand.Builder}
*/
private ReplicationStatus replicate(ReplicationCommand.Builder builder, CouchDbInstance couchDbInstance) {
int retryCount = 0;
ReplicationStatus replicationStatus = null;
while (retryCount < REPLICTAION_RETRY_MAX) {
replicationStatus = couchDbInstance.replicate(builder.build());
if (replicationStatus.isOk()) {
break;
}
retryCount++;
}
return replicationStatus;
}
In couch logs I see POST on _replicate returns 404
We use couchbasemobile and I know its not more supported. Can I know if _replicate way of replication is not supported and should I use _replicator way of replication

I don't know much java, so I'm guessing here, but I think you problem is misunderstanding how _replicate is used.
The documentation here explains: http://wiki.apache.org/couchdb/Replication It's not in the offical docs anymore, as I think they want people to use _replicator.
To start a continuous replication, you POST to _replicate:
{"source":"example-database","target":"target-db", "continuous": true}
In response, you get:
{"ok":true,"_local_id":"127c65ee56bcd253d9a019f5a6f84f16+continuous+create_target"}
To get the status of the replication, you GET _active_tasks. In response, for each active replication, you get:
{"ok":true,"_local_id":"127c65ee56bcd253d9a019f5a6f84f16+continuous+create_target"}
If the "_local_id" is not in _active_tasks, the replication is not happening.
I think that your problem is here:
replicationStatus = couchDbInstance.replicate(builder.build());
I don't know the libraries you're using, but this seems wrong. You should be checking _active_tasks to see if the _local_id is there. Also, you seem to be implementing continuous replication your self.
With couchbasemobile, I have found that there are some bugs with continuous replication, and it is a good idea to periodically GET _active_tasks to check if the continuous replications are still going, restarting them if they're not. But you should still use continuous replication.

Related

Kundera - Cassandra Replication Factor using EntityManagerFactory

I have an application which uses Kundera to generate tables from objects. I want to change Cassandra Replication factor. I use EntityManagerFactory separately to interact with the database for initializing, persisting records, etc.
I know we can create a separate kundera-cassandra.xml file and mention the replication factor. However, this throws an error for me and says keyspace doesn't exist. Also, I don't want to do this.
I want to change replication factor using EntityManagerFactory instead and somehow it doesn't work.
Here is my initialize function:
props.put(KUNDERA_NODES_KEY, host);
props.put(KUNDERA_PORT_KEY, String.valueOf(port));
props.put(KUNDERA_KEYSPACE_KEY, databaseName);
props.put(CassandraConstants.CQL_VERSION,CassandraConstants.CQL_VERSION_3_);
props.put("replication_factor", 2);
entityManagerFactory = Persistence.createEntityManagerFactory(
DataServiceConfiguration.KUNDERA_PERSISTENCE_UNIT, props);
LOG.info("DataServiceImpl initialized with Properties: " + props);
Note: I have tried setting the replication factor value as String as well and also have tried using CassandraConstants. Please let me know what am I doing incorrectly?
This is not possible with the current code. I have added a fix for this in github (track issue #1005).
This fix will be available from next Kundera release or you can build code from source to use it ASAP.
-Karthik

How to modify Server side paging size

I have an OData Web API service using .NET 4.5. It has a WebApi controller derived from EntitySetController:
public class WorkItemsController : EntitySetController<WorkItem, string>
{
[Queryable(PageSize=100)]
public override IQueryable<WorkItem> Get()
{## Heading ##
// go to AWS DynamoDb, get the workitems and then return
}
}
As you can see, I set the server-side page size to 100 by default. Later I realize that I need to increase the size programmatically inside the Get() function. Does anyone know how to do it?
If you want to know the reason, here is why:
AWS DynamoDb doesn't support $skip or $top query. Each time a client wants to get a collection of workitems, I need to get all workitems from DynamoDb. When the number is big, it takes very long time if each time we only return 100 items back to user. So my strategy is to double/triple the number of workitems we return to user each time. So user will get 100, 200, 400, 800 workitems with consecutive requests. Assuming there are 1500 workitems in DynamoDb, I will query only 4 times to return all of them back to user. If we keep a constant pagesize, like 100, I need to query 15 times.
You can invoke the ODataQueryOptions in your method and set the page size.
public IQueryable Get(ODataQueryOptions queryOptions)
{
var settings = new ODataQuerySettings { PageSize = 100 };
var result = GetResult();
return queryOptions.ApplyTo(result, settings);
}
This is exactly the issue, that LINQ2DynamoDB addresses. To support $skip and $top (that is, Enumerable.Skip() and Enumerable.Take()), it caches the results returned by DynamoDb in ElastiCache. So that server-side paging works much more efficiently and the number of read operations is greatly reduced.
Moreover, LINQ2DynamoDB supports OData automatically, so maybe you don't even need to do any WebApi controllers.
Why not trying it? :)

How to resolve conflicts with continuous replication

I'm new to both CouchDB and PouchDB and am using it to create a contact management system that syncs across mobile and desktop devices, and can be used offline. I am seeing that using PouchDB is infinitely easier than having to write a PHP/MySQL backend.
I have been using it successfully, and when I make conflicting changes on offline devices, CouchDB uses an algorithm to arbitrarily pick a winner and then correctly pushes it to all the devices.
What I would like to do is implement a custom algorithm to merge conflicting records. Here is the algorithm I would like to use:
If a record is deleted on one client and merely updated on another,
the updated version wins, unless both clients agree on the delete.
The record with the most recent "modified" timestamp becomes the
master, and the older record becomes the secondary.
Any fields that exist only in the secondary (or are empty in the
master) are moved over to the master.
The master revision is saved and the secondary is deleted.
CouchDB's guide has a good explanation, but I don't have a clue how to implement it with the PouchDB API during a continuous replication. According to the PouchDB API, there is an "onChange" listener in the replicate options, but I don't understand how to use it to intercept conflicts.
If someone could write a brief tutorial including some sample code, myself and I'm sure many other PouchDB users would appreciate it!
Writing an article with examples of exactly how to manage conflict resolution is a really good idea, it can be confusing, but with the lack of one
The idea is the exact same as CouchDB, to resolve conflicts you delete the revisions that didnt win (and write a new winner if needed)
#1 is how CouchDB conflict resolution works anyway, so you dont need to worry about that, deleted leafs dont conflict
function onChange(doc) {
if (!doc._conflicts) return;
collectConflicts(doc._conflicts, function(docs) {
var master = docs.sort(byTime).unshift();
for (var doc in docs) {
for (var prop in doc) {
if (!(prop in master)) {
master[prop] = doc[prop];
}
}
}
db.put(master, function(err) {
if (!err) {
for (var doc in docs) {
db.remove(doc);
}
}
});
});
}
}
db.changes({conflicts: true, onChange: onChange});
This will need error handling etc and could be written much nicer, was just a quick napkin drawing of what the code could look like

Creating record in other databases from CRM 2011

Is there any solution to create record in other DBs from the CRM 2011 records? When a record such as "cost" was created in CRM 2011, we want a record would be created in out Oracle DB. Could it be done through a plugin? Or a service should be created for this?
Could you please provide me references or solutions for this.
Any helps would be greatly appreciated.
We had a similar request from a customer a while ago. They claimed that CRM's database wasn't to be trusted and wanted to securely store a copy of the records created in - guess what - SQL Server too. (Yes, we do understand the irony. They didn't.)
The way we've resolved it was to create a plugin. However, bear in mind that simply reacting to the message of Create won't really do. You need to set up a listener for three of the CRUD operations (retrieval doesn't affect the external database so it's rather C_UD operations, then).
Here's the skeleton of the main Execute method.
public void Execute(IServiceProvider serviceProvider)
{
Context = GetContextFromProvider(serviceProvider);
Service = GetServiceFromProvider(serviceProvider);
switch (Context.MessageName)
{
case "Create": ExecuteCreate(); break;
case "Update": ExecuteUpdate(); break;
case "Delete": ExecuteDelete(); break;
}
}
After this dispatcher, you can implement the actual calls to the other database. There are three gotchas I'd like to give you head-up on.
Remember to provide a suitable value to the outer DB when CRM doesn't offer you one.
Register the plugin as asynchronous since you'll be talking to an external resource.
Consider the problem with entity references, whether to store them recursively as well.
Walk-through for plugin construction
Link to CRM SDK if you haven't got that
Information on registering the plugin
And besides that, I've got a walk-through (including code and structure) on the subject in my blog. The URL to it, you'll have to figure out yourself - I'm not going to self-promote but it's got to do with my name and WP. Google is your friend. :)
You could use a plugin to create a record in another system, although you would need to think about syncing and ensure you don't get duplicates, but it certainly can be done.
Tutorial on plugins can be found here.
You need to write a plugin that runs on Create and uses the information on the created Cost entity to create a record in your Oracle DB.
As an example:
public void Execute(IServiceProvider serviceProvider)
{
var context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
//get the created entity from CRM
var theCreatedEntity = context.InputParameters["Target"] as Entity;
//build up a stored procedure call
using (OracleConnection objConn = new OracleConnection("connection string"))
{
var cmd = new OracleCommand();
cmd.Connection = objConn;
cmd.CommandText = "stored procedure name";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("param1", OracleType.Number).Value = theCreatedEntity.GetAttributeValue<int>("Attribute1");
cmd.Parameters.Add("param2", OracleType.Number).Value = theCreatedEntity.GetAttributeValue<int>("Attribute2");
//etc
cmd.ExecuteNonQuery();
}
}
That should give you enough to get going

MVC 3 EF Code-first to webhost database trouble

Im fairly new to ASP.NET MVC 3, and to coding in general really.
I have a very very small application i want to upload to my webhosting domain.
I am using entity framework, and it works fine on my local machine.
I've entered a new connection string to use my remote database instead however it dosen't really work, first of all i have 1 single MSSQL database, which cannot be de dropped and recreated, so i cannot use that strategy in my initializer, i tried to supply null in the strategy, but to no avail, my tables simply does not get created in my database and thats the problem, i don't know how i am to do that with entity framework.
When i run the application, it tries to select the data from the database, that part works fine, i just dont know how to be able to create those tabes in my database through codefirst.
I could probaly get it to work through manually recreating the tables, but i want to know the solution through codefirst.
This is my initializer class
public class EntityInit : DropCreateDatabaseIfModelChanges<NewsContext>
{
private NewsContext _db = new NewsContext();
protected override void Seed(NewsContext context)
{
new List<News>
{
new News{ Author="Michael Brandt", Title="Test News 1 ", NewsBody="Bblablabalblaaaaa1" },
new News{ Author="Michael Brandt", Title="Test News 2 ", NewsBody="Bblablabalblaaaaa2" },
new News{ Author="Michael Brandt", Title="Test News 3 ", NewsBody="Bblablabalblaaaaa3" },
new News{ Author="Michael Brandt", Title="Test News 4 ", NewsBody="Bblablabalblaaaaa4" },
}.ForEach(a => context.News.Add(a));
base.Seed(context);
}
}
As i said, im really new to all this, so excuse me, if im lacking to provide the proper information you need to answer my question, just me know and i will answer it
Initialization strategies do not support upgrade strategies at the moment.
Initialization strategies should be used to initialise a new database. all subsequent changes should be done using scripts at the moment.
the best practice as we speak is to modify the database with a script, and then adjust by hand the code to reflect this change.
in future releases, upgrade / migration strategies will be available.
try to execute the scripts statement by statement from a custom IDatabaseInitializer
then from this you can read the database version in the db and apply the missing scripts to your database. simply store a db version in a table. then level up with change scripts.
public class Initializer : IDatabaseInitializer<MyContext>
{
public void InitializeDatabase(MyContext context)
{
if (!context.Database.Exists() || !context.Database.CompatibleWithModel(false))
{
context.Database.Delete();
context.Database.Create();
var jobInstanceStateList = EnumExtensions.ConvertEnumToDictionary<JobInstanceStateEnum>().ToList();
jobInstanceStateList.ForEach(kvp => context.JobInstanceStateLookup.Add(
new JobInstanceStateLookup()
{
JobInstanceStateLookupId = kvp.Value,
Value = kvp.Key
}));
context.SaveChanges();
}
}
}
Have you tried to use the CreateDatabaseOnlyIfNotExists
– Every time the context is initialized, database will be recreated if it does not exist.
The database initializer can be set using the SetInitializer method of the Database class.If nothing is specified it will use the CreateDatabaseOnlyIfNotExists class to initialize the database.
Database.SetInitializer(null);
-
Database.SetInitializer<NewsContext>(new CreateDatabaseOnlyIfNotExists<NewsContext>());
I'm not sure if this is the exact syntax as I have not written this in a while. But it should be very similar.
If you are using a very small application, you maybe could go for SQL CE 4.0.
The bin-deployment should allow you to run SQL CE 4.0 even if your provider doesn't have the binaries installed for it. You can read more here.
That we you can actually use whatever initializer you want, since you now don't have the problem of not being able to drop databases and delete tables.
could this be of any help?

Resources