Esempio n. 1
0
        private void BatchInsert(string tableName, IEnumerable <JObject> items, List <ColumnDefinition> columns)
        {
            if (columns.Count == 0) // we need to have some columns to insert the item
            {
                return;
            }

            // Generate the prepared insert statement
            string sqlBase =
                $"INSERT OR IGNORE INTO {SqlHelpers.FormatTableName(tableName)} ({String.Join(", ", columns.Select(c => c.Name).Select(SqlHelpers.FormatMember))}) VALUES ";

            // Use int division to calculate how many times this record will fit into our parameter quota
            int batchSize = ValidateParameterCount(columns.Count);

            foreach (var batch in items.Split(maxLength: batchSize))
            {
                var sql        = new StringBuilder(sqlBase);
                var parameters = new Dictionary <string, object>();

                foreach (JObject item in batch)
                {
                    AppendInsertValuesSql(sql, parameters, columns, item);
                    sql.Append(",");
                }

                if (parameters.Any())
                {
                    sql.Remove(sql.Length - 1, 1); // remove the trailing comma
                    ExecuteNonQueryInternal(sql.ToString(), parameters);
                }
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Executes a lookup against a local table.
        /// </summary>
        /// <param name="tableName">Name of the local table.</param>
        /// <param name="id">The id of the item to lookup.</param>
        /// <returns>A task that will return with a result when the lookup finishes.</returns>
        public override Task <JObject> LookupAsync(string tableName, string id)
        {
            if (tableName == null)
            {
                throw new ArgumentNullException(nameof(tableName));
            }
            if (id == null)
            {
                throw new ArgumentNullException(nameof(id));
            }

            EnsureInitialized();

            string sql =
                $"SELECT * FROM {SqlHelpers.FormatTableName(tableName)} WHERE {MobileServiceSystemColumns.Id} = @id";
            var parameters = new Dictionary <string, object>
            {
                { "@id", id }
            };

            return(_operationSemaphore.WaitAsync()
                   .ContinueWith(t =>
            {
                try
                {
                    IList <JObject> results = ExecuteQueryInternal(tableName, sql, parameters);
                    return results.FirstOrDefault();
                }
                finally
                {
                    _operationSemaphore.Release();
                }
            }));
        }
Esempio n. 3
0
        internal virtual void CreateTableFromObject(string tableName, IEnumerable <ColumnDefinition> columns)
        {
            ColumnDefinition idColumn = columns.FirstOrDefault(c => c.Name.Equals(MobileServiceSystemColumns.Id));
            var colDefinitions        = columns.Where(c => c != idColumn).Select(c =>
                                                                                 $"{SqlHelpers.FormatMember(c.Name)} {c.StoreType}").ToList();

            if (idColumn != null)
            {
                colDefinitions.Insert(0, $"{SqlHelpers.FormatMember(idColumn.Name)} {idColumn.StoreType} PRIMARY KEY");
            }

            String tblSql =
                $"CREATE TABLE IF NOT EXISTS {SqlHelpers.FormatTableName(tableName)} ({String.Join(", ", colDefinitions)})";

            ExecuteNonQueryInternal(tblSql, parameters: null);

            string infoSql = $"PRAGMA table_info({SqlHelpers.FormatTableName(tableName)});";
            IDictionary <string, JObject> existingColumns = ExecuteQueryInternal("table_info", (TableDefinition)null, infoSql, parameters: null)
                                                            .ToDictionary(c => c.Value <string>("name"), StringComparer.OrdinalIgnoreCase);

            // new columns that do not exist in existing columns
            var columnsToCreate = columns.Where(c => !existingColumns.ContainsKey(c.Name));

            foreach (ColumnDefinition column in columnsToCreate)
            {
                string createSql =
                    $"ALTER TABLE {SqlHelpers.FormatTableName(tableName)} ADD COLUMN {SqlHelpers.FormatMember(column.Name)} {column.StoreType}";
                ExecuteNonQueryInternal(createSql, parameters: null);
            }

            // NOTE: In SQLite you cannot drop columns, only add them.
        }
Esempio n. 4
0
        private void BatchUpdate(string tableName, IEnumerable <JObject> items, List <ColumnDefinition> columns)
        {
            if (columns.Count <= 1)
            {
                return; // For update to work there has to be at least once column besides Id that needs to be updated
            }

            ValidateParameterCount(columns.Count);

            string sqlBase = $"UPDATE {SqlHelpers.FormatTableName(tableName)} SET ";

            foreach (JObject item in items)
            {
                var sql        = new StringBuilder(sqlBase);
                var parameters = new Dictionary <string, object>();

                ColumnDefinition idColumn = columns.FirstOrDefault(c => c.Name.Equals(MobileServiceSystemColumns.Id));
                if (idColumn == null)
                {
                    continue;
                }

                foreach (var column in columns.Where(c => c != idColumn))
                {
                    string paramName = AddParameter(item, parameters, column);

                    sql.AppendFormat("{0} = {1}", SqlHelpers.FormatMember(column.Name), paramName);
                    sql.Append(",");
                }

                if (parameters.Any())
                {
                    sql.Remove(sql.Length - 1, 1); // remove the trailing comma
                }

                sql.AppendFormat(" WHERE {0} = {1}", SqlHelpers.FormatMember(MobileServiceSystemColumns.Id), AddParameter(item, parameters, idColumn));

                ExecuteNonQueryInternal(sql.ToString(), parameters);
            }
        }
Esempio n. 5
0
        /// <summary>
        /// Deletes items from local table with the given list of ids
        /// </summary>
        /// <param name="tableName">Name of the local table.</param>
        /// <param name="ids">A list of ids of the items to be deleted</param>
        /// <returns>A task that completes when delete query has executed.</returns>
        public override Task DeleteAsync(string tableName, IEnumerable <string> ids)
        {
            if (tableName == null)
            {
                throw new ArgumentNullException(nameof(tableName));
            }
            if (ids == null)
            {
                throw new ArgumentNullException(nameof(ids));
            }

            EnsureInitialized();

            string idRange = String.Join(",", ids.Select((_, i) => "@id" + i));

            string sql =
                $"DELETE FROM {SqlHelpers.FormatTableName(tableName)} WHERE {MobileServiceSystemColumns.Id} IN ({idRange})";

            var parameters = new Dictionary <string, object>();

            int j = 0;

            foreach (string id in ids)
            {
                parameters.Add("@id" + (j++), id);
            }

            return(_operationSemaphore.WaitAsync()
                   .ContinueWith(t =>
            {
                try
                {
                    ExecuteNonQueryInternal(sql, parameters);
                }
                finally
                {
                    _operationSemaphore.Release();
                }
            }));
        }