Esempio n. 1
0
    int MaxObjectsPerBatch <TObject>(TObjectName tableName, TObject sampleObject, InsertOptions options)
        where TObject : class
    {
        var metadata = DataSource.DatabaseMetadata;

        var table      = metadata.GetTableOrView(tableName);
        var sqlBuilder = table.CreateSqlBuilder(false);

        sqlBuilder.ApplyDesiredColumns(Materializer.NoColumns);
        sqlBuilder.ApplyArgumentValue(DataSource, sampleObject, options);
        sqlBuilder.GetInsertColumns(options.HasFlag(InsertOptions.IdentityInsert)).Count();         //Call .Count() to trigger needed side-effects

        var parametersPerRow = DataSource.GetParameters(sqlBuilder).Count;

        var maxParams = metadata.MaxParameters;

        if (maxParams == null)
        {
            return(int.MaxValue);
        }

        var maxRows = maxParams.Value / parametersPerRow;

        if (metadata.MaxRowsPerValuesClause.HasValue)
        {
            maxRows = Math.Min(metadata.MaxRowsPerValuesClause.Value, maxRows);
        }

        return(maxRows);
    }
Esempio n. 2
0
        /// <summary>
        /// Prepares the command for execution by generating any necessary SQL.
        /// </summary>
        /// <param name="materializer"></param>
        /// <returns><see cref="PostgreSqlCommandExecutionToken" /></returns>
        public override CommandExecutionToken <NpgsqlCommand, NpgsqlParameter> Prepare(Materializer <NpgsqlCommand, NpgsqlParameter> materializer)
        {
            if (materializer == null)
            {
                throw new ArgumentNullException(nameof(materializer), $"{nameof(materializer)} is null.");
            }

            var identityInsert = m_Options.HasFlag(InsertOptions.IdentityInsert);

            if (identityInsert)
            {
                throw new NotImplementedException("See issue 256. https://github.com/TortugaResearch/Tortuga.Chain/issues/256");
            }

            var sqlBuilder = Table.CreateSqlBuilder(StrictMode);

            sqlBuilder.ApplyArgumentValue(DataSource, ArgumentValue, m_Options);
            sqlBuilder.ApplyDesiredColumns(materializer.DesiredColumns());

            if (KeyColumns.Count > 0)
            {
                sqlBuilder.OverrideKeys(KeyColumns);
            }

            var sql = new StringBuilder();

            sqlBuilder.BuildInsertClause(sql, $"INSERT INTO {Table.Name.ToString()} (", null, ")", identityInsert);
            sqlBuilder.BuildValuesClause(sql, " VALUES (", ")", identityInsert);
            sqlBuilder.BuildSelectClause(sql, " RETURNING ", null, ";");

            return(new PostgreSqlCommandExecutionToken(DataSource, "Insert into " + Table.Name, sql.ToString(), sqlBuilder.GetParameters()));
        }
Esempio n. 3
0
        /// <summary>
        /// Prepares the command for execution by generating any necessary SQL.
        /// </summary>
        /// <param name="materializer"></param>
        /// <returns><see cref="SQLiteCommandExecutionToken" /></returns>
        public override CommandExecutionToken <SQLiteCommand, SQLiteParameter> Prepare(Materializer <SQLiteCommand, SQLiteParameter> materializer)
        {
            if (materializer == null)
            {
                throw new ArgumentNullException(nameof(materializer), $"{nameof(materializer)} is null.");
            }

            var identityInsert = m_Options.HasFlag(InsertOptions.IdentityInsert);

            var sqlBuilder = Table.CreateSqlBuilder(StrictMode);

            sqlBuilder.ApplyArgumentValue(DataSource, ArgumentValue, m_Options);
            sqlBuilder.ApplyDesiredColumns(materializer.DesiredColumns());

            if (KeyColumns.Count > 0)
            {
                sqlBuilder.OverrideKeys(KeyColumns);
            }

            var sql = new StringBuilder();

            sqlBuilder.BuildInsertStatement(sql, Table.Name.ToQuotedString(), ";", identityInsert);
            sql.AppendLine();
            sqlBuilder.BuildSelectClause(sql, "SELECT ", null, $" FROM {Table.Name.ToQuotedString()} WHERE ROWID=last_insert_rowid();");

            return(new SQLiteCommandExecutionToken(DataSource, "Insert into " + Table.Name, sql.ToString(), sqlBuilder.GetParameters(), lockType: LockType.Write));
        }
Esempio n. 4
0
        int MaxObjectsPerBatch <TObject>(AbstractObjectName tableName, TObject sampleObject, InsertOptions options)
            where TObject : class
        {
            var table      = DatabaseMetadata.GetTableOrView(tableName);
            var sqlBuilder = table.CreateSqlBuilder(false);

            sqlBuilder.ApplyDesiredColumns(Materializer.NoColumns);
            sqlBuilder.ApplyArgumentValue(this, sampleObject, options);
            sqlBuilder.GetInsertColumns(options.HasFlag(InsertOptions.IdentityInsert)).Count(); //Call .Count() to trigger needed side-effects

            var parametersPerRow = sqlBuilder.GetParameters().Count;

            var maxParams = DatabaseMetadata.MaxParameters;

            if (maxParams == null)
            {
                return(int.MaxValue);
            }

            var maxRows = maxParams.Value / parametersPerRow;

#if SQL_SERVER_SDS || SQL_SERVER_MDS
            //Max rows per VALUES clause is 1000.
            maxRows = Math.Min(1000, maxRows);
#endif
            return(maxRows);
        }
Esempio n. 5
0
        public override CommandExecutionToken <SqlCommand, SqlParameter> Prepare(Materializer <SqlCommand, SqlParameter> materializer)
        {
            if (materializer == null)
            {
                throw new ArgumentNullException(nameof(materializer), $"{nameof(materializer)} is null.");
            }

            var sqlBuilder = m_Table.CreateSqlBuilder(StrictMode);

            sqlBuilder.ApplyDesiredColumns(materializer.DesiredColumns());

            //This sets up the sqlBuilder. We're not actually going to build the parameters now
            sqlBuilder.ApplyArgumentValue(DataSource, m_SourceList[0], m_Options);

            var sql = new StringBuilder();

            bool identityInsert = m_Options.HasFlag(InsertOptions.IdentityInsert);

            if (identityInsert)
            {
                sql.AppendLine($"SET IDENTITY_INSERT {m_Table.Name.ToQuotedString()} ON;");
            }

            sqlBuilder.BuildInsertClause(sql, $"INSERT INTO {m_Table.Name.ToQuotedString()} (", null, ")", identityInsert);
            sqlBuilder.BuildSelectClause(sql, " OUTPUT ", "Inserted.", null);
            sql.AppendLine("VALUES");

            var parameters = new List <SqlParameter>();

            for (var i = 0; i < m_SourceList.Count; i++)
            {
                var parameterSuffix = "_" + i;
                var footer          = (i == m_SourceList.Count - 1) ? ");" : "),";

                sqlBuilder.OverrideArgumentValue(DataSource, AuditRules.OperationTypes.Insert, m_SourceList[i]);
                sqlBuilder.BuildValuesClause(sql, "(", footer, identityInsert, parameterSuffix, parameters, Utilities.ParameterBuilderCallback);
            }

            var maxParams = DataSource.DatabaseMetadata.MaxParameters !.Value;

            if (parameters.Count > maxParams)
            {
                var parametersPerRow = parameters.Count / m_SourceList.Count;
                var maxRows          = maxParams / parametersPerRow;
                throw new InvalidOperationException($"Batch insert exceeds SQL Server's parameter limit of {DataSource.DatabaseMetadata.MaxParameters}. Supply a table type, break the call into batches of {maxRows}, use InsertMultipleBatch, or use BulkInsert");
            }

            if (identityInsert)
            {
                sql.AppendLine($"SET IDENTITY_INSERT {m_Table.Name.ToQuotedString()} OFF;");
            }

            return(new SqlServerCommandExecutionToken(DataSource, "Insert batch into " + m_Table.Name, sql.ToString(), parameters));
        }
Esempio n. 6
0
    /// <summary>
    /// Prepares the command for execution by generating any necessary SQL.
    /// </summary>
    /// <param name="materializer"></param>
    /// <returns><see cref="MySqlCommandExecutionToken" /></returns>
    public override CommandExecutionToken <MySqlCommand, MySqlParameter> Prepare(Materializer <MySqlCommand, MySqlParameter> materializer)
    {
        if (materializer == null)
        {
            throw new ArgumentNullException(nameof(materializer), $"{nameof(materializer)} is null.");
        }

        var identityInsert = m_Options.HasFlag(InsertOptions.IdentityInsert);

        var sqlBuilder = Table.CreateSqlBuilder(StrictMode);

        sqlBuilder.ApplyArgumentValue(DataSource, ArgumentValue, m_Options);
        sqlBuilder.ApplyDesiredColumns(materializer.DesiredColumns());

        if (KeyColumns.Count > 0)
        {
            sqlBuilder.OverrideKeys(KeyColumns);
        }

        var sql = new StringBuilder();

        sqlBuilder.BuildInsertClause(sql, $"INSERT INTO {Table.Name.ToString()} (", null, ")", identityInsert);
        sqlBuilder.BuildValuesClause(sql, " VALUES (", ");", identityInsert);

        if (sqlBuilder.HasReadFields)
        {
            var identityColumn = Table.Columns.Where(c => c.IsIdentity).SingleOrDefault();
            if (!identityInsert && identityColumn != null)
            {
                sqlBuilder.BuildSelectClause(sql, "SELECT ", null, null);
                sql.Append(" FROM " + Table.Name.ToQuotedString());
                sql.Append(" WHERE " + identityColumn.QuotedSqlName + " = LAST_INSERT_ID()");
                sql.Append(";");
            }
            else
            {
                var primaryKeys = Table.PrimaryKeyColumns;
                if (primaryKeys.Count == 0)
                {
                    throw new MappingException($"Insert operation cannot return any values for { Table.Name} because it doesn't have a primary key.");
                }

                sqlBuilder.BuildSelectClause(sql, "SELECT ", null, null);
                sql.Append(" FROM " + Table.Name.ToQuotedString());
                sqlBuilder.BuildWhereClause(sql, " WHERE ", null);
                sql.Append(";");
            }
        }

        return(new MySqlCommandExecutionToken(DataSource, "Insert into " + Table.Name, sql.ToString(), sqlBuilder.GetParameters()));
    }
Esempio n. 7
0
        /// <summary>
        /// Prepares the command for execution by generating any necessary SQL.
        /// </summary>
        /// <param name="materializer"></param>
        /// <returns><see cref="PostgreSqlCommandExecutionToken" /></returns>
        public override CommandExecutionToken <NpgsqlCommand, NpgsqlParameter> Prepare(Materializer <NpgsqlCommand, NpgsqlParameter> materializer)
        {
            if (materializer == null)
            {
                throw new ArgumentNullException(nameof(materializer), $"{nameof(materializer)} is null.");
            }

            var identityInsert = m_Options.HasFlag(InsertOptions.IdentityInsert);

            if (identityInsert)
            {
                throw new NotImplementedException("See issue 256. https://github.com/docevaad/Chain/issues/256");
            }

            var sqlBuilder = m_Table.CreateSqlBuilder(StrictMode);

            sqlBuilder.ApplyDesiredColumns(materializer.DesiredColumns());

            //This sets up the sqlBuilder. We're not actually going to build the parameters now
            sqlBuilder.ApplyArgumentValue(DataSource, m_SourceList[0], m_Options);

            var sql = new StringBuilder();

            sqlBuilder.BuildInsertClause(sql, $"INSERT INTO {m_Table.Name.ToQuotedString()} (", null, ")", identityInsert);
            sql.AppendLine("VALUES");

            var parameters = new List <NpgsqlParameter>();

            for (var i = 0; i < m_SourceList.Count; i++)
            {
                var parameterSuffix = "_" + i;
                var footer          = (i == m_SourceList.Count - 1) ? ")" : "),";

                sqlBuilder.OverrideArgumentValue(DataSource, AuditRules.OperationTypes.Insert, m_SourceList[i]);
                sqlBuilder.BuildValuesClause(sql, "(", footer, identityInsert, parameterSuffix, parameters, Utilities.ParameterBuilderCallback);
            }
            sqlBuilder.BuildSelectClause(sql, " RETURNING ", null, ";");

            var maxParams = DataSource.DatabaseMetadata.MaxParameters !.Value;

            if (parameters.Count > maxParams)
            {
                var parametersPerRow = parameters.Count / m_SourceList.Count;
                var maxRows          = maxParams / parametersPerRow;
                throw new InvalidOperationException($"Batch insert exceeds PostgreSql's parameter limit of {DataSource.DatabaseMetadata.MaxParameters}. Break the call into batches of {maxRows} or use InsertMultipleBatch");
            }

            return(new PostgreSqlCommandExecutionToken(DataSource, "Insert batch into " + m_Table.Name, sql.ToString(), parameters));
        }
Esempio n. 8
0
        /// <summary>
        /// Prepares the command for execution by generating any necessary SQL.
        /// </summary>
        /// <param name="materializer">The materializer.</param>
        /// <returns>ExecutionToken&lt;TCommand&gt;.</returns>

        public override CommandExecutionToken <SqlCommand, SqlParameter> Prepare(Materializer <SqlCommand, SqlParameter> materializer)
        {
            if (materializer == null)
            {
                throw new ArgumentNullException(nameof(materializer), $"{nameof(materializer)} is null.");
            }

            var sqlBuilder = Table.CreateSqlBuilder(StrictMode);

            sqlBuilder.ApplyArgumentValue(DataSource, ArgumentValue, m_Options);
            sqlBuilder.ApplyDesiredColumns(materializer.DesiredColumns());

            if (KeyColumns.Count > 0)
            {
                sqlBuilder.OverrideKeys(KeyColumns);
            }

            var    sql = new StringBuilder();
            string?header;
            string?intoClause;
            string?footer;

            sqlBuilder.UseTableVariable(Table, out header, out intoClause, out footer);
            sql.Append(header);

            bool identityInsert = m_Options.HasFlag(InsertOptions.IdentityInsert);

            if (identityInsert)
            {
                sql.AppendLine($"SET IDENTITY_INSERT {Table.Name.ToQuotedString()} ON;");
            }

            sqlBuilder.BuildInsertClause(sql, $"INSERT INTO {Table.Name.ToQuotedString()} (", null, ")", identityInsert);
            sqlBuilder.BuildSelectClause(sql, " OUTPUT ", "Inserted.", intoClause);
            sqlBuilder.BuildValuesClause(sql, " VALUES (", ")", identityInsert);
            sql.Append(";");

            sql.Append(footer);

            if (identityInsert)
            {
                sql.AppendLine($"SET IDENTITY_INSERT {Table.Name.ToQuotedString()} OFF;");
            }

            return(new SqlServerCommandExecutionToken(DataSource, "Insert into " + Table.Name, sql.ToString(), sqlBuilder.GetParameters()));
        }
Esempio n. 9
0
        /// <summary>
        /// Prepares the command for execution by generating any necessary SQL.
        /// </summary>
        /// <param name="materializer"></param>
        /// <returns><see cref="AccessCommandExecutionToken" /></returns>
        public override CommandExecutionToken <OleDbCommand, OleDbParameter> Prepare(Materializer <OleDbCommand, OleDbParameter> materializer)
        {
            if (materializer == null)
            {
                throw new ArgumentNullException(nameof(materializer), $"{nameof(materializer)} is null.");
            }

            var desiredColumns = materializer.DesiredColumns();
            var identityInsert = m_Options.HasFlag(InsertOptions.IdentityInsert);

            var sqlBuilder = Table.CreateSqlBuilder(StrictMode);

            sqlBuilder.ApplyArgumentValue(DataSource, ArgumentValue, m_Options);
            sqlBuilder.ApplyDesiredColumns(desiredColumns);

            if (KeyColumns.Count > 0)
            {
                sqlBuilder.OverrideKeys(KeyColumns);
            }

            var sql = new StringBuilder();

            sqlBuilder.BuildInsertClause(sql, $"INSERT INTO {Table.Name.ToQuotedString()} (", null, ")", identityInsert);
            sqlBuilder.BuildValuesClause(sql, " VALUES (", ")", identityInsert);
            sql.Append(";");

            var result = new AccessCommandExecutionToken(DataSource, "Insert into " + Table.Name, sql.ToString(), sqlBuilder.GetParameters());

            if (desiredColumns == Materializer.AutoSelectDesiredColumns)
            {
                result.ExecutionMode = AccessCommandExecutionMode.NonQuery;
                result.NextCommand   = new AccessCommandExecutionToken(DataSource, "Fetch autonumber", "SELECT @@IDENTITY", new List <OleDbParameter>());
            }
            else if (desiredColumns.Count > 0)
            {
                result.ExecutionMode             = AccessCommandExecutionMode.NonQuery;
                result.NextCommand               = new AccessCommandExecutionToken(DataSource, "Fetch autonumber", "SELECT @@IDENTITY", new List <OleDbParameter>());
                result.NextCommand.ExecutionMode = AccessCommandExecutionMode.ExecuteScalarAndForward;
                result.NextCommand.ForwardResult = value => { result.NextCommand.NextCommand = PrepareNext(desiredColumns, value); };
            }

            return(result);
        }
Esempio n. 10
0
    public override CommandExecutionToken <SqlCommand, SqlParameter> Prepare(Materializer <SqlCommand, SqlParameter> materializer)
    {
        if (materializer == null)
        {
            throw new ArgumentNullException(nameof(materializer), $"{nameof(materializer)} is null.");
        }

        var sqlBuilder = m_Table.CreateSqlBuilder(StrictMode);

        sqlBuilder.ApplyTableType(DataSource, OperationTypes.Insert, m_TableType.Columns);
        sqlBuilder.ApplyDesiredColumns(materializer.DesiredColumns());

        var sql = new StringBuilder();

        bool identityInsert = m_Options.HasFlag(InsertOptions.IdentityInsert);

        if (identityInsert)
        {
            sql.AppendLine($"SET IDENTITY_INSERT {m_Table.Name.ToQuotedString()} ON;");
        }

        sqlBuilder.BuildInsertClause(sql, $"INSERT INTO {m_Table.Name.ToQuotedString()} (", null, ")", identityInsert);
        sqlBuilder.BuildSelectClause(sql, " OUTPUT ", "Inserted.", null);
        sqlBuilder.BuildSelectTvpForInsertClause(sql, " SELECT ", null, " FROM @ValuesParameter ", identityInsert);
        sql.Append(";");

        if (identityInsert)
        {
            sql.AppendLine($"SET IDENTITY_INSERT {m_Table.Name.ToQuotedString()} OFF;");
        }

        var parameters = sqlBuilder.GetParameters();

        parameters.Add(new SqlParameter()
        {
            ParameterName = "@ValuesParameter",
            Value         = m_Source,
            SqlDbType     = SqlDbType.Structured,
            TypeName      = m_TableType.Name.ToQuotedString()
        });
        return(new SqlServerCommandExecutionToken(DataSource, "Insert batch into " + m_Table.Name, sql.ToString(), parameters));
    }