Couchbase Lite DocumentUpdater does not update the db - android

Here is my code to update the document:
doc.update(new Document.DocumentUpdater() {
#Override
public boolean update(UnsavedRevision newRevision) {
Map < String, Object > properties = newRevision.getUserProperties()
properties.put("timeCreated", "348390284");
properties.put("name", "231321");
return true;
}
});
When I run a query and iterate over the result rows using the following code:
Database db = getDB(ID);
Query query = db.createAllDocumentsQuery();
query.setDescending(true);
try {
QueryEnumerator result = query.run();
for (Iterator<QueryRow> it = result; it.hasNext(); ) {
QueryRow row = it.next();
row.getDocument().getProperties();
}
} catch (CouchbaseLiteException e) {}
row doesn't have any of the updates I put in the updater. I am getting something like this:
row -> size 2
"conflict" -> "size=0"
"rev" -> "1-ac2065458743..."
I am stuck at this point and unsure how to fix it.

UnsavedRevision.getUserProperties() returns the new Map instance. So you need to set it back by calling setUserProperties() method to the revision before returning true.
Following codes is from Couchbase Lite Sample code. LINK
Document doc = database.getDocument(myDocId);
doc.update(new Document.DocumentUpdater() {
#Override
public boolean update(UnsavedRevision newRevision) {
Map<String, Object> properties = newRevision.getUserProperties();
properties.put("title", title);
properties.put("notes", notes);
newRevision.setUserProperties(properties); <<----
return true;
}
});
I hope this helps you.
Thanks!

Related

Sorting and querying documents in couchbase-lite android

What I want to do is finding all records that match some id and sorted by a name. The data looks something like:
{
type:"receiving",
saleName:"Harshitha",
penId:"7aac88118420858d62f5ea55e22"
}
{
type:"receiving",
saleName:"Tom",
penId:"81fb1a79526f4e2bdc77aa7d73d"
}
{
type:"receiving",
saleName:"James",
penId:"81fb1a79526f4e2bdc77aa7d73d"
}
I want to get documents with some specific penID sorted by saleName.
Ex:- I want to get documents with this penId ‘81fb1a79526f4e2bdc77aa7d73d’ and sort them by saleName. Like this order:-
{
type:"receiving",
saleName:"James",
penId:"81fb1a79526f4e2bdc77aa7d73d"
}
{
type:"receiving",
saleName:"Tom",
penId:"81fb1a79526f4e2bdc77aa7d73d"
}
My view like this,
View view = database.getView("receiving_view");
if (view.getMap() == null) {
view.setMap(new Mapper() {
#Override
public void map(Map<String, Object> document, Emitter emitter) {
if (document.get("type").equals("receiving") ) {
List<Object> keys = new ArrayList<Object>();
keys.add(document.get("penId"));
keys.add(document.get("saleName"));
emitter.emit(keys, document);
}
}
}, "1.1");
}
return view;
Then I tried to get data like this,
View view = getView("receiving_view");
Query query = view.createQuery();
List<Object> keys = new ArrayList<Object>();
keys.add("81fb1a79526f4e2bdc77aa7d73d");
List<Object> allKeys = new ArrayList<Object>();
allKeys.add(keys);
query.setKeys(allKeys);
query.run();
It’s not working because I passed one key, but their are two keys in the view… But I can’t pass the ‘saleName’ as a key because I want only to sort by ‘saleName’. What is the best way to do this?
Finally I found the solution. I don’t want to use setKeys here, I should use range of keys, not a specific set of keys.
I set startKey to [penID] and endKey to [penID, {}]. The empty map sorts after any other value, so this key range includes all keys that start with penID. I change my data getting method. Now this is what it is looks like,
View view = getView("receiving_view");
Query query = view.createQuery();
query.setStartKey(Arrays.asList("81fb1a79526f4e2bdc77aa7d73d"));
query.setEndKey(Arrays.asList("81fb1a79526f4e2bdc77aa7d73d", new HashMap<String, Object>()));
query.run();

How to know when SQLite query is finished

Ok, I've got this Retrofit Call that receives a list of objects and insert the into a local SQLite database. I want to display a message saying that the operation was successful with a Ok button that when pressed opens a new activity.
How do I check if my Query has finished so I can show the message?
final ContactApi contactApi = retrofit.create(ContactApi.class);
Call<List<Contact>> callContact = contactApi.getContact(token);
callContact.enqueue(new Callback<List<Contact>>() {
#Override
public void onResponse(Response<List<Contact>> response, Retrofit retrofit) {
List<Contact> contactList = response.body();
if (contactList != null) {
try {
DBHelper dbHelper = new DBHelper(TokenActivity.this, token);
SQLiteDatabase conn = dbHelper.getWritableDatabase();
RepoContact repocontact = new RepoContact(conn);
// Inserts each contact into the database
for (Contatc c : contactList) {
repositorioCadastro.inserirCadastro(c);
Log.i("ACTTOKEN", "Contact insert ID: " + c.getId());
}
} catch (SQLiteException e) {
Log.i("ACTTOKEN", "Faillure on insert: " + e.getMessage());
}
}
wrap your code in try{...}finally{...} blocks with a listener ( beginTransactionWithListener(SQLiteTransactionListener transactionListener)), and use the transactionListner to check whether everything went well within the transaction, in addition to everything within the try/finally.
what you have is good, just try adding finally block..
something like this..
db.beginTransaction();
try {
...
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
You can try a different loop, something like this:
for(int i = 0; i < contactList.size(); i++) {
Contact c = contactList.get(i);
repositorioCadastro.inserirCadastro(c);
Log.i("ACTTOKEN", "Contact insert ID: " + c.getId());
if(i == (contactList.size() - 1)) {
// DO SOMETHING HERE
}
}
You may check insert statement return a long when query successfully executed then long value.
db.insert()
returns the row ID of the newly inserted row, or -1 if an error occurred

Unable to OR two condition in Parse query

I have been trying to OR two condition on two different fields of a table. while individual condition works fine, but when I try to use it both, it doesn't work.
Here is my code :
ParseQuery<NewExamAlert> query = ABC.getQuery();
query.whereContainedIn("category", Arrays.asList(arr)); //here arr is array of different category
query.whereContainedIn("subCategory", Arrays.asList(arr1));//here arr1 is array of different subcategory
query.findInBackground(new FindCallback<ABC>() {
public void done(List<ABC> list, ParseException exp) {
//My Logic
}
}
Please let me know, what am I missing ?
You'll need to explicitly "or" them:
List<ParseQuery<NewExamAlert>> queries = new ArrayList<ParseQuery<NewExamAlert>>();
queries.add( ParseQuery<NewExamAlert> query1 = ABC.getQuery()
.whereContainedIn("category", Arrays.asList(arr)) );
queries.add( ParseQuery<NewExamAlert> query2 = ABC.getQuery()
.whereContainedIn("subCategory", Arrays.asList(arr1)) );
ParseQuery<NewExamAlert> orQuery = ParseQuery.or( queries );
orQuery.findInBackground(new FindCallback<ABC>() {
public void done(List<ABC> list, ParseException exp) {
//Your Logic
}
}

SQLite sort by integer value

I'm using ActiveAndroid library. I need to get a list of my objects sorted by the integer field. here is how I'm trying to do that:
public static List<Category> getCategories() {
try {
return new Select()
.all()
.from(Category.class)
.orderBy("NumInRow ASC") // NumInRow is my int field
.execute();
} catch (Exception ignored) {
return null;
}
}
Am I right?
Yes Absolutely ,what you have done is Correct way to order the column,it doesn't matter whether it is a int or some other data type.
Example :
public static List<Item> getAll(Category category) {
// This is how you execute a query
return new Select()
.from(Item.class)
.where("Category = ?", category.getId())
.orderBy("Name ASC")
.execute();
}
Active Android Complete Guide
Using Active Android

Querying CouchBaseLite Views?

I am querying CouchBaseLite view but I am getting this exception every time I query it. It is not returning the result.
detailMessage: last sequence < 0(-1)
View:
com.couchbase.lite.View viewItemsByDate = database.getView(String.format("%s/%s", designDocName, byDateViewName));
viewItemsByDate.setMap(new Mapper() {
#Override
public void map(Map<String, Object> document, Emitter emitter) {
Object createdAt = document.get("text");
if (createdAt != null) {
emitter.emit(createdAt.toString(), null);
}
}
}, "1.0");
and My query to this view is:
com.couchbase.lite.View view = database.getView(byDateViewName);
Query query = view.createQuery();//database.createAllDocumentsQuery();
List<Object> keyArray = new ArrayList<Object>();
keyArray.add("A");
keyArray.add("B");
query.setKeys(keyArray);
QueryEnumerator rowEnum = query.run();
for (Iterator<QueryRow> it = rowEnum; it.hasNext();) {
QueryRow row = it.next();
Log.d("Document ID:", row.getDocumentId());
}
And I have documents in the database with key "text": "A" and "text": "B" but still it is showing me exception. last sequence < 0(-1)
Why it could not find the rows that I queried for?
The problem is that you are querying a different view name than the view name you defined.
Change
database.getView(String.format("%s/%s", designDocName, byDateViewName));
to
database.getView(byDateViewName);
and it fixes the problem.
See Couchbase Lite Android issue #66

Categories

Resources