protected virtual IDbCommand BuildInsertCommand(TypeDescriptor typeDescriptor, DataAccessObject dataAccessObject) { IDbCommand command; SqlCommandValue sqlCommandValue; var updatedProperties = dataAccessObject.GetAdvanced().GetChangedPropertiesFlattened(); var commandKey = new SqlCommandKey(dataAccessObject.GetType(), updatedProperties); if (this.TryGetInsertCommand(commandKey, out sqlCommandValue)) { command = this.CreateCommand(); command.CommandText = sqlCommandValue.commandText; this.FillParameters(command, updatedProperties, null); return(command); } IReadOnlyList <string> returningAutoIncrementColumnNames = null; if (dataAccessObject.GetAdvanced().DefinesAnyDirectPropertiesGeneratedOnTheServerSide) { var propertyDescriptors = typeDescriptor.PersistedProperties.Where(c => c.IsPropertyThatIsCreatedOnTheServerSide).ToList(); returningAutoIncrementColumnNames = new ReadOnlyList <string>(propertyDescriptors.Select(c => c.PersistedName).ToList()); } var columnNames = new ReadOnlyList <string>(updatedProperties.Select(c => c.PersistedName).ToList()); var valueExpressions = new ReadOnlyList <Expression>(updatedProperties.Select(c => (Expression)Expression.Constant(c.Value)).ToList()); Expression expression = new SqlInsertIntoExpression(new SqlTableExpression(typeDescriptor.PersistedName), columnNames, returningAutoIncrementColumnNames, valueExpressions); if (this.SqlDatabaseContext.SqlDialect.SupportsFeature(SqlFeature.PragmaIdentityInsert) && dataAccessObject.ToObjectInternal().HasAnyChangedPrimaryKeyServerSideProperties) { var list = new List <Expression> { new SqlSetCommandExpression("IdentityInsert", new SqlTableExpression(typeDescriptor.PersistedName), Expression.Constant(true)), expression, new SqlSetCommandExpression("IdentityInsert", new SqlTableExpression(typeDescriptor.PersistedName), Expression.Constant(false)), }; expression = new SqlStatementListExpression(list); } var result = this.SqlDatabaseContext.SqlQueryFormatterManager.Format(expression, SqlQueryFormatterOptions.Default & ~SqlQueryFormatterOptions.OptimiseOutConstantNulls); Debug.Assert(result.ParameterValues.Count() == updatedProperties.Count); command = this.CreateCommand(); var commandText = result.CommandText; command.CommandText = commandText; this.CacheInsertCommand(commandKey, new SqlCommandValue { commandText = command.CommandText }); this.FillParameters(command, updatedProperties, null); return(command); }
public override Exception DecorateException(Exception exception, DataAccessObject dataAccessObject, string relatedQuery) { var postgresException = exception as PgSqlException; if (postgresException == null) { return(base.DecorateException(exception, dataAccessObject, relatedQuery)); } switch (postgresException.ErrorCode) { case "40001": return(new ConcurrencyException(exception, relatedQuery)); case "23502": return(new MissingPropertyValueException(dataAccessObject, postgresException, relatedQuery)); case "23503": return(new MissingRelatedDataAccessObjectException(null, dataAccessObject, postgresException, relatedQuery)); case "23505": if (!string.IsNullOrEmpty(postgresException.ColumnName) && dataAccessObject != null) { if (dataAccessObject.GetAdvanced().GetPrimaryKeysFlattened().Any(c => c.PersistedName == postgresException.ColumnName)) { return(new ObjectAlreadyExistsException(dataAccessObject, exception, relatedQuery)); } } if (!string.IsNullOrEmpty(postgresException.ConstraintName) && postgresException.ConstraintName.EndsWith("_pkey")) { return(new ObjectAlreadyExistsException(dataAccessObject, exception, relatedQuery)); } if (!string.IsNullOrEmpty(postgresException.DetailMessage) && dataAccessObject != null) { if (dataAccessObject.GetAdvanced().GetPrimaryKeysFlattened().Any(c => Regex.Match(postgresException.DetailMessage, @"Key\s*\(\s*""?" + c.PersistedName + @"""?\s*\)", RegexOptions.CultureInvariant).Success)) { return(new ObjectAlreadyExistsException(dataAccessObject, exception, relatedQuery)); } } if (postgresException.Message.IndexOf("_pkey", StringComparison.InvariantCultureIgnoreCase) >= 0) { return(new ObjectAlreadyExistsException(dataAccessObject, exception, relatedQuery)); } else { return(new UniqueConstraintException(exception, relatedQuery)); } } return(new DataAccessException(exception, relatedQuery)); }
private DataAccessObject ApplyPropertiesGeneratedOnServerSide(DataAccessObject dataAccessObject, IDataReader reader) { if (!dataAccessObject.GetAdvanced().DefinesAnyDirectPropertiesGeneratedOnTheServerSide) { return(dataAccessObject); } Func <DataAccessObject, IDataReader, DataAccessObject> applicator; if (!this.serverSideGeneratedPropertySettersByType.TryGetValue(Type.GetTypeHandle(dataAccessObject), out applicator)) { var objectParameter = Expression.Parameter(typeof(DataAccessObject)); var readerParameter = Expression.Parameter(typeof(IDataReader)); var propertiesGeneratedOnServerSide = dataAccessObject.GetAdvanced().GetPropertiesGeneratedOnTheServerSide(); var local = Expression.Variable(dataAccessObject.GetType()); var statements = new List <Expression> { Expression.Assign(local, Expression.Convert(objectParameter, dataAccessObject.GetType())) }; var index = 0; foreach (var property in propertiesGeneratedOnServerSide) { var sqlDataType = this.sqlDataTypeProvider.GetSqlDataType(property.PropertyType); var valueExpression = sqlDataType.GetReadExpression(readerParameter, index++); var member = dataAccessObject.GetType().GetProperty(property.PropertyName); statements.Add(Expression.Assign(Expression.MakeMemberAccess(local, member), valueExpression)); } statements.Add(objectParameter); var body = Expression.Block(new [] { local }, statements); var lambda = Expression.Lambda <Func <DataAccessObject, IDataReader, DataAccessObject> >(body, objectParameter, readerParameter); applicator = lambda.Compile(); var newDictionary = new Dictionary <RuntimeTypeHandle, Func <DataAccessObject, IDataReader, DataAccessObject> >(this.serverSideGeneratedPropertySettersByType) { [Type.GetTypeHandle(dataAccessObject)] = applicator }; this.serverSideGeneratedPropertySettersByType = newDictionary; } return(applicator(dataAccessObject, reader)); }
public override Exception DecorateException(Exception exception, DataAccessObject dataAccessObject, string relatedQuery) { // http://www.sqlite.org/c3ref/c_abort.html var sqliteException = exception as SqliteException; if (sqliteException == null) { return base.DecorateException(exception, dataAccessObject, relatedQuery); } if (sqliteException.ErrorCode == SQLiteErrorCode.Constraint) { if (sqliteException.Message.IndexOf("FOREIGN KEY", StringComparison.Ordinal) >= 0) { return new MissingRelatedDataAccessObjectException(null, dataAccessObject, sqliteException, relatedQuery); } else if (sqliteException.Message.IndexOf("NOT NULL", StringComparison.Ordinal) >= 0) { return new MissingPropertyValueException(dataAccessObject, sqliteException, relatedQuery); } else { if (dataAccessObject != null) { var primaryKeyNames = dataAccessObject.GetAdvanced().TypeDescriptor.PrimaryKeyProperties.Select(c => c.DeclaringTypeDescriptor.PersistedName + "." + c.PersistedName); if (primaryKeyNames.Any(c => sqliteException.Message.IndexOf(c, StringComparison.Ordinal) >= 0)) { return new ObjectAlreadyExistsException(dataAccessObject, exception, relatedQuery); } } return new UniqueConstraintException(exception, relatedQuery); } } return new DataAccessException(exception, relatedQuery); }
public override Exception DecorateException(Exception exception, DataAccessObject dataAccessObject, string relatedQuery) { // http://www.sqlite.org/c3ref/c_abort.html var sqliteException = exception as SqliteException; if (sqliteException == null) { return(base.DecorateException(exception, dataAccessObject, relatedQuery)); } if (sqliteException.ErrorCode == SQLiteErrorCode.Constraint) { if (sqliteException.Message.IndexOf("FOREIGN KEY", StringComparison.Ordinal) >= 0) { return(new MissingRelatedDataAccessObjectException(null, dataAccessObject, sqliteException, relatedQuery)); } else if (sqliteException.Message.IndexOf("NOT NULL", StringComparison.Ordinal) >= 0) { return(new MissingPropertyValueException(dataAccessObject, sqliteException, relatedQuery)); } else { if (dataAccessObject != null) { var primaryKeyNames = dataAccessObject.GetAdvanced().TypeDescriptor.PrimaryKeyProperties.Select(c => c.DeclaringTypeDescriptor.PersistedName + "." + c.PersistedName); if (primaryKeyNames.Any(c => sqliteException.Message.IndexOf(c, StringComparison.Ordinal) >= 0)) { return(new ObjectAlreadyExistsException(dataAccessObject, exception, relatedQuery)); } } return(new UniqueConstraintException(exception, relatedQuery)); } } return(new DataAccessException(exception, relatedQuery)); }
protected virtual IDbCommand BuildInsertCommand(TypeDescriptor typeDescriptor, DataAccessObject dataAccessObject) { var success = false; IDbCommand command = null; SqlCachedUpdateInsertFormatValue cachedValue; bool predicated; var requiresIdentityInsert = dataAccessObject.ToObjectInternal().HasAnyChangedPrimaryKeyServerSideProperties; var updatedProperties = dataAccessObject.ToObjectInternal().GetChangedPropertiesFlattened(out predicated); if (predicated) { return(BuildInsertCommandForDeflatedPredicated(typeDescriptor, dataAccessObject, updatedProperties)); } var commandKey = new SqlCachedUpdateInsertFormatKey(dataAccessObject.GetType(), updatedProperties, requiresIdentityInsert); if (this.TryGetInsertCommand(commandKey, out cachedValue)) { try { command = this.CreateCommand(); command.CommandText = cachedValue.formatResult.CommandText; this.FillParameters(command, cachedValue, updatedProperties, null); success = true; return(command); } finally { if (!success) { command?.Dispose(); } } } IReadOnlyList <string> returningAutoIncrementColumnNames = null; if (dataAccessObject.GetAdvanced().DefinesAnyDirectPropertiesGeneratedOnTheServerSide) { var propertyDescriptors = typeDescriptor.PersistedPropertiesWithoutBackreferences.Where(c => c.IsPropertyThatIsCreatedOnTheServerSide).ToList(); returningAutoIncrementColumnNames = propertyDescriptors.Select(c => c.PersistedName).ToReadOnlyCollection(); } var constantPlaceholdersCount = 0; var valueIndexesToParameterPlaceholderIndexes = new int[updatedProperties.Count]; var columnNames = updatedProperties.Select(c => c.PersistedName).ToReadOnlyCollection(); var valueExpressions = new List <Expression>(updatedProperties.Count); foreach (var updated in updatedProperties) { var value = (Expression) new SqlConstantPlaceholderExpression(constantPlaceholdersCount++, Expression.Constant(updated.Value, updated.PropertyType.CanBeNull() ? updated.PropertyType : updated.PropertyType.MakeNullable())); if (value.Type != updated.PropertyType) { value = Expression.Convert(value, updated.PropertyType); } valueExpressions.Add(value); } Expression expression = new SqlInsertIntoExpression(new SqlTableExpression(typeDescriptor.PersistedName), columnNames, returningAutoIncrementColumnNames, valueExpressions, null, requiresIdentityInsert); for (var i = 0; i < constantPlaceholdersCount; i++) { valueIndexesToParameterPlaceholderIndexes[i] = i; } var result = this.SqlDatabaseContext.SqlQueryFormatterManager.Format(expression); try { command = this.CreateCommand(); var commandText = result.CommandText; command.CommandText = commandText; cachedValue = new SqlCachedUpdateInsertFormatValue { formatResult = result, valueIndexesToParameterPlaceholderIndexes = valueIndexesToParameterPlaceholderIndexes, primaryKeyIndexesToParameterPlaceholderIndexes = null }; if (result.Cacheable) { this.CacheInsertCommand(commandKey, cachedValue); } this.FillParameters(command, cachedValue, updatedProperties, null); success = true; return(command); } finally { if (!success) { command?.Dispose(); } } }
public override Exception DecorateException(Exception exception, DataAccessObject dataAccessObject, string relatedQuery) { var postgresException = exception as PgSqlException; if (postgresException == null) { return base.DecorateException(exception, dataAccessObject, relatedQuery); } switch (postgresException.ErrorCode) { case "40001": return new ConcurrencyException(exception, relatedQuery); case "23502": return new MissingPropertyValueException(dataAccessObject, postgresException, relatedQuery); case "23503": return new MissingRelatedDataAccessObjectException(null, dataAccessObject, postgresException, relatedQuery); case "23505": if (!string.IsNullOrEmpty(postgresException.ColumnName) && dataAccessObject != null) { if (dataAccessObject.GetAdvanced().GetPrimaryKeysFlattened().Any(c => c.PersistedName == postgresException.ColumnName)) { return new ObjectAlreadyExistsException(dataAccessObject, exception, relatedQuery); } } if (!string.IsNullOrEmpty(postgresException.ConstraintName) && postgresException.ConstraintName.EndsWith("_pkey")) { return new ObjectAlreadyExistsException(dataAccessObject, exception, relatedQuery); } if (!string.IsNullOrEmpty(postgresException.DetailMessage) && dataAccessObject != null) { if (dataAccessObject.GetAdvanced().GetPrimaryKeysFlattened().Any(c => Regex.Match(postgresException.DetailMessage, @"Key\s*\(\s*""?" + c.PersistedName + @"""?\s*\)", RegexOptions.CultureInvariant).Success)) { return new ObjectAlreadyExistsException(dataAccessObject, exception, relatedQuery); } } if (postgresException.Message.IndexOf("_pkey", StringComparison.InvariantCultureIgnoreCase) >= 0) { return new ObjectAlreadyExistsException(dataAccessObject, exception, relatedQuery); } else { return new UniqueConstraintException(exception, relatedQuery); } } return new DataAccessException(exception, relatedQuery); }
protected virtual IDbCommand BuildUpdateCommand(TypeDescriptor typeDescriptor, DataAccessObject dataAccessObject) { IDbCommand command; SqlCommandValue sqlCommandValue; var updatedProperties = dataAccessObject.GetAdvanced().GetChangedPropertiesFlattened(); if (updatedProperties.Count == 0) { return(null); } var primaryKeys = dataAccessObject.GetAdvanced().GetPrimaryKeysForUpdateFlattened(); var commandKey = new SqlCommandKey(dataAccessObject.GetType(), updatedProperties); if (this.TryGetUpdateCommand(commandKey, out sqlCommandValue)) { command = this.CreateCommand(); command.CommandText = sqlCommandValue.commandText; this.FillParameters(command, updatedProperties, primaryKeys); return(command); } var assignments = updatedProperties.Select(c => (Expression) new SqlAssignExpression(new SqlColumnExpression(c.PropertyType, null, c.PersistedName), Expression.Constant(c.Value))).ToReadOnlyList(); Expression where = null; var i = 0; Debug.Assert(primaryKeys.Length > 0); foreach (var primaryKey in primaryKeys) { var currentExpression = Expression.Equal(new SqlColumnExpression(primaryKey.PropertyType, null, primaryKey.PersistedName), Expression.Constant(primaryKey.Value)); if (where == null) { where = currentExpression; } else { where = Expression.And(where, currentExpression); } i++; } var expression = new SqlUpdateExpression(new SqlTableExpression(typeDescriptor.PersistedName), assignments, where); expression = (SqlUpdateExpression)SqlObjectOperandComparisonExpander.Expand(expression); var result = this.SqlDatabaseContext.SqlQueryFormatterManager.Format(expression, SqlQueryFormatterOptions.Default & ~SqlQueryFormatterOptions.OptimiseOutConstantNulls); command = this.CreateCommand(); command.CommandText = result.CommandText; this.CacheUpdateCommand(commandKey, new SqlCommandValue() { commandText = command.CommandText }); this.FillParameters(command, updatedProperties, primaryKeys); return(command); }