///<summary>Applies an update row to the database.</summary>
        public override void ApplyUpdate(TransactionContext context, SchemaMapping schema, Row row)
        {
            if (context == null) throw new ArgumentNullException("context");
            if (schema == null) throw new ArgumentNullException("schema");
            if (row == null) throw new ArgumentNullException("row");

            var sql = new StringBuilder();

            //UPDATE [SchemaName].[TableName]
            //SET [FirstColumn] = @Col0, [SecondColumn] = @Col1
            //WHERE @IDColumn = @ID AND RowVersion = @version;

            sql.Append("UPDATE ").AppendLine(QualifyTable(schema));
            sql.Append("SET").AppendJoin(
                schema.Columns.Select((c, i) => c.SqlName.EscapeSqlIdentifier() + " = @Col" + i.ToString(CultureInfo.InvariantCulture)), ", "
            ).AppendLine();
            sql.Append("WHERE ").Append(schema.PrimaryKey.SqlName.EscapeSqlIdentifier()).Append(" = @Col").Append(schema.Columns.IndexOf(schema.PrimaryKey))
                                .Append(" AND RowVersion = @version;");

            using (var command = context.CreateCommand(sql.ToString())) {
                PopulateParameters(command, schema, row);

                var versionParameter = command.CreateParameter();
                versionParameter.ParameterName = "@version";
                versionParameter.Value = row.RowVersion;
                command.Parameters.Add(versionParameter);

                if (command.ExecuteNonQuery() != 1)
                    ThrowRowModified(context, schema, row);
            }
            RefreshVersion(context, schema, row);
        }
        ///<summary>Applies an inserted row to the database.</summary>
        public override void ApplyInsert(TransactionContext context, SchemaMapping schema, Row row)
        {
            if (context == null) throw new ArgumentNullException("context");
            if (schema == null) throw new ArgumentNullException("schema");
            if (row == null) throw new ArgumentNullException("row");

            var sql = new StringBuilder();

            //INSERT INTO [SchemaName].[TableName]
            //	([FirstColumn], [SecondColumn])
            //VALUES(@Col0, @Col1);

            sql.Append("INSERT INTO ").AppendLine(QualifyTable(schema));
            sql.Append("\t(").AppendJoin(
                schema.Columns.Select(c => c.SqlName.EscapeSqlIdentifier()), ", "
            ).AppendLine(")");

            sql.Append("VALUES(").AppendJoin(
                schema.Columns.Select((c, i) => "@Col" + i.ToString(CultureInfo.InvariantCulture)), ", "
            ).Append(");");

            using (var command = context.CreateCommand(sql.ToString())) {
                PopulateParameters(command, schema, row);

                if (command.ExecuteNonQuery() != 1)
                    throw new DataException("INSERT command didn't work");
            }

            RefreshVersion(context, schema, row);
        }
Example #3
0
		public SqlTransactionalCommandsContext CreateSqlTransactionalCommandsContext(TransactionContext transactionContext)
		{
			var connection = this.OpenConnection();

			try
			{
				return this.CreateSqlTransactionalCommandsContext(connection, transactionContext);
			}
			catch
			{
				ActionUtils.IgnoreExceptions(() => connection.Dispose());

				throw;
			}
		}
        ///<summary>Applies a deleted row to the database.</summary>
        public void ApplyDelete(TransactionContext context, SchemaMapping schema, Row row)
        {
            if (context == null) throw new ArgumentNullException("context");
            if (schema == null) throw new ArgumentNullException("schema");
            if (row == null) throw new ArgumentNullException("row");

            //Should work fine for SQLCE too
            using (var command = context.CreateCommand(
                "DELETE FROM " + QualifyTable(schema) + " WHERE " + schema.PrimaryKey.SqlName.EscapeSqlIdentifier() + " = @ID AND RowVersion = @version",
                new { ID = row[row.Schema.PrimaryKey], version = row.RowVersion }
            )) {
                if (command.ExecuteNonQuery() != 1)
                    ThrowRowModified(context, schema, row);
            }
        }
        ///<summary>Applies an inserted row to the database.</summary>
        public virtual void ApplyInsert(TransactionContext context, SchemaMapping schema, Row row)
        {
            if (context == null) throw new ArgumentNullException("context");
            if (schema == null) throw new ArgumentNullException("schema");
            if (row == null) throw new ArgumentNullException("row");

            var sql = new StringBuilder();

            //INSERT INTO [SchemaName].[TableName]
            //	([FirstColumn], [SecondColumn])
            //OUTPUT INSERTED.RowVersion
            //VALUES(@Col0, @Col1);

            sql.Append("INSERT INTO ").AppendLine(QualifyTable(schema));
            sql.Append("\t(").AppendJoin(
                schema.Columns.Select(c => c.SqlName.EscapeSqlIdentifier()), ", "
            ).AppendLine(")");

            sql.AppendLine("OUTPUT INSERTED.RowVersion");

            sql.Append("VALUES(").AppendJoin(
                schema.Columns.Select((c, i) => "@Col" + i.ToString(CultureInfo.InvariantCulture)), ", "
            ).Append(");");

            using (var command = context.CreateCommand(sql.ToString())) {
                PopulateParameters(command, schema, row);

                using (var reader = command.ExecuteReader()) {
                    if (!reader.Read())
                        throw new DataException("INSERT command returned no rows");
                    row.RowVersion = reader.GetValue(0);

                    if (reader.Read())
                        throw new DataException("INSERT command returned multiple rows");
                }
            }
        }
		protected SqlTransactionalCommandsContext(SqlDatabaseContext sqlDatabaseContext, IDbConnection dbConnection, TransactionContext transactionContext)
		{
			this.TransactionContext = transactionContext;

			try
		    {
		        this.DbConnection = dbConnection;
		        this.SqlDatabaseContext = sqlDatabaseContext;
		        this.DataAccessModel = sqlDatabaseContext.DataAccessModel;

		        this.emulateMultipleActiveResultSets = !sqlDatabaseContext.SqlDialect.SupportsCapability(SqlCapability.MultipleActiveResultSets);

		        if (transactionContext?.DataAccessTransaction != null)
		        {
		            this.dbTransaction = dbConnection.BeginTransaction(ConvertIsolationLevel(transactionContext.DataAccessTransaction.IsolationLevel));
		        }
		    }
		    catch
		    {
		        this.Dispose(true);

		        throw;
		    }
		}
Example #7
0
		protected virtual SqlTransactionalCommandsContext CreateSqlTransactionalCommandsContext(IDbConnection connection, TransactionContext transactionContext)
		{
			return new DefaultSqlTransactionalCommandsContext(this, connection, transactionContext);
		}
		public SqlServerSqlTransactionsCommandContext(SqlDatabaseContext sqlDatabaseContext, IDbConnection connection, TransactionContext transactionContext)
			: base(sqlDatabaseContext, connection, transactionContext)
		{
		}
        protected override SqlTransactionalCommandsContext CreateSqlTransactionalCommandsContext(IDbConnection connection, TransactionContext transactionContext)
        {
			return new SqlServerSqlTransactionsCommandContext(this, connection, transactionContext);
		}
		public PostgresSqlTransactionalCommandsContext(SqlDatabaseContext sqlDatabaseContext, IDbConnection connection, TransactionContext transactionContext)
			: base(sqlDatabaseContext, connection, transactionContext)
		{	
		}
 ///<summary>Refreshes a row's RowVersion.</summary>
 ///<remarks>.Net's SQL CE client doesn't 
 ///support multiple SQL statements in a 
 ///single command.  Therefore, I need to
 ///use a separate command to update the 
 ///RowVersion after updating or adding a
 ///row. This method will update the field.</remarks>
 void RefreshVersion(TransactionContext context, SchemaMapping schema, Row row)
 {
     using (var command = context.CreateCommand(
             "SELECT RowVersion FROM " + QualifyTable(schema) + " WHERE " + schema.PrimaryKey.SqlName.EscapeSqlIdentifier() + " = @ID",
             new { ID = row[schema.PrimaryKey.Column] }
         )) {
         context.SetRowVersion(row, command.ExecuteScalar());
     }
 }
        ///<summary>Throws a RowModifiedException for a row, reading the row's current values from the database.</summary>
        protected void ThrowRowModified(TransactionContext context, SchemaMapping schema, Row row)
        {
            if (context == null) throw new ArgumentNullException("context");
            if (schema == null) throw new ArgumentNullException("schema");
            if (row == null) throw new ArgumentNullException("row");

            //SELECT [FirstColumn], [SecondColumn], [RowVersion]
            //FROM [SchemaName].[TableName]
            //WHERE [IDColumnName] = @ID
            var sql = BuildSelectCommand(schema);
            sql.AppendLine().Append("WHERE ").Append(schema.PrimaryKey.SqlName.EscapeSqlIdentifier()).Append(" = @ID");

            using (var command = context.CreateCommand(sql.ToString(), new { ID = row[schema.PrimaryKey.Column] }))
            using (var reader = command.ExecuteReader()) {
                if (!reader.Read()) {
                    row.RowVersion = null;
                    throw new RowDeletedException(row);
                }

                var dict = schema.Columns.ToDictionary(cm => cm.Column, cm => reader[cm.SqlName]);

                row.RowVersion = reader["RowVersion"];

                if (reader.Read())
                    throw new InvalidOperationException("Duplicate ID");

                throw new RowModifiedException(row, dict);
            }
        }
        ///<summary>Applies an update row to the database.</summary>
        public virtual void ApplyUpdate(TransactionContext context, SchemaMapping schema, Row row)
        {
            if (context == null) throw new ArgumentNullException("context");
            if (schema == null) throw new ArgumentNullException("schema");
            if (row == null) throw new ArgumentNullException("row");

            var sql = new StringBuilder();

            //UPDATE [SchemaName].[TableName]
            //SET [FirstColumn] = @Col0, [SecondColumn] = @Col1
            //OUTPUT INSERTED.RowVersionINTO @version
            //WHERE [IDColumnName] = @ColN AND RowVersion = @version;

            sql.Append("UPDATE ").AppendLine(QualifyTable(schema));
            sql.Append("SET").AppendJoin(
                schema.Columns.Select((c, i) => c.SqlName.EscapeSqlIdentifier() + " = @Col" + i.ToString(CultureInfo.InvariantCulture)), ", "
            ).AppendLine();
            sql.AppendLine("OUTPUT INSERTED.RowVersion");
            sql.Append("WHERE ").Append(schema.PrimaryKey.SqlName.EscapeSqlIdentifier()).Append(" = @Col").Append(schema.Columns.IndexOf(schema.PrimaryKey))
                                .Append(" AND RowVersion = @version;");

            using (var command = context.CreateCommand(sql.ToString())) {
                PopulateParameters(command, schema, row);

                var versionParameter = command.CreateParameter();
                versionParameter.ParameterName = "@version";
                versionParameter.Value = row.RowVersion;
                command.Parameters.Add(versionParameter);

                using (var reader = command.ExecuteReader()) {
                    if (!reader.Read()) {
                        reader.Close();		//A single connection cannot have two DataReaders at once
                        ThrowRowModified(context, schema, row);
                    }
                    row.RowVersion = reader.GetValue(0);

                    if (reader.Read())
                        throw new DBConcurrencyException("Concurrency FAIL!");	//Exception will be handled by TableSynchronizer
                }
            }
        }
        protected override SqlTransactionalCommandsContext CreateSqlTransactionalCommandsContext(IDbConnection connection, TransactionContext transactionContext)
        {
			return new PostgresDotConnectSqlTransactionalCommandsContext(this, connection, transactionContext);
		}