Beispiel #1
0
        private List <SqlObjectName> LoadDependencies(DatabaseConfig config, SqlObjectName viewName)
        {
            List <SqlObjectName> result = new List <SqlObjectName>();

            config.DatabaseConnectionString.WithReader(
                $@"SELECT DISTINCT referenced_schema_name, referenced_entity_name, obj.type
            FROM
                sys.dm_sql_referenced_entities('{viewName}', 'OBJECT') e
            LEFT JOIN
                sys.objects obj
            ON
                obj.object_id = referenced_id",
                reader =>
            {
                while (reader.Read())
                {
                    var objectName = new SqlObjectName(reader[1] as string, reader[0] as string);
                    if (((string)reader[2]).Trim() == "V")
                    {
                        result.AddRange(LoadDependencies(config, objectName));
                    }
                    else if (result.Contains(objectName) == false)
                    {
                        result.Add(objectName);
                    }
                }
            });
            return(result);
        }
 public RowSchema(string connectionString, SqlObjectName tableName, string[] primaryKeyColumns)
 {
     _columns               = GetTableColumns(connectionString, tableName);
     PrimaryKeyColumns      = (primaryKeyColumns ?? connectionString.GetPrimaryKeyColumns(tableName)).ToDictionary(c => c, c => ColumnNamesLookup[c]);
     RowEqualityComparer    = new RowComparer();
     RowKeyEqualityComparer = new RowKeyComparer();
 }
Beispiel #3
0
 private static string BuildFQN(ISqlBuilder sqlBuilder, SqlObjectName name)
 {
     // TODO: linq2db fix required
     // currently we miss FQN-based mapping support at least for for stored procedures and non-table functions
     // and they require raw SQL name instead
     return(sqlBuilder.BuildObjectName(new (), name, ConvertType.NameToProcedure).ToString());
 }
        private IEnumerable <(string, string)> BuildReplacements(SqlObjectName cacheName, SqlObjectName viewName, string[] allTargetCollumns, string[] keyColumns, string[] notNullColumns)
        {
            yield return("cacheName", cacheName);

            yield return("viewName", viewName);

            yield return
                (
                "allTargetCollumns",
                String.Join
                (
                    ", ",
                    allTargetCollumns.Select(c => $"[{c}]")
                )
                );

            yield return("sourceAlias", "s");

            yield return("targetAlias", "t");

            yield return("keyColumnsMatchCondition", BuildKeyColumnsMatchCondition(keyColumns));

            yield return("firstNotNullPrimaryKeyColumn", $"[{keyColumns.Intersect(notNullColumns).First()}]");

            yield return("valuesUpdate", BuildValuesUpdate(allTargetCollumns, keyColumns));

            yield return("notMatchedValuesWithNullCheck", NotMatchedValuesWithNullCheck(allTargetCollumns, keyColumns, notNullColumns));
        }
Beispiel #5
0
        internal SqlTable(
            int id,
            string?expression,
            string alias,
            SqlObjectName tableName,
            Type objectType,
            SequenceNameAttribute[]?sequenceAttributes,
            IEnumerable <SqlField> fields,
            SqlTableType sqlTableType,
            ISqlExpression[]?tableArguments,
            TableOptions tableOptions,
            string?tableID)
            : this(objectType, id, tableName)
        {
            Expression         = expression;
            Alias              = alias;
            SequenceAttributes = sequenceAttributes;
            ID = tableID;

            AddRange(fields);

            SqlTableType   = sqlTableType;
            TableArguments = tableArguments;
            TableOptions   = tableOptions;
        }
Beispiel #6
0
        /// <summary>
        /// Preprocess database object name according to current settings.
        /// </summary>
        /// <param name="originalName">Original (full) database object name.</param>
        /// <param name="defaultSchemas">Collection of default schemas.</param>
        /// <returns>New database object name for use in data model metadata and non-default schema flag.</returns>
        private (SqlObjectName name, bool isNonDefaultSchema) ProcessObjectName(SqlObjectName originalName, ISet <string> defaultSchemas)
        {
            var isNonDefaultSchema = originalName.Schema != null && !defaultSchemas.Contains(originalName.Schema);
            var result             = originalName;

            // remove default schema from name if disabled
            if (!_options.DataModel.GenerateDefaultSchema && !isNonDefaultSchema && originalName.Schema != null)
            {
                result = result with {
                    Schema = null
                }
            }
            ;

            // remove database name if disabled
            if (!_options.DataModel.IncludeDatabaseName)
            {
                result = result with {
                    Database = null
                }
            }
            ;

            // currently we don't load schema data from linked servers, so there is no need to process server name

            return(result, isNonDefaultSchema);
        }
Beispiel #7
0
        public override StringBuilder BuildObjectName(StringBuilder sb, SqlObjectName name, ConvertType objectType, bool escape, TableOptions tableOptions)
        {
            var schemaName = name.Schema;

            if (schemaName == null && tableOptions.IsTemporaryOptionSet())
            {
                schemaName = "SESSION";
            }

            // "db..table" syntax not supported
            if (name.Database != null && schemaName == null)
            {
                throw new LinqToDBException("DB2 requires schema name if database name provided.");
            }

            if (name.Database != null)
            {
                (escape ? Convert(sb, name.Database, ConvertType.NameToDatabase) : sb.Append(name.Database))
                .Append('.');
                if (schemaName == null)
                {
                    sb.Append('.');
                }
            }

            if (schemaName != null)
            {
                (escape ? Convert(sb, schemaName, ConvertType.NameToSchema) : sb.Append(schemaName))
                .Append('.');
            }

            return(escape ? Convert(sb, name.Name, objectType) : sb.Append(name.Name));
        }
        public static void CreateQueue(this SqlTransaction tran, SqlObjectName queueName)
        {
            var script = LoadScript("CreateQueue");

            script = script.Replace("{queueName}", queueName);
            tran.ExecuteNonQuery(script);
        }
Beispiel #9
0
 public TableFunctionModel(
     SqlObjectName name,
     MethodModel method,
     TableFunctionMetadata metadata,
     string methodInfoFieldName)
     : base(name, method)
 {
     Metadata            = metadata;
     MethodInfoFieldName = methodInfoFieldName;
 }
Beispiel #10
0
        public override StringBuilder BuildObjectName(StringBuilder sb, SqlObjectName name, ConvertType objectType, bool escape, TableOptions tableOptions)
        {
            if (name.Database != null)
            {
                (escape ? Convert(sb, name.Database, ConvertType.NameToDatabase) : sb.Append(name.Database))
                .Append('.');
            }

            return(escape ? Convert(sb, name.Name, objectType) : sb.Append(name.Name));
        }
        public MergeSelectViewChanges(SqlObjectName cacheName, SqlObjectName viewName, string[] allTargetCollumns, string[] keyColumns, string[] notNullColumns)
        {
            string sc = _script;

            foreach (var replacement in BuildReplacements(cacheName, viewName, allTargetCollumns, keyColumns, notNullColumns))
            {
                sc = sc.Replace($"{{{replacement.Item1}}}", replacement.Item2);
            }

            _replacedScript = sc;
        }
Beispiel #12
0
            public void Build(ISqExtensionBuilder builder)
            {
                var tableExpr    = builder.Arguments[0].EvaluateExpression();
                var tableType    = ((MethodInfo)builder.Member).GetGenericArguments()[0];
                var helperType   = typeof(TableHelper <>).MakeGenericType(tableType);
                var tableHelper  = (TableHelper)Activator.CreateInstance(helperType, tableExpr) !;
                var qualified    = builder.Arguments.Length <= 1 ? TableQualification.Full : builder.GetValue <TableQualification>(1);
                var isExpression = builder.Member.Name == "TableExpr";

                if (isExpression)
                {
                    if (qualified == TableQualification.None)
                    {
                        builder.ResultExpression = new SqlExpression(typeof(string), tableHelper.TableName, Precedence.Primary);
                    }
                    else
                    {
                        var tableName = new SqlObjectName(
                            tableHelper.TableName,
                            Server: (qualified & TableQualification.ServerName) != 0 ? tableHelper.ServerName   : null,
                            Database: (qualified & TableQualification.DatabaseName) != 0 ? tableHelper.DatabaseName : null,
                            Schema: (qualified & TableQualification.SchemaName) != 0 ? tableHelper.SchemaName   : null);
                        var table = new SqlTable(tableType)
                        {
                            TableName    = tableName,
                            TableOptions = (qualified & TableQualification.TableOptions) != 0 ? tableHelper.TableOptions : TableOptions.NotSet,
                        };

                        builder.ResultExpression = table;
                    }
                }
                else
                {
                    var name = tableHelper.TableName;

                    if (qualified != TableQualification.None)
                    {
                        var sb = new StringBuilder();
                        builder.DataContext.CreateSqlProvider().BuildObjectName(
                            sb,
                            new SqlObjectName(
                                name,
                                Server: (qualified & TableQualification.ServerName) != 0 ? tableHelper.ServerName   : null,
                                Database: (qualified & TableQualification.DatabaseName) != 0 ? tableHelper.DatabaseName : null,
                                Schema: (qualified & TableQualification.SchemaName) != 0 ? tableHelper.SchemaName   : null),
                            ConvertType.NameToQueryTable,
                            true,
                            (qualified & TableQualification.TableOptions) != 0 ? tableHelper.TableOptions : TableOptions.NotSet);
                        name = sb.ToString();
                    }

                    builder.ResultExpression = new SqlValue(name);
                }
            }
        public static void CreateMemoryViewCache(this string connectionString, SqlObjectName viewName, SqlObjectName cacheName, params string[] primaryColumns)
        {
            var script = LoadScript("CreateMemoryViewCache");

            script = script.Replace("{viewName}", viewName);
            script = script.Replace("{cacheName}", cacheName);
            script = script.Replace("{cacheName.Schema}", cacheName.Schema);
            script = script.Replace("{cacheName.Name}", cacheName.Name);
            script = script.Replace("{primaryColumnList}", String.Join(", ", primaryColumns.Select(c => $"[{c}]")));
            connectionString.WithConnection(con => { con.ExecuteNonQuery(script); });
        }
        public static void MergeViewChanges(this string sqlConnection, SqlObjectName cacheName, SqlObjectName viewName, string[] keyColumns, string[] valueColumns)
        {
            var script = LoadScript("MergeViewChanges");

            script = script.Replace("{cacheName}", cacheName);
            script = script.Replace("{viewName}", viewName);
            script = script.Replace("{targetAlias}", "t");
            script = script.Replace("{sourceAlias}", "s");
            script = script.Replace
                     (
                "{keyColumnsMatchCondition}",
                String.Join(" AND ", keyColumns.Select(c => $"s.[{c}] = t.[{c}]"))
                     );
            if (valueColumns.Length > 0)
            {
                script = script.Replace("{whenMatchedClause}", @"    WHEN MATCHED AND ({valueColumnsChangedCondition})
        THEN 
			UPDATE SET {valueColumnUpdates}"            );
                script = script.Replace
                         (
                    "{valueColumnsChangedCondition}",
                    String.Join(" OR ", valueColumns.Select(c => $"s.[{c}] <> t.[{c}]"))
                         );
                script = script.Replace
                         (
                    "{valueColumnUpdates}",
                    String.Join(", ", valueColumns.Select(c => $"t.[{c}] = s.[{c}]"))
                         );
            }
            else
            {
                script = script.Replace("{whenMatchedClause}", String.Empty);
            }
            script = script.Replace
                     (
                "{allTargetCollumns}",
                String.Join(", ", keyColumns.Union(valueColumns).Select(c => $"[{c}]"))
                     );
            script = script.Replace
                     (
                "{allSourceColumns}",
                String.Join(", ", keyColumns.Union(valueColumns).Select(c => $"s.[{c}]"))
                     );
            sqlConnection.WithConnection(con =>
            {
                using (var command = con.CreateCommand())
                {
                    command.CommandTimeout = 0;
                    command.CommandText    = script;
                    command.ExecuteNonQuery();
                }
            });
        }
Beispiel #15
0
        public override StringBuilder BuildObjectName(StringBuilder sb, SqlObjectName name, ConvertType objectType, bool escape, TableOptions tableOptions)
        {
            if (name.Database != null && IsTemporary(name.Name, tableOptions))
            {
                name = name with {
                    Database = null
                }
            }
            ;

            name = name with {
                Name = GetTablePhysicalName(name.Name, tableOptions)
            };

            return(base.BuildObjectName(sb, name, objectType, escape, tableOptions));
        }
Beispiel #16
0
        // https://www.ibm.com/support/knowledgecenter/en/SSGU8G_12.1.0/com.ibm.sqls.doc/ids_sqs_1652.htm
        public override StringBuilder BuildObjectName(StringBuilder sb, SqlObjectName name, ConvertType objectType, bool escape, TableOptions tableOptions)
        {
            if (name.Server != null && name.Database == null)
            {
                throw new LinqToDBException("You must specify database for linked server query");
            }

            if (name.Database != null)
            {
                if (escape)
                {
                    Convert(sb, name.Database, ConvertType.NameToDatabase);
                }
                else
                {
                    sb.Append(name.Database);
                }
            }

            if (name.Server != null)
            {
                sb.Append('@');
                if (escape)
                {
                    Convert(sb, name.Server, ConvertType.NameToServer);
                }
                else
                {
                    sb.Append(name.Server);
                }
            }

            if (name.Database != null)
            {
                sb.Append(':');
            }

            if (name.Schema != null)
            {
                (escape ? Convert(sb, name.Schema, ConvertType.NameToSchema) : sb.Append(name.Schema))
                .Append('.');
            }

            return(escape ? Convert(sb, name.Name, objectType) : sb.Append(name.Name));
        }
 public QueryView(Database db, string query, string[] primaryKeyColumns)
 {
     _db               = db;
     Query             = query;
     PrimaryKeyColumns = primaryKeyColumns;
     ViewName          = string.Format(db.Config.QueryViewNameTemplate, Guid.ToString().Replace('-', '_'));
     db.Config.DatabaseConnectionString.WithConnection
     (
         con =>
     {
         using (var command = con.CreateCommand())
         {
             command.CommandText = $"CREATE VIEW {ViewName} AS {Environment.NewLine}{query}";
             command.ExecuteNonQuery();
         }
     }
     );
 }
Beispiel #18
0
        public override StringBuilder BuildObjectName(StringBuilder sb, SqlObjectName name, ConvertType objectType, bool escape, TableOptions tableOptions)
        {
            var databaseName = name.Database;

            // remove database name, which could be inherited from non-temporary table mapping
            // except explicit use of tempdb, needed in some cases at least for sql server 2014
            if ((name.Name.StartsWith("#") || tableOptions.IsTemporaryOptionSet()) && databaseName != "tempdb")
            {
                databaseName = "tempdb";
            }

            if (name.Server != null && (databaseName == null || name.Schema == null))
            {
                // all components required for linked-server syntax by SQL server
                throw new LinqToDBException("You must specify both schema and database names explicitly for linked server query");
            }

            if (name.Server != null)
            {
                (escape ? Convert(sb, name.Server, ConvertType.NameToServer) : sb.Append(name.Server))
                .Append('.');
            }

            if (databaseName != null)
            {
                (escape ? Convert(sb, databaseName, ConvertType.NameToDatabase) : sb.Append(databaseName))
                .Append('.');
            }

            if (name.Schema != null)
            {
                (escape ? Convert(sb, name.Schema, ConvertType.NameToSchema) : sb.Append(name.Schema)).Append('.');
            }
            else if (databaseName != null)
            {
                sb.Append('.');
            }

            var tableName = GetTablePhysicalName(name.Name, tableOptions);

            return(escape ? Convert(sb, tableName, objectType) : sb.Append(tableName));
        }
Beispiel #19
0
        public override StringBuilder BuildObjectName(StringBuilder sb, SqlObjectName name, ConvertType objectType, bool escape, TableOptions tableOptions)
        {
            var schemaName = tableOptions.HasIsTemporary() ? null : name.Schema;

            // "db..table" syntax not supported and postgresql doesn't support database name, if it is not current database
            // so we can ignore database name to avoid error from server
            if (name.Database != null && schemaName != null)
            {
                (escape ? Convert(sb, name.Database, ConvertType.NameToDatabase) : sb.Append(name.Database))
                .Append('.');
            }

            if (schemaName != null)
            {
                (escape ? Convert(sb, schemaName, ConvertType.NameToSchema) : sb.Append(schemaName))
                .Append('.');
            }

            return(escape ? Convert(sb, name.Name, objectType) : sb.Append(name.Name));
        }
        public static IEnumerable <string> ReceiveMessages(this SqlTransaction tran, SqlObjectName queueName, TimeSpan timeoutMs)
        {
            var script = LoadScript("ReceiveMessages");

            script = script.Replace("{queueName}", queueName);
            script = script.Replace("{timeoutMs}", timeoutMs.TotalMilliseconds.ToString(CultureInfo.InvariantCulture));
            using (var command = tran.Connection.CreateCommand())
            {
                command.CommandText    = script;
                command.Transaction    = tran;
                command.CommandTimeout = 0;
                using (var reader = command.ExecuteReader())
                {
                    while (reader.Read())
                    {
                        yield return(reader.GetString(0));
                    }
                }
            }
        }
Beispiel #21
0
        public override ISqlExpression?GetIdentityExpression(SqlTable table)
        {
            if (!table.SequenceAttributes.IsNullOrEmpty())
            {
                var attr = GetSequenceNameAttribute(table, false);

                if (attr != null)
                {
                    var sequenceName = new SqlObjectName(attr.SequenceName, Server: table.TableName.Server, Database: table.TableName.Database, Schema: attr.Schema ?? table.TableName.Schema);

                    var sb = new StringBuilder();
                    sb.Append("nextval(");
                    MappingSchema.ConvertToSqlValue(sb, null, BuildObjectName(new StringBuilder(), sequenceName, ConvertType.SequenceName, true, TableOptions.NotSet).ToString());
                    sb.Append(')');
                    return(new SqlExpression(sb.ToString(), Precedence.Primary));
                }
            }

            return(base.GetIdentityExpression(table));
        }
        private (Dictionary <int, string>, Dictionary <string, int>, Dictionary <int, Type>) GetTableColumns(string connectionString, SqlObjectName objectName)
        {
            string query       = $"SELECT TOP(0) * FROM {objectName}";
            var    names       = new Dictionary <int, string>();
            var    namesLookup = new Dictionary <string, int>();
            var    types       = new Dictionary <int, Type>();

            connectionString.WithReader(query, reader =>
            {
                for (int i = 0; i < reader.FieldCount; i++)
                {
                    names.Add(i, reader.GetName(i));
                    namesLookup.Add(reader.GetName(i), i);
                    types.Add(i, reader.GetFieldType(i));
                }
            });
            return(names, namesLookup, types);
        }
        private static void CreateTrigger(this SqlTransaction tran, string triggerResource, SqlObjectName triggerName, SqlObjectName tableName, string dialogHandle, SqlSchemalessObjectName messageType, bool withNative)
        {
            var script = LoadScript(triggerResource);

            script = script.Replace("{triggerName}", triggerName);
            script = script.Replace("{tableName.Schema}", tableName.Schema);
            script = script.Replace("{tableName.Name}", tableName.Name);
            script = script.Replace("{tableName}", tableName);
            script = script.Replace("{dialogHandle}", dialogHandle);
            script = script.Replace("{messageType}", messageType);
            if (withNative)
            {
                script = script.Replace("{with}", "WITH NATIVE_COMPILATION, SCHEMABINDING");
                script = script.Replace("{as}", "BEGIN ATOMIC WITH ( TRANSACTION ISOLATION LEVEL = SNAPSHOT, LANGUAGE = N'us_english' )");
            }
            else
            {
                script = script.Replace("{with}", String.Empty);
                script = script.Replace("{as}", String.Empty);
            }
            tran.ExecuteNonQuery(script);
        }
 public RowSchema(string connectionString, SqlObjectName tableName) : this(connectionString, tableName, null)
 {
 }
 public static void DropQueue(this SqlTransaction tran, SqlObjectName queueName)
 {
     tran.ExecuteNonQuery($"DROP QUEUE {queueName}");
 }
 public static IEnumerable <string> ReceiveMessages(this SqlTransaction tran, SqlObjectName queueName)
 {
     return(ReceiveMessages(tran, queueName, TimeSpan.Zero));
 }
        public static IEnumerable <string> ReceiveMessages(this string connectionString, SqlObjectName queueName, TimeSpan timeoutMs)
        {
            IEnumerable <string> result = Enumerable.Empty <string>();

            connectionString.WithConnection(con =>
            {
                var transaction = con.BeginTransaction();
                try
                {
                    result = ReceiveMessages(transaction, queueName, timeoutMs).ToArray();
                    transaction.Commit();
                }
                finally
                {
                    if (transaction.Connection == null || transaction.Connection.State != ConnectionState.Closed)
                    {
                        transaction.Dispose();
                    }
                }
            });
            return(result);
        }
 public AggregateFunctionModel(SqlObjectName name, MethodModel method, FunctionMetadata metadata, IType returnType)
     : base(name, method, metadata)
 {
     ReturnType = returnType;
 }
Beispiel #29
0
 public override StringBuilder BuildObjectName(StringBuilder sb, SqlObjectName name, ConvertType objectType, bool escape, TableOptions tableOptions)
 {
     return(escape ? Convert(sb, name.Name, objectType) : sb.Append(name.Name));
 }
Beispiel #30
0
 protected TableFunctionModelBase(SqlObjectName name, MethodModel method)
     : base(name, method)
 {
     Name = name;
 }