Exemple #1
0
        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);
        }
Exemple #2
0
        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));
        }
Exemple #6
0
        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);
        }
Exemple #8
0
        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);
        }