public DMLService(IDatabaseServices databaseServices) : base(databaseServices)
 {
     queries                    = new DMLQueries(this);
     identifiers                = new DMLIdentifiers(this);
     operators                  = new DMLOperators(this);
     functions                  = new DMLFunctions(this);
     aggregateFunctions         = new DMLAggregateFunctions(this);
     defaultValues              = new DMLDefaultValues(this);
     syntaxHighlightDefinitions = new DMLSyntaxHighlightDefinitions(this);
 }
示例#2
0
 /// <summary>
 /// Initializes a new instance of the <see cref="DMLService"/> class.
 /// </summary>
 /// <param name="databaseServices">The database services.</param>
 public DMLService(IDatabaseServices databaseServices)
     : base(databaseServices)
 {
     _queries            = new DMLQueries(this);
     _identifiers        = new DMLIdentifiers(this);
     _operators          = new DMLOperators(this);
     _functions          = new DMLFunctions(this);
     _aggregateFunctions = new DMLAggregateFunctions(this);
     _defaultValues      = new DMLDefaultValues(this);
 }
示例#3
0
        /// <summary>
        /// This method generates the query that will be used in the event trigger.
        /// This assumes that the underlying database has the NULLIF and COALESCE functions.
        /// </summary>
        /// <param name="sql">StringBuilder that will receive the query SQL.</param>
        /// <param name="triggerTablePrimaryKeyColumn">Primary key column of the table associated with the trigger.</param>
        /// <param name="triggerTableEventColumns">Columns of the table associated with the trigger that fire events.</param>
        /// <param name="triggerTableForeignKeys">Foreign keys of the table associated with the trigger.</param>
        /// <param name="eventTable">Table source that stores the events for the table associated with the trigger. This table resides in the same database as the table where the trigger is defined.</param>
        /// <param name="eventQueueTable">Table source that stores the events to be fired by the platform.</param>
        /// <param name="triggerDataAccessor">SQL snippet to access the newly triggered data (new or updated line in trigger table).</param>
        /// <param name="needsTriggerDataAccessorInFrom">True if we need to include the <paramref name="triggerDataAccessor"/> in a from clause to access it in a query.</param>
        /// <param name="isUpdateVariableAccessor">SQL snippet to access the variable that is true if this trigger is an update.</param>
        protected virtual void FillEventTriggerQuery(StringBuilder sql, IPlatformTableSourceColumnInfo triggerTablePrimaryKeyColumn,
                                                     IEnumerable <IPlatformTableSourceColumnInfo> triggerTableEventColumns, IEnumerable <ITableSourceForeignKeyInfo> triggerTableForeignKeys,
                                                     ITableSourceInfo eventTable, ITableSourceInfo eventQueueTable, string triggerDataAccessor, bool needsTriggerDataAccessorInFrom,
                                                     string isUpdateVariableAccessor)
        {
            // We don't use the qualified name if both tables are in the same database, because this breaks database clone processes
            sql.AppendFormat(" INSERT INTO {0}", eventTable.Database.Equals(eventQueueTable.Database) ? eventQueueTable.Name : eventQueueTable.QualifiedName);
            sql.Append("(ESPACE_ID, TENANT_ID, ACTIVITY_ID, PROCESS_DEF_ID, DATA_ID, ENQUEUE_TIME, ERROR_COUNT, NEXT_RUN)");
            var triggerTableEventColumnsList         = triggerTableEventColumns.ToList();
            ITableSourceColumnInfo tenantFilterField = GetTenantFilterField(triggerTableEventColumnsList);
            string defaultTenantIdField = Identifiers.EscapeIdentifier("_TENANT_ID");

            string tenantIdInSelect = (tenantFilterField == null)? defaultTenantIdField:
                                      "COALESCE(" + defaultTenantIdField + ", " + triggerDataAccessor + "."
                                      + Identifiers.EscapeIdentifier(tenantFilterField.Name) + ")";

            IDMLService dmlService     = DatabaseServices.DMLService;
            string      dataIdInSelect = String.Format("{0}.{1}", triggerDataAccessor, Identifiers.EscapeIdentifier(triggerTablePrimaryKeyColumn.Name));

            dataIdInSelect = (triggerTablePrimaryKeyColumn.DataType.Type == DBDataType.INTEGER)? dmlService.Functions.IntegerToText(dataIdInSelect):
                             dataIdInSelect;

            sql.AppendFormat(" (SELECT {0}, {1}, {2}, {3}, {4}, GETDATE(), 0, GETDATE() FROM {5} evt{6}",
                             Identifiers.EscapeIdentifier("_ESPACE_ID"), tenantIdInSelect, Identifiers.EscapeIdentifier("_ACTIVITY_ID"),
                             Identifiers.EscapeIdentifier("_PROCESS_DEF_ID"), dataIdInSelect, Identifiers.EscapeIdentifier(eventTable.Name),
                             needsTriggerDataAccessorInFrom? (", " + triggerDataAccessor): String.Empty);

            sql.Append(" WHERE ");
            IDMLOperators operators               = dmlService.Operators;
            string        whereClause             = operators.Equal("evt." + Identifiers.EscapeIdentifier("_IS_UPDATE"), isUpdateVariableAccessor);
            var           triggerTableColumnNames = new HashSet <string>(triggerTableForeignKeys.Select(fk => fk.ColumnName.ToUpperInvariant()));

            foreach (var column in triggerTableEventColumnsList)
            {
                string insertedFieldSnippet = triggerDataAccessor + "." + Identifiers.EscapeIdentifier(column.Name);
                string evtFieldSnippet      = "evt." + Identifiers.EscapeIdentifier(column.Name);
                string coalesceSnippet      = "{0}";
                string nullIfSnippet        = "{0}";

                if (triggerTableColumnNames.Contains(column.Name.ToUpperInvariant()) || (column == tenantFilterField))
                {
                    switch (column.DataType.Type)
                    {
                    case DBDataType.INTEGER:
                        nullIfSnippet   = "NULLIF({0}, " + GetDefaultValue(DBDataType.INTEGER) + ")";
                        coalesceSnippet = "COALESCE({0}, " + GetDefaultValue(DBDataType.INTEGER) + ")";
                        break;

                    case DBDataType.LONGINTEGER:
                        nullIfSnippet   = "NULLIF({0}, " + GetDefaultValue(DBDataType.LONGINTEGER) + ")";
                        coalesceSnippet = "COALESCE({0}, " + GetDefaultValue(DBDataType.LONGINTEGER) + ")";
                        break;

                    case DBDataType.TEXT:
                        nullIfSnippet   = "NULLIF({0}, " + GetDefaultValue(DBDataType.TEXT) + ")";
                        coalesceSnippet = "COALESCE({0}, " + GetDefaultValue(DBDataType.TEXT) + ")";
                        break;
                    }
                }

                string condition = operators.Or(operators.IsNull(nullIfSnippet.F(evtFieldSnippet)),
                                                operators.Equal(evtFieldSnippet, coalesceSnippet.F(insertedFieldSnippet)));

                whereClause = operators.And(whereClause, "(" + condition + ")");
            }

            sql.Append(whereClause);
            sql.Append(")");
        }