public void UpdateLastSyncCount(string identityId, string datasetName, long lastSyncCount)
        {
            lock (sqlite_lock)
            {
                SQLiteStatement stmt = null;
                try
                {
                    stmt = db.Prepare(
                        DatasetColumns.BuildUpdate(
                            new string[] {
                        DatasetColumns.LAST_SYNC_COUNT,
                        DatasetColumns.LAST_SYNC_TIMESTAMP
                    },
                            RecordColumns.IDENTITY_ID + " = @whereIdentityId AND " +
                            RecordColumns.DATASET_NAME + " = @whereDatasetName"
                            ));

                    stmt.BindInt(1, lastSyncCount);
                    stmt.BindDateTime(2, DateTime.Now);
                    stmt.BindText(3, identityId);
                    stmt.BindText(4, datasetName);

                    stmt.Step();
                }
                finally
                {
                    stmt.FinalizeStm();
                }
            }
        }
        public List <Record> GetModifiedRecords(string identityId, string datasetName)
        {
            lock (sqlite_lock)
            {
                List <Record> records = new List <Record>();

                SQLiteStatement stmt = null;
                try
                {
                    stmt = db.Prepare(
                        RecordColumns.BuildQuery(
                            RecordColumns.IDENTITY_ID + " = @whereIdentityId AND " +
                            RecordColumns.DATASET_NAME + " = @whereDatasetName AND " +
                            RecordColumns.MODIFIED + " = @whereModified"
                            ));

                    stmt.BindText(1, identityId);
                    stmt.BindText(2, datasetName);
                    stmt.BindInt(3, 1);


                    while (stmt.Read())
                    {
                        records.Add(this.SqliteStmtToRecord(stmt));
                    }
                }
                finally
                {
                    stmt.FinalizeStm();
                }
                return(records);
            }
        }
        private bool UpdateDatasetMetadataInternal(string identityId, DatasetMetadata metadata)
        {
            lock (sqlite_lock)
            {
                DatasetMetadata local = this.GetMetadataInternal(identityId, metadata.DatasetName);
                SQLiteStatement stmt  = null;
                try
                {
                    if (local == null)
                    {
                        stmt = db.Prepare(DatasetColumns.BuildInsert());
                        stmt.BindText(1, identityId);
                        stmt.BindText(2, metadata.DatasetName);
                        stmt.BindDateTime(3, metadata.CreationDate);
                        stmt.BindDateTime(4, metadata.LastModifiedDate);
                        stmt.BindInt(5, metadata.RecordCount);
                        stmt.BindInt(6, metadata.StorageSizeBytes);
                        stmt.BindInt(7, 0);
                        stmt.BindInt(8, 0);
                        stmt.BindText(9, null);
                        stmt.Step();
                    }
                    else
                    {
                        stmt = db.Prepare(
                            DatasetColumns.BuildUpdate(
                                new string[] {
                            DatasetColumns.DATASET_NAME,
                            DatasetColumns.CREATION_TIMESTAMP,
                            DatasetColumns.LAST_MODIFIED_TIMESTAMP,
                            DatasetColumns.LAST_MODIFIED_BY,
                            DatasetColumns.RECORD_COUNT,
                            DatasetColumns.STORAGE_SIZE_BYTES
                        },
                                DatasetColumns.IDENTITY_ID + " = @whereIdentityId AND " +
                                DatasetColumns.DATASET_NAME + " = @whereDatasetName"
                                ));

                        stmt.BindText(1, metadata.DatasetName);
                        stmt.BindDateTime(2, metadata.CreationDate);
                        stmt.BindDateTime(3, metadata.LastModifiedDate);
                        stmt.BindText(4, metadata.LastModifiedBy);

                        stmt.BindInt(5, metadata.RecordCount);
                        stmt.BindInt(6, metadata.StorageSizeBytes);

                        stmt.BindText(7, identityId);
                        stmt.BindText(8, metadata.DatasetName);
                        stmt.Step();
                    }
                    return(true);
                }
                finally
                {
                    stmt.FinalizeStm();
                }
            }
        }
        public void DeleteDataset(string identityId, string datasetName)
        {
            lock (sqlite_lock)
            {
                SQLiteStatement stmt = null;
                try
                {
                    stmt = db.Prepare(
                        RecordColumns.BuildDelete(
                            RecordColumns.IDENTITY_ID + " = @whereIdentityId AND " +
                            RecordColumns.DATASET_NAME + " = @whereDatasetName"
                            ));

                    stmt.BindText(1, identityId);
                    stmt.BindText(2, datasetName);
                    stmt.Step();

                    stmt.FinalizeStm();


                    stmt = db.Prepare(
                        DatasetColumns.BuildUpdate(
                            new string[] {
                        DatasetColumns.LAST_MODIFIED_TIMESTAMP,
                        DatasetColumns.LAST_SYNC_COUNT
                    },
                            DatasetColumns.IDENTITY_ID + " = @whereIdentityId AND " +
                            DatasetColumns.DATASET_NAME + " = @whereDatasetName"
                            ));
                    stmt.BindDateTime(1, DateTime.Now);
                    stmt.BindInt(2, -1);
                    stmt.BindText(3, identityId);
                    stmt.BindText(4, datasetName);

                    stmt.Step();
                }
                finally
                {
                    stmt.FinalizeStm();
                }
            }
        }
        private bool PutValueInternal(string identityId, string datasetName, string key, string value)
        {
            lock (sqlite_lock)
            {
                Record record = this.GetRecord(identityId, datasetName, key);

                if (record != null && string.Equals(record.Value, value))
                {
                    return(true);
                }
                SQLiteStatement stmt = null;
                try
                {
                    if (record == null)
                    {
                        stmt = db.Prepare(RecordColumns.BuildInsert());
                        stmt.BindText(1, identityId);
                        stmt.BindText(2, datasetName);
                        stmt.BindText(3, key);
                        stmt.BindText(4, value);
                        stmt.BindInt(5, 0);
                        stmt.BindDateTime(6, DateTime.Now);
                        stmt.BindText(7, "");
                        stmt.BindInt(8, 0);
                        stmt.BindInt(9, 1);
                        stmt.Step();
                        return(true);
                    }
                    else
                    {
                        stmt = db.Prepare(
                            RecordColumns.BuildUpdate(
                                new string[] {
                            RecordColumns.IDENTITY_ID, RecordColumns.DATASET_NAME, RecordColumns.KEY,
                            RecordColumns.VALUE, RecordColumns.MODIFIED, RecordColumns.SYNC_COUNT,
                            RecordColumns.DEVICE_LAST_MODIFIED_TIMESTAMP
                        },
                                RecordColumns.IDENTITY_ID + " = @whereIdentityId AND " +
                                RecordColumns.DATASET_NAME + " = @whereDatasetName AND " +
                                RecordColumns.KEY + " = @whereKey "
                                ));

                        stmt.BindText(1, identityId);
                        stmt.BindText(2, datasetName);
                        stmt.BindText(3, key);
                        stmt.BindText(4, value);
                        stmt.BindInt(5, 1);
                        stmt.BindInt(6, record.SyncCount);
                        stmt.BindDateTime(7, DateTime.Now);
                        stmt.BindText(8, identityId);
                        stmt.BindText(9, datasetName);
                        stmt.BindText(10, key);
                        stmt.Step();
                        return(true);
                    }
                }
                finally
                {
                    stmt.FinalizeStm();
                }
            }
        }
        private void UpdateOrInsertRecord(string identityId, string datasetName, Record record)
        {
            lock (sqlite_lock)
            {
                SQLiteStatement stmt = null;
                try
                {
                    stmt = db.Prepare(
                        RecordColumns.BuildQuery(
                            RecordColumns.IDENTITY_ID + " = @whereIdentityId AND " +
                            RecordColumns.DATASET_NAME + " = @whereDatasetName AND " +
                            RecordColumns.KEY + " = @whereKey "
                            ));

                    stmt.BindText(1, identityId);
                    stmt.BindText(2, datasetName);
                    stmt.BindText(3, record.Key);
                    bool recordsFound = false;

                    while (stmt.Read())
                    {
                        recordsFound = true;
                    }
                    stmt.FinalizeStm();

                    if (recordsFound)
                    {
                        stmt = db.Prepare(
                            RecordColumns.BuildUpdate(
                                new string[] {
                            RecordColumns.VALUE,
                            RecordColumns.SYNC_COUNT,
                            RecordColumns.MODIFIED,
                            RecordColumns.LAST_MODIFIED_TIMESTAMP,
                            RecordColumns.LAST_MODIFIED_BY,
                            RecordColumns.DEVICE_LAST_MODIFIED_TIMESTAMP
                        },
                                RecordColumns.IDENTITY_ID + " = @whereIdentityId AND " +
                                RecordColumns.DATASET_NAME + " = @whereDatasetName AND " +
                                RecordColumns.KEY + " = @whereKey "
                                ));
                        stmt.BindText(1, record.Value);
                        stmt.BindInt(2, record.SyncCount);
                        stmt.BindInt(3, record.IsModified ? 1 : 0);
                        stmt.BindDateTime(4, record.LastModifiedDate);
                        stmt.BindText(5, record.LastModifiedBy);
                        stmt.BindDateTime(6, record.DeviceLastModifiedDate);
                        stmt.BindText(7, identityId);
                        stmt.BindText(8, datasetName);
                        stmt.BindText(9, record.Key);
                        stmt.Step();
                    }
                    else
                    {
                        stmt = db.Prepare(RecordColumns.BuildInsert());
                        stmt.BindText(1, identityId);
                        stmt.BindText(2, datasetName);
                        stmt.BindText(3, record.Key);
                        stmt.BindText(4, record.Value);
                        stmt.BindInt(5, record.SyncCount);
                        stmt.BindDateTime(6, record.LastModifiedDate);
                        stmt.BindText(7, record.LastModifiedBy);
                        stmt.BindDateTime(8, record.DeviceLastModifiedDate);
                        stmt.BindInt(9, record.IsModified ? 1 : 0);
                        stmt.Step();
                    }
                }
                finally
                {
                    stmt.FinalizeStm();
                }
            }
        }