/**
         * Returns the total number of documents that match the query.
         */
        public int countDocuments(JObject query, bool exactMatch)
        {
            JSONStoreSQLLite store = JSONStoreSQLLite.sharedManager();

            if (store == null)
            {
                throw new JSONStoreException(JSONStoreConstants.JSON_STORE_DATABASE_NOT_OPEN);
            }

            int countResult = 0;

            lock (JSONStore.lockThis)
            {
                if (query != null && query.HasValues)
                {
                    countResult = store.countWithQuery(query, collectionName, exactMatch);
                }
                else
                {
                    countResult = store.count(collectionName);
                }

                return(countResult);
            }
        }
        /**
         * Permanently deletes all the documents stored in a collection and removes the accessor for that collection.
         */
        public bool removeCollection()
        {
            // cannot remove if transaction is in progress, throw exception
            if (JSONStore.transactionInProgress)
            {
                //JSONStoreLoggerError(@"Error: JSON_STORE_TRANSACTION_FAILURE_DURING_REMOVE_COLLECTION, code: %d", rc);
                throw new JSONStoreException(JSONStoreConstants.JSON_STORE_TRANSACTION_FAILURE_DURING_REMOVE_COLLECTION);
            }

            JSONStoreSQLLite store = JSONStoreSQLLite.sharedManager();

            if (store == null)
            {
                //JSONStoreLoggerError(@"Error: JSON_STORE_DATABASE_NOT_OPEN, code: %d", rc);
                throw new JSONStoreException(JSONStoreConstants.JSON_STORE_DATABASE_NOT_OPEN);
            }

            // drop the table
            lock (JSONStore.lockThis)
            {
                bool worked = store.dropTable(collectionName);

                if (!worked)
                {
                    //JSONStoreLoggerError(@"Error: JSON_STORE_ERROR_CLEARING_COLLECTION, code: %d, collection name: %@, accessor username: %@", rc, self.collectionName, accessor != nil ? accessor.username : @"nil");
                    throw new JSONStoreException(JSONStoreConstants.JSON_STORE_ERROR_CLEARING_COLLECTION);
                }
                else
                {
                    JSONStore.removeAccessor(collectionName);
                }

                return(worked);
            }
        }
        public JArray findWithAdvancedQuery(List <JSONStoreQuery> queryParts, JSONStoreQueryOptions options)
        {
            // the results
            JArray results = null;

            // get the shared store
            JSONStoreSQLLite store = JSONStoreSQLLite.sharedManager();

            if (store == null)
            {
                //JSONStoreLoggerError(@"Error: JSON_STORE_DATABASE_NOT_OPEN, code: %d", rc);
                throw new JSONStoreException(JSONStoreConstants.JSON_STORE_DATABASE_NOT_OPEN);
            }

            lock (JSONStore.lockThis)
            {
                results = store.findWithQueryParts(queryParts, collectionName, options);

                if (results == null)
                {
                    // JSONStoreLoggerError(@"Error: JSON_STORE_INVALID_SEARCH_FIELD, code: %d, collection name: %@, accessor username: %@, currentQuery: %@, JSONStoreQueryOptions: %@", rc, self.collectionName, accessor != nil ? accessor.username : @"nil", nil, options);

                    throw new JSONStoreException(JSONStoreConstants.JSON_STORE_INVALID_SEARCH_FIELD);
                }

                return(results);
            }
        }
        /**
         * Replaces documents in the collection with given documents. This method is used to modify documents inside a collection by replacing existing documents with given documents. The field used to perform the replacement is the document unique identifier (_id).
         */
        public int replaceDocuments(JArray documents, bool markDirty)
        {
            // get the shared manager
            JSONStoreSQLLite store = JSONStoreSQLLite.sharedManager();

            if (store == null)
            {
                //JSONStoreLoggerError(@"Error: JSON_STORE_DATABASE_NOT_OPEN, code: %d", rc);
                throw new JSONStoreException(JSONStoreConstants.JSON_STORE_DATABASE_NOT_OPEN);
            }

            int    numReplaced = 0;
            JArray failures    = new JArray();

            lock (JSONStore.lockThis)
            {
                if (!JSONStore.transactionInProgress)
                {
                    //Start transaction
                    store.startTransaction();
                }

                foreach (JToken document in documents)
                {
                    bool worked = store.replace(document, collectionName, markDirty);

                    if (worked)
                    {
                        //It worked, increment the number of docs replaced
                        numReplaced++;
                    }
                    else
                    {
                        //If we can't store all the data, we rollback and go
                        //to the error callback
                        numReplaced = JSONStoreConstants.JSON_STORE_PERSISTENT_STORE_FAILURE;
                        failures.Add(document);
                        break;
                    }
                }

                if (numReplaced < 0)
                {
                    if (!JSONStore.transactionInProgress)
                    {
                        store.rollbackTransaction();
                    }

                    throw new JSONStoreException(JSONStoreConstants.JSON_STORE_REPLACE_DOCUMENTS_FAILURE, failures);
                }

                // things worked, commit
                if (!JSONStore.transactionInProgress)
                {
                    store.commitTransaction();
                }

                return(numReplaced);
            }
        }
Esempio n. 5
0
        private static int provisionCollection(string collectionName, IDictionary <string, string> searchFields, IDictionary <string,
                                                                                                                              string> additionalSearchFields, string username, string password, bool dropFirst)
        {
            // if no username set, use the default
            if (String.IsNullOrEmpty(username))
            {
                username = JSONStoreConstants.JSON_STORE_DEFAULT_USER;
            }

            // get the shared manager
            JSONStoreSQLLite store = JSONStoreSQLLite.sharedManager(username);

            if (store == null)
            {
                //JSONStoreLoggerError(@"Error: JSON_STORE_USERNAME_MISMATCH, code: %d, username passed: %@, accessor username: %@, collection name: %@", JSON_STORE_USERNAME_MISMATCH, username, accessor != nil ? accessor.username : @"nil", collectionName);
                throw new JSONStoreException(JSONStoreConstants.JSON_STORE_USERNAME_MISMATCH);
            }

            if (!String.IsNullOrEmpty(password))
            {
                // set the key for the database
                lock (lockThis)
                {
                    if (!store.setDatabaseKey(username, password))
                    {
                        //JSONStoreLoggerError(@"Error: JSON_STORE_PROVISION_KEY_FAILURE, code: %d, checkForSecurityUpgrade return code: %d, setDBKeyWorked: %@", JSON_STORE_PROVISION_KEY_FAILURE, rc, setDBKeyWorked ? @"YES" : @"NO");
                        throw new JSONStoreException(JSONStoreConstants.JSON_STORE_PROVISION_KEY_FAILURE);
                    }
                }
            }

            int rc = 0;

            lock (lockThis)
            {
                // drop the table if needed
                if (dropFirst)
                {
                    store.dropTable(collectionName);
                }

                // provision the collection for the name, searchFields, and additionalSearchFields

                rc = store.provisionCollection(collectionName, new JSONStoreSchema(searchFields, additionalSearchFields));

                if (rc < JSONStoreConstants.JSON_STORE_RC_OK)
                {
                    //JSONStoreLoggerError(@"Error: JSON_STORE_EXCEPTION, code: %d, username: %@, accessor username: %@, collection name: %@, searchFields: %@, additionalSearchFields: %@", rc, username, accessor != nil ? accessor.username : @"nil", collectionName, searchFields, additionalIndexes);

                    store.close();

                    throw new JSONStoreException(rc);
                }
            }

            return(rc);
        }
Esempio n. 6
0
        /**
         * Committ the user transaction
         */
        public static bool commitTransaction()
        {
            lock (lockThis)
            {
                bool worked = true;

                // get the shared manager
                JSONStoreSQLLite store = JSONStoreSQLLite.sharedManager();

                if (store == null)
                {
                    //JSONStoreLoggerError(@"Error: JSON_STORE_DATABASE_NOT_OPEN, code: %d", rc);
                    // problem getting the shared manager for this username
                    throw new JSONStoreException(JSONStoreConstants.JSON_STORE_DATABASE_NOT_OPEN);
                }

                string username = store.username;

                //long long startTime = wlGetTimeIntervalSince1970();


                if (!transactionInProgress)
                {
                    worked = false;

                    //JSONStoreLoggerError(@"Error: JSON_STORE_NO_TRANSACTION_IN_PROGRESS, code: %d", rc);

                    throw new JSONStoreException(JSONStoreConstants.JSON_STORE_NO_TRANSACTION_IN_PROGRESS);
                }
                else
                {
                    lock (lockThis)
                    {
                        worked = store.commitTransaction();
                    }

                    if (!worked)
                    {
                        transactionInProgress = false;

                        //JSONStoreLoggerError(@"Error: JSON_STORE_TRANSACTION_FAILURE, code: %d", rc);
                        throw new JSONStoreException(JSONStoreConstants.JSON_STORE_TRANSACTION_FAILURE);
                    }

                    transactionInProgress = false;
                }

                //JSONStoreLoggerAnalytics(username != nil ? username : @"", @"", @"commitTransaction", startTime, rc);

                return(worked);
            }
        }
        /**
         * Returns whether the state of the document is dirty or not.
         */
        public bool isDirtyDocument(string documentId)
        {
            JSONStoreSQLLite store = JSONStoreSQLLite.sharedManager();

            if (store == null)
            {
                throw new JSONStoreException(JSONStoreConstants.JSON_STORE_DATABASE_NOT_OPEN);
            }

            lock (JSONStore.lockThis)
            {
                return(store.isDirty(documentId, collectionName));
            }
        }
        /**
         * Stores data as documents in the collection.
         */
        public int addData(JArray jsonArray, bool markDirty, JSONStoreAddOptions options)
        {
            // get the shared manager
            JSONStoreSQLLite store = JSONStoreSQLLite.sharedManager();

            if (store == null)
            {
                //JSONStoreLoggerError(@"Error: JSON_STORE_DATABASE_NOT_OPEN, code: %d", rc);
                throw new JSONStoreException(JSONStoreConstants.JSON_STORE_DATABASE_NOT_OPEN);
            }

            int numWorked = 0;

            lock (JSONStore.lockThis)
            {
                //Start transaction if no user transaction is already open
                if (!JSONStore.transactionInProgress)
                {
                    store.startTransaction();
                }

                foreach (JObject data in jsonArray)
                {
                    // loop through all the data in the array and attempt to store
                    if (store.storeObject(data, collectionName, markDirty, options.additionalSearchFields))
                    {
                        numWorked++;
                    }
                    else
                    {
                        //If we can't store all the data, we rollback and go
                        //to the error callback
                        if (!JSONStore.transactionInProgress)
                        {
                            store.rollbackTransaction();
                        }
                        throw new JSONStoreException(JSONStoreConstants.JSON_STORE_PERSISTENT_STORE_FAILURE);
                    }
                }

                // things worked, commit
                if (!JSONStore.transactionInProgress)
                {
                    store.commitTransaction();
                }
                return(numWorked);
            }
        }
        public int countAllDirtyDocuments()
        {
            JSONStoreSQLLite store = JSONStoreSQLLite.sharedManager();

            if (store == null)
            {
                throw new JSONStoreException(JSONStoreConstants.JSON_STORE_DATABASE_NOT_OPEN);
            }

            lock (JSONStore.lockThis)
            {
                int countResult = store.dirtyCount(collectionName);

                return(countResult);
            }
        }
        /**
         * Get all dirty documents in the collection from the given document array.
         */
        public JArray allDirtyWithDocuments(JArray documents)
        {
            JSONStoreSQLLite store = JSONStoreSQLLite.sharedManager();

            if (store == null)
            {
                throw new JSONStoreException(JSONStoreConstants.JSON_STORE_DATABASE_NOT_OPEN);
            }


            JArray docsToReturn = new JArray();

            lock (JSONStore.lockThis)
            {
                JArray retArr = store.allDirtyInCollection(collectionName);

                if (retArr.Count > 0)
                {
                    foreach (JObject md in retArr)
                    {
                        //If we are passed an array of docs from pushSelected, we
                        //only want to return those that are actually dirty in the database.
                        if (documents.Count > 0)
                        {
                            string dirtyId = md.GetValue(JSONStoreConstants.JSON_STORE_FIELD_ID).ToString();
                            foreach (JObject doc in documents)
                            {
                                if (doc.GetValue(JSONStoreConstants.JSON_STORE_FIELD_ID).ToString().Equals(dirtyId))
                                {
                                    docsToReturn.Add(md);
                                    break;
                                }
                            }
                        }
                        else
                        {
                            docsToReturn.Add(md);
                        }

                        //[JSONStoreCollection _changeJSONBlobToDictionaryWithDictionary:md];
                    }
                }

                return(docsToReturn);
            }
        }
        /**
         * Updates the dirty state of documents passed to clean. If the document was marked for removal it is permanently deleted.
         */
        public int markDocumentsClean(JArray documents)
        {
            JSONStoreSQLLite store = JSONStoreSQLLite.sharedManager();

            if (store == null)
            {
                throw new JSONStoreException(JSONStoreConstants.JSON_STORE_DATABASE_NOT_OPEN);
            }


            int numWorked = 0;

            JArray failedDocs = new JArray();

            lock (JSONStore.lockThis)
            {
                foreach (JObject doc in documents)
                {
                    string docId     = doc.GetValue(JSONStoreConstants.JSON_STORE_FIELD_ID).ToString();
                    string operation = doc.GetValue(JSONStoreConstants.JSON_STORE_FIELD_OPERATION).ToString();

                    bool worked = store.markClean(docId, collectionName, operation);

                    if (worked)
                    {
                        numWorked++;
                    }
                    else
                    {
                        failedDocs.Add(doc);
                    }
                }

                if (failedDocs.Count > 0)
                {
                    //JSONStoreLoggerError(@"Error: JSON_STORE_COULD_NOT_MARK_DOCUMENT_PUSHED, code: %d, collection name: %@, accessor username: %@, failedDocs count: %d, failedDocs: %@, numWorked: %d", JSON_STORE_COULD_NOT_MARK_DOCUMENT_PUSHED, self.collectionName, accessor != nil ? accessor.username : @"nil", [failedDocs count], failedDocs, numWorked);
                    throw new JSONStoreException(JSONStoreConstants.JSON_STORE_COULD_NOT_MARK_DOCUMENT_PUSHED, failedDocs);
                }

                return(numWorked);
            }
        }
Esempio n. 12
0
        /**
         * start a user transaction
         */
        public static bool startTransaction()
        {
            lock (lockThis)
            {
                bool worked = true;

                // get the shared manager
                JSONStoreSQLLite store = JSONStoreSQLLite.sharedManager();

                if (store == null)
                {
                    //JSONStoreLoggerError(@"Error: JSON_STORE_DATABASE_NOT_OPEN, code: %d", rc);
                    throw new JSONStoreException(JSONStoreConstants.JSON_STORE_DATABASE_NOT_OPEN);
                }

                if (transactionInProgress)
                {
                    //JSONStoreLoggerError(@"Error: JSON_STORE_TRANSACTION_IN_PROGRESS, code: %d", rc);
                    throw new JSONStoreException(JSONStoreConstants.JSON_STORE_TRANSACTION_IN_PROGRESS);
                }
                else
                {
                    worked = store.startTransaction();

                    if (!worked)
                    {
                        transactionInProgress = false;

                        //JSONStoreLoggerError(@"Error: JSON_STORE_TRANSACTION_FAILURE, code: %d", rc);
                        throw new JSONStoreException(JSONStoreConstants.JSON_STORE_TRANSACTION_FAILURE);
                    }
                    else
                    {
                        transactionInProgress = true;
                    }
                }

                //JSONStoreLoggerAnalytics(username != nil ? username : @"", @"", @"startTransaction", startTime, rc);

                return(worked);
            }
        }
        /**
         * Stores data as documents in the collection.
         */
        public int remove(JArray documents, JSONStoreRemoveOptions options)
        {
            // get the shared manager
            JSONStoreSQLLite store = JSONStoreSQLLite.sharedManager();

            if (store == null)
            {
                //JSONStoreLoggerError(@"Error: JSON_STORE_DATABASE_NOT_OPEN, code: %d", rc);
                throw new JSONStoreException(JSONStoreConstants.JSON_STORE_DATABASE_NOT_OPEN);
            }

            int    numUpdated = 0;
            JArray failures   = new JArray();

            // loop through each document to remove
            lock (JSONStore.lockThis)
            {
                foreach (JToken document in documents)
                {
                    int lastUpdatedNum = 0;
                    lastUpdatedNum = store.remove(document, collectionName, !options.isErase, options.exact);
                    if (lastUpdatedNum < 0)
                    {
                        // store the failure
                        failures.Add(document);
                    }
                    else
                    {
                        // sucess, update the count
                        numUpdated += lastUpdatedNum;
                    }
                }

                // if failures, return each
                if (failures.Count > 0)
                {
                    //JSONStoreLoggerError(@"Error: JSON_STORE_REMOVE_WITH_QUERIES_FAILURE, code: %d, collection name: %@, accessor username: %@, failures count: %d, query failures: %@", rc, self.collectionName, accessor != nil ? accessor.username : @"nil", [failures count], failures);
                    throw new JSONStoreException(JSONStoreConstants.JSON_STORE_REMOVE_WITH_QUERIES_FAILURE, failures);
                }
                return(numUpdated);
            }
        }
Esempio n. 14
0
        /**
         * Locks access to all the collections until init is called.
         */
        public static bool closeAllCollections()
        {
            bool worked = false;

            // if transaction in process, cannot close, throw exception
            if (transactionInProgress)
            {
                //JSONStoreLoggerError(@"Error: JSON_STORE_TRANSACTION_FAILURE_DURING_CLOSE_ALL, code: %d", JSON_STORE_TRANSACTION_FAILURE_DURING_CLOSE_ALL);
                throw new JSONStoreException(JSONStoreConstants.JSON_STORE_TRANSACTION_FAILURE_DURING_CLOSE_ALL);
            }

            JSONStoreSQLLite store = JSONStoreSQLLite.sharedManager();

            if (store == null)
            {
                // if can't get a store, then we are already closed
                worked = true;
            }
            else if (!store.isOpen())
            {
                // already closed!
                worked = true;
            }
            else
            {
                // not closed, so do the close
                worked = store.close();
            }

            if (worked)
            {
                // clear the collections
                globalJSONStoreCollectionAccessors = null;
            }
            else
            {
                //JSONStoreLoggerError(@"Error: JSON_STORE_ERROR_CLOSING_ALL, code: %d", rc);
                throw new JSONStoreException(JSONStoreConstants.JSON_STORE_ERROR_CLOSING_ALL);
            }
            return(worked);
        }
Esempio n. 15
0
        /**
         * Changes the password associated with the security artifacts used to provide data encryption.
         */
        public static bool changeCurrentPassword(string oldPassword, string newPassword, string username)
        {
            // get the shared manager
            JSONStoreSQLLite store = JSONStoreSQLLite.sharedManager();

            if (store == null)
            {
                //JSONStoreLoggerError(@"Error: JSON_STORE_DATABASE_NOT_OPEN, code: %d", rc);
                throw new JSONStoreException(JSONStoreConstants.JSON_STORE_DATABASE_NOT_OPEN);
            }

            bool worked = store.changePassword(oldPassword, newPassword, username);

            if (!worked)
            {
                //JSONStoreLoggerError(@"Error: JSON_STORE_ERROR_CHANGING_PASSWORD, code: %d, username: %@, newPwdLength: %d, oldPwdLength: %d", rc, username, [newPassword length], [oldPassword length]);
                throw new JSONStoreException(JSONStoreConstants.JSON_STORE_ERROR_CHANGING_PASSWORD);
            }

            return(worked);
        }
Esempio n. 16
0
        /**
         * Destory data in a collection
         */
        public static bool destroyData(string username)
        {
            Boolean destroyAll = true;

            // cannot destory if transaction in progress, throw exception
            if (transactionInProgress)
            {
                //JSONStoreLoggerError(@"Error: JSON_STORE_TRANSACTION_FAILURE_DURING_DESTROY, code: %d", rc);
                throw new JSONStoreException(JSONStoreConstants.JSON_STORE_TRANSACTION_FAILURE_DURING_DESTROY);
            }

            JSONStoreSQLLite store = JSONStoreSQLLite.sharedManager();

            if (!String.IsNullOrEmpty(username))
            {
                destroyAll = false;
            }

            if (store == null && !String.IsNullOrEmpty(username))
            {
                // if store is null, try to find with set username
                store = JSONStoreSQLLite.sharedManager(username);
            }
            else if (store == null && String.IsNullOrEmpty(username))
            {
                //if store is null, try to find with default username
                store = JSONStoreSQLLite.sharedManager(JSONStoreConstants.JSON_STORE_DEFAULT_USER);
            }

            if (store != null && destroyClearKeyChainAndCloseWithAccessor(store, destroyAll))
            {
                return(closeAllCollections());
            }
            else
            {
                //JSONStoreLoggerError(@"Error: JSON_STORE_ERROR_DURING_DESTROY, code: %d, accessor user: %@", rc, accessor != nil ? accessor.username : @"nil");
                throw new JSONStoreException(JSONStoreConstants.JSON_STORE_ERROR_DURING_DESTROY);
            }
        }
        /**
         * Permanently deletes all the documents stored in a collection while preserving the accessor for the collection.
         */
        public bool clearCollection()
        {
            // get the shared manager
            JSONStoreSQLLite store = JSONStoreSQLLite.sharedManager();

            if (store == null)
            {
                //JSONStoreLoggerError(@"Error: JSON_STORE_DATABASE_NOT_OPEN, code: %d", rc);
                throw new JSONStoreException(JSONStoreConstants.JSON_STORE_DATABASE_NOT_OPEN);
            }

            lock (JSONStore.lockThis)
            {
                bool worked = store.clearTable(collectionName);

                if (!worked)
                {
                    // JSONStoreLoggerError(@"Error: JSON_STORE_ERROR_CLEARING_COLLECTION, code: %d, collection name: %@, accessor username: %@", rc, self.collectionName, accessor != nil ? accessor.username : @"nil");
                    throw new JSONStoreException(JSONStoreConstants.JSON_STORE_ERROR_CLEARING_COLLECTION);
                }
                return(worked);
            }
        }
        /**
         * Locates documents inside a collection that matches the query.
         */
        public JArray findWithQueries(JArray queries, JSONStoreQueryOptions options)
        {
            if (options.offset > 0 && options.limit <= 0)
            {
                //JSONStoreLoggerError(@"Error: JSON_STORE_INVALID_OFFSET, code: %d", rc);
                throw new JSONStoreException(JSONStoreConstants.JSON_STORE_INVALID_OFFSET);
            }

            JSONStoreSQLLite store = JSONStoreSQLLite.sharedManager();

            if (store == null)
            {
                throw new JSONStoreException(JSONStoreConstants.JSON_STORE_DATABASE_NOT_OPEN);
            }

            List <string> ids            = new List <string>();
            List <string> jObjectStrings = new List <string>();
            JArray        fullResults    = new JArray();

            lock (JSONStore.lockThis)
            {
                foreach (JToken currentQuery in queries)
                {
                    JArray results = store.find(currentQuery, collectionName, options);

                    if (results != null)
                    {
                        foreach (JObject result in results)
                        {
                            JToken value;
                            if (!result.TryGetValue("_id", out value))
                            {
                                if (!jObjectStrings.Contains(result.ToString()))
                                {
                                    fullResults.Add(result);
                                    jObjectStrings.Add(result.ToString());
                                }
                            }
                            else if (!ids.Contains(value.ToString()))
                            {
                                fullResults.Add(result);
                                ids.Add(value.ToString());
                            }
                        }
                    }
                    else
                    {
                        fullResults = null;

                        //A find failed, break and go to the error callback
                        break;
                    }
                }

                // If we get back a nil array, then the SQL statment was invalid or the database was closed.
                // If we just didn't find anything for a valid SQL statement, then we get back a non-nil empty array.
                if (fullResults == null)
                {
                    //JSONStoreLoggerError(@"Error: JSON_STORE_INVALID_SEARCH_FIELD, code: %d, collection name: %@, accessor username: %@, currentQuery: %@, JSONStoreQueryOptions: %@", rc, self.collectionName, accessor != nil ? accessor.username : @"nil", lastQuery, options);
                    throw new JSONStoreException(JSONStoreConstants.JSON_STORE_INVALID_SEARCH_FIELD);
                }

                return(fullResults);
            }
        }
        public int changeData(JArray dataArray, JSONStoreReplaceOptions options)
        {
            int numUpdatedOrAdded = 0;

            JSONStoreSQLLite store = JSONStoreSQLLite.sharedManager();

            if (store == null)
            {
                //JSONStoreLoggerError(@"Error: JSON_STORE_DATABASE_NOT_OPEN, code: %d", rc);
                throw new JSONStoreException(JSONStoreConstants.JSON_STORE_DATABASE_NOT_OPEN);
            }

            foreach (JObject data in dataArray)
            {
                JArray query = new JArray();

                if (options.replaceCriteria != null)
                {
                    foreach (string sf in options.replaceCriteria)
                    {
                        JToken value;
                        if (data.TryGetValue(sf, out value))
                        {
                            JObject queryObject = new JObject();
                            queryObject.Add(sf, value);
                            query.Add(queryObject);
                        }
                    }
                }

                JArray results = null;
                if (query.Count > 0)
                {
                    JSONStoreQueryOptions queryOptions = new JSONStoreQueryOptions();
                    queryOptions.exact = true;
                    results            = findWithQueries(query, queryOptions);
                }

                if (results != null && results.Count > 0)
                {
                    JArray docsToReplace = new JArray();

                    foreach (JObject obj in results)
                    {
                        JObject doc = new JObject();
                        doc.Add(JSONStoreConstants.JSON_STORE_FIELD_ID, obj.GetValue(JSONStoreConstants.JSON_STORE_FIELD_ID));
                        doc.Add(JSONStoreConstants.JSON_STORE_FIELD_JSON, data);
                        docsToReplace.Add(doc);
                    }

                    int numReplaced = replaceDocuments(docsToReplace, options.markDirty);
                    if (numReplaced > 0)
                    {
                        numUpdatedOrAdded += numReplaced;
                    }
                }
                else
                {
                    if (options.addNew)
                    {
                        JArray addArray = new JArray();
                        addArray.Add(data);
                        int numAdded = addData(addArray, options.markDirty, new JSONStoreAddOptions());
                        numUpdatedOrAdded += numAdded;
                    }
                }
            }

            return(numUpdatedOrAdded);
        }