Esempio n. 1
0
        internal virtual void CreateTableFromObject(string tableName, IEnumerable <ColumnDefinition> columns)
        {
            if (!TableExists(tableName))
            {
                //Id in Zumo is nvarchar(255)
                String tblSql = string.Format("CREATE TABLE {0} ({1} nvarchar(255) PRIMARY KEY)",
                                              SqlHelpers.FormatTableName(tableName), SqlHelpers.FormatMember(MobileServiceSystemColumns.Id));
                this.ExecuteNonQuery(tblSql, parameters: null);
            }

            var sql = string.Format("SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name = '{0}'", tableName);
            IDictionary <string, JObject> existingColumns = this.ExecuteQuery((TableDefinition)null, sql, parameters: null)
                                                            .ToDictionary(c => c.Value <string>("COLUMN_NAME"), StringComparer.OrdinalIgnoreCase);

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

            foreach (ColumnDefinition column in columnsToCreate)
            {
                string createSql = string.Format("ALTER TABLE {0} ADD  {1} {2} ",  //we make the other columns nullable
                                                 SqlHelpers.FormatTableName(tableName),
                                                 SqlHelpers.FormatMember(column.Name),
                                                 column.StoreType);
                this.ExecuteNonQuery(createSql, parameters: null);
            }

            //TODO: Should we allow dropping columns?
        }
Esempio n. 2
0
        public override QueryNode Visit(MemberAccessNode nodeIn)
        {
            string memberName = SqlHelpers.FormatMember(nodeIn.MemberName);

            this.sql.Append(memberName);

            return(nodeIn);
        }
Esempio n. 3
0
        public string FormatDelete()
        {
            var delQuery = this.query.Clone(); // create a copy to avoid modifying the original

            delQuery.Selection.Clear();
            delQuery.Selection.Add(MobileServiceSystemColumns.Id);
            delQuery.IncludeTotalCount = false;

            var    formatter     = new SqlQueryFormatter(delQuery);
            string selectIdQuery = formatter.FormatSelect();
            string idMemberName  = SqlHelpers.FormatMember(MobileServiceSystemColumns.Id);
            string tableName     = SqlHelpers.FormatTableName(delQuery.TableName);
            string command       = string.Format("DELETE FROM {0} WHERE {1} IN ({2})", tableName, idMemberName, selectIdQuery);

            this.Parameters = formatter.Parameters;

            return(command);
        }
Esempio n. 4
0
        private Task UpsertAsyncInternal(string tableName, IEnumerable <JObject> items, bool fromServer)
        {
            TableDefinition table = GetTable(tableName);

            var first = items.FirstOrDefault();

            if (first == null)
            {
                return(Task.FromResult(0));
            }

            // Get the columns which we want to map into the database.
            var columns = new List <ColumnDefinition>();

            foreach (var prop in first.Properties())
            {
                ColumnDefinition column;

                // If the column is coming from the server we can just ignore it,
                // otherwise, throw to alert the caller that they have passed an invalid column
                if (!table.TryGetValue(prop.Name, out column) && !fromServer)
                {
                    throw new InvalidOperationException(string.Format(Properties.Resources.SqlStore_ColumnNotDefined, prop.Name, tableName));
                }

                if (column != null)
                {
                    columns.Add(column);
                }
            }

            if (columns.Count == 0)
            {
                // no query to execute if there are no columns in the table
                return(Task.FromResult(0));
            }

            var mergeIntoSql      = String.Format("MERGE INTO {0} AS Target ", SqlHelpers.FormatTableName(tableName));
            var mergeAsSourceSql  = string.Format(" AS SOURCE ({0}) ", String.Join(", ", columns.Select(c => c.Name).Select(SqlHelpers.FormatMember)));
            var mergeConditionSql = string.Format(" ON Target.{0} = Source.{1} ", MobileServiceSystemColumns.Id, MobileServiceSystemColumns.Id);
            var whenMatchedSql    = String.Format(" WHEN MATCHED THEN UPDATE SET {0} ", String.Join(", ", columns.Select(c => c.Name).Select(c => SqlHelpers.FormatMember(c) + " = " + "Source." + SqlHelpers.FormatMember(c))));
            var whenNotMatchedSql = String.Format(" WHEN NOT MATCHED BY TARGET THEN INSERT ({0}) VALUES ({1}); ",
                                                  String.Join(", ", columns.Select(c => c.Name).Select(SqlHelpers.FormatMember)),
                                                  String.Join(", ", columns.Select(c => " Source." + SqlHelpers.FormatMember(c.Name))));

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

            if (batchSize == 0)
            {
                throw new InvalidOperationException(string.Format(Properties.Resources.SqlStore_TooManyColumns, MaxParametersPerUpsertQuery));
            }

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

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

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

                    var upsertSql = mergeIntoSql
                                    + string.Format("USING (VALUES {0})", mergeValues)
                                    + mergeAsSourceSql
                                    + mergeConditionSql
                                    + whenMatchedSql
                                    + whenNotMatchedSql;

                    this.ExecuteNonQuery(upsertSql, parameters);
                }
            }

            return(Task.FromResult(0));
        }
Esempio n. 5
0
        public string FormatSelect()
        {
            var command = new StringBuilder("SELECT ");

            // has top but not skip, use SELECT TOP
            if (this.query.Top.HasValue && query.Top.Value > 0 && !this.query.Skip.HasValue)
            {
                command.AppendFormat(" TOP {0} ", this.query.Top.Value);
            }

            if (this.query.Selection.Any())
            {
                string columnNames = String.Join(", ", this.query.Selection.Select(c => SqlHelpers.FormatMember(c)));
                command.Append(columnNames);
            }
            else
            {
                command.Append("*");
            }

            return(FormatQuery(command.ToString()));
        }