예제 #1
0
        public virtual IEnumerable <IntrospectedIndex> GetAllUniqueIndexes(NrdoConnection connection)
        {
            var uniqueIndexColumns = connection.ExecuteSql("select k.constraint_schema as k_schema, k.constraint_name as k_name, k.table_schema as t_schema, k.table_name as t_name, " +
                                                           "k.constraint_type as k_type, u.column_name as c_name, u.ordinal_position as c_index " +
                                                           "from information_schema.table_constraints k, information_schema.key_column_usage u " +
                                                           "where (k.constraint_type = 'PRIMARY KEY' or k.constraint_type = 'UNIQUE') " +
                                                           "and k.constraint_schema = u.constraint_schema and k.constraint_name = u.constraint_name " +
                                                           "and k.table_schema = u.table_schema and k.table_name = u.table_name ",
                                                           result => new
            {
                keySchema   = result.GetString("k_schema"),
                keyName     = result.GetString("k_name"),
                tableSchema = result.GetString("t_schema"),
                tableName   = result.GetString("t_name"),
                keyType     = result.GetString("k_type"),
                columnName  = result.GetString("c_name"),
                columnIndex = result.GetInt("c_index"),
            });

            return(from col in uniqueIndexColumns
                   group col by new { col.keySchema, col.keyName, col.tableSchema, col.tableName, col.keyType } into cols
                   select new IntrospectedIndex(
                       new IntrospectedTable(cols.Key.tableSchema, cols.Key.tableName),
                       StringEquals(cols.Key.keyType, "PRIMARY KEY"), true, cols.Key.keyName,
                       from col in cols orderby col.columnIndex select col.columnName));
        }
예제 #2
0
 public virtual IEnumerable <string> GetAllFulltextCatalogs(NrdoConnection connection)
 {
     if (IsFulltextCatalogUsed)
     {
         throw new NotImplementedException("Getting existing fulltext catalogs not implemented on " + DisplayName);
     }
     yield break;
 }
예제 #3
0
 public virtual IEnumerable <IntrospectedFulltextIndex> GetAllFulltextIndexes(NrdoConnection connection)
 {
     if (IsFulltextIndexSupported)
     {
         throw new NotImplementedException("Getting existing fulltext indexes not implemented on " + DisplayName);
     }
     yield break;
 }
예제 #4
0
 public virtual void TryAcquireSchemaUpdateLock(NrdoConnection connection)
 {
     // FIXME: the semantics of this method are easy to achieve on SQL server but may not be as easy to do on other database systems.
     // Finishing up support for other systems may require changing the API to something that's less convenient for the calling code.
     // The semantics of the method currently are:
     // - Only one connection can hold the lock at once
     // - Once a connection is holding the lock, any other connection trying to take it will fail with a SchemaLockFailException
     // - When the connection that's holding the lock is closed, the lock is automatically released
     throw new NotImplementedException("Schema lock not implemented on " + DisplayName);
 }
예제 #5
0
 public override void TryAcquireSchemaUpdateLock(NrdoConnection connection)
 {
     try
     {
         connection.ExecuteSql(GetCreateTableSql("##nrdo_update_in_progress", new[] { new FieldCreation("nothing", "int", true, false, null) }));
     }
     catch (DbException)
     {
         throw new SchemaLockFailException();
     }
 }
예제 #6
0
 public NrdoConnection GetConnection()
 {
     if (disposed)
     {
         throw new InvalidCastException("Cannot get a connection from a disposed scope");
     }
     if (conn == null)
     {
         NrdoStats.UpdateGlobalStats(stats => stats.WithConnectionStart());
         conn = NrdoConnection.Create(dataBase);
     }
     return(conn);
 }
예제 #7
0
        public virtual IEnumerable <IntrospectedProc> GetAllStoredProcsAndFunctions(NrdoConnection connection)
        {
            var routines = connection.ExecuteSql("select r.specific_schema as s_schema, r.specific_name as s_name, " + // Doesn't seem to be any difference between specific_xyz and routine_xyz but just in case...
                                                 "r.routine_schema as r_schema, r.routine_name as r_name, " +
                                                 "r.routine_type as r_type, " +
                                                 "r.data_type as r_datatype, r.character_maximum_length as r_length, " +
                                                 "r.numeric_precision as r_precision, r.numeric_scale as r_scale, " +
                                                 "r.routine_definition as r_definition " +
                                                 "from information_schema.routines r " +
                                                 "where (r.routine_type = 'PROCEDURE' or r.routine_type = 'FUNCTION') " +
                                                 "and r.routine_body = 'SQL'",
                                                 result => new
            {
                specSchema = result.GetString("s_schema"),
                specName   = result.GetString("s_name"),
                schema     = result.GetString("r_schema"),
                name       = result.GetString("r_name"),
                type       = result.GetString("r_type"),
                dataType   = result.GetString("r_datatype") == null ? null :
                             GetDataTypeName(result.GetString("r_datatype"), result.GetInt("r_length"), result.GetByte("r_precision"), result.GetInt("r_scale")),
                definition = result.GetString("r_definition"),
            });

            var parameters = connection.ExecuteSql("select p.specific_schema as s_schema, p.specific_name as s_name, p.ordinal_position as p_index, " +
                                                   "p.parameter_name as p_name, p.data_type as p_type, p.character_maximum_length as p_length, " +
                                                   "p.numeric_precision as p_precision, p.numeric_scale as p_scale " +
                                                   "from information_schema.parameters p " +
                                                   "where p.is_result = 'NO'",
                                                   result => new
            {
                specSchema = result.GetString("s_schema"),
                specName   = result.GetString("s_name"),
                name       = UnquoteParam(result.GetString("p_name")),
                index      = result.GetInt("p_index"),
                dataType   = GetDataTypeName(result.GetString("p_type"), result.GetInt("p_length"), result.GetByte("p_precision"), result.GetInt("p_scale")),
            });

            return(from r in routines
                   join p in parameters on new { r.specSchema, r.specName } equals new { p.specSchema, p.specName } into rparams
                   let procParams = from param in rparams orderby param.index select new ProcParam(param.name, param.dataType)
                                    select StringEquals(r.type, "FUNCTION") ?
                                    new IntrospectedFunction(r.schema, r.name, procParams, r.dataType, ExtractFunctionBody(r.definition)) :
                                    new IntrospectedProc(r.schema, r.name, procParams, ExtractProcBody(r.definition)));
        }
예제 #8
0
        public override IEnumerable <IntrospectedTrigger> GetAllTriggers(NrdoConnection connection)
        {
            var triggers = connection.ExecuteSql(@"
                select tr.object_id as o_id,
                       object_schema_name(tr.parent_id) as t_schema, object_name(tr.parent_id) as t_name,
                       object_schema_name(tr.object_id) as tr_schema, tr.name as tr_name,
                       object_definition(tr.object_id) as tr_definition, is_instead_of_trigger as tr_instead
                from sys.triggers tr",
                                                 result => new
            {
                objectId      = result.GetInt("o_id"),
                tableSchema   = result.GetString("t_schema"),
                tableName     = result.GetString("t_name"),
                triggerSchema = result.GetString("tr_schema"),
                triggerName   = result.GetString("tr_name"),
                triggerDef    = result.GetString("tr_definition"),
                timing        = (bool)result.GetBool("tr_instead") ? TriggerTiming.InsteadOf : TriggerTiming.After,
            });

            var events = connection.ExecuteSql("select e.object_id as o_id, e.type_desc as tr_event from sys.trigger_events e",
                                               result => new
            {
                objectId = result.GetInt("o_id"),
                evt      = (TriggerEvents)Enum.Parse(typeof(TriggerEvents), result.GetString("tr_event"), true),
            });

            var triggerEvents = triggers.ToDictionary(tr => tr.objectId, tr => default(TriggerEvents));

            foreach (var triggerEvent in events)
            {
                triggerEvents[triggerEvent.objectId] |= triggerEvent.evt;
            }

            return(from trigger in triggers
                   select new IntrospectedTrigger(trigger.triggerSchema, trigger.triggerName,
                                                  new IntrospectedTable(trigger.tableSchema, trigger.tableName),
                                                  trigger.timing, triggerEvents[trigger.objectId], ExtractTriggerBody(trigger.triggerDef)));
        }
예제 #9
0
        public virtual IEnumerable <IntrospectedField> GetAllFields(NrdoConnection connection)
        {
            string isIdentitySelectSql;
            string isIdentityFromSql;
            string isIdentityWhereSql;
            Func <NrdoResult, bool>   getIdentity;
            Func <NrdoResult, string> getSequenceName;

            GetInformationSchemaFieldIsSequencedSql("c", out isIdentitySelectSql, out isIdentityFromSql, out isIdentityWhereSql, out getIdentity, out getSequenceName);

            return(connection.ExecuteSql("select c.table_schema as t_schema, c.table_name as t_name, c.column_name as c_name, c.is_nullable as c_nullable, " +
                                         "c.ordinal_position as c_pos, c.data_type as c_type, c.character_maximum_length as c_length, " +
                                         "c.numeric_precision as c_precision, c.numeric_scale as c_scale" + isIdentitySelectSql +
                                         " from information_schema.tables t, information_schema.columns c" + isIdentityFromSql +
                                         " where t.table_schema = c.table_schema and t.table_name = c.table_name and t.table_type = 'BASE TABLE'" + isIdentityWhereSql,
                                         result => new IntrospectedField(new IntrospectedTable(result.GetString("t_schema"), result.GetString("t_name")),
                                                                         result.GetString("c_name"),
                                                                         (int)result.GetInt("c_pos"),
                                                                         GetDataTypeName(result.GetString("c_type"), result.GetInt("c_length"), result.GetByte("c_precision"), result.GetInt("c_scale")),
                                                                         GetInformationSchemaFieldNullability(result.GetString("c_nullable")),
                                                                         getIdentity(result),
                                                                         getSequenceName(result))));
        }
예제 #10
0
        public override IEnumerable <IntrospectedIndex> GetAllNonUniqueIndexes(NrdoConnection connection)
        {
            var indexColumns = connection.ExecuteSql("select object_schema_name(i.object_id) as t_schema, object_name(i.object_id) as t_name, i.name as i_name, " +
                                                     "c.name as c_name, ic.key_ordinal as c_index " +
                                                     "from sys.indexes i, information_schema.tables t, sys.index_columns ic, sys.columns c " +
                                                     "where i.is_unique = 0 and t.table_schema = object_schema_name(i.object_id) and t.table_name = object_name(i.object_id) " +
                                                     "and ic.is_included_column = 0 " +
                                                     "and ic.object_id = i.object_id and ic.index_id = i.index_id and ic.column_id = c.column_id and ic.object_id = c.object_id",
                                                     result => new
            {
                tableSchema = result.GetString("t_schema"),
                tableName   = result.GetString("t_name"),
                indexName   = result.GetString("i_name"),
                columnName  = result.GetString("c_name"),
                columnIndex = result.GetByte("c_index"),
            });

            return(from col in indexColumns
                   group col by new { col.tableSchema, col.tableName, col.indexName } into cols
                   select new IntrospectedIndex(
                       new IntrospectedTable(cols.Key.tableSchema, cols.Key.tableName),
                       false, false, cols.Key.indexName,
                       from col in cols orderby col.columnIndex select col.columnName));
        }
예제 #11
0
        public virtual IEnumerable <IntrospectedForeignKey> GetAllForeignKeys(NrdoConnection connection)
        {
            var fkeyJoins = connection.ExecuteSql("select from_k.table_schema as from_t_schema, from_k.table_name as from_t_name, " +
                                                  "to_k.table_schema as to_t_schema, to_k.table_name as to_t_name, " +
                                                  "f.constraint_name as f_name, f.delete_rule as f_rule, " +
                                                  "from_u.column_name as from_c_name, to_u.column_name as to_c_name, " +
                                                  "from_u.ordinal_position as c_index " +
                                                  "from information_schema.referential_constraints f, " +
                                                  "information_schema.table_constraints from_k, information_schema.table_constraints to_k, " +
                                                  "information_schema.key_column_usage from_u, information_schema.key_column_usage to_u " +
                                                  "where f.constraint_schema = from_k.constraint_schema and f.constraint_name = from_k.constraint_name " +
                                                  "and f.unique_constraint_schema = to_k.constraint_schema and f.unique_constraint_name = to_k.constraint_name " +
                                                  "and f.constraint_schema = from_u.constraint_schema and f.constraint_name = from_u.constraint_name " +
                                                  "and f.unique_constraint_schema = to_u.constraint_schema and f.unique_constraint_name = to_u.constraint_name " +
                                                  "and from_u.ordinal_position = to_u.ordinal_position",
                                                  result => new
            {
                fromSchema    = result.GetString("from_t_schema"),
                fromTableName = result.GetString("from_t_name"),
                toSchema      = result.GetString("to_t_schema"),
                toTableName   = result.GetString("to_t_name"),
                fkeyName      = result.GetString("f_name"),
                deleteRule    = result.GetString("f_rule"),
                fromColumn    = result.GetString("from_c_name"),
                toColumn      = result.GetString("to_c_name"),
                columnIndex   = result.GetInt("c_index"),
            });

            return(from j in fkeyJoins
                   group j by new { j.fromSchema, j.fromTableName, j.toSchema, j.toTableName, j.fkeyName, j.deleteRule } into joins
                   select new IntrospectedForeignKey(
                       new IntrospectedTable(joins.Key.fromSchema, joins.Key.fromTableName),
                       new IntrospectedTable(joins.Key.toSchema, joins.Key.toTableName),
                       joins.Key.fkeyName, StringEquals(joins.Key.deleteRule, "CASCADE"),
                       from fieldPair in joins orderby fieldPair.columnIndex select new FieldPair(fieldPair.fromColumn, fieldPair.toColumn)));
        }
예제 #12
0
 public override IEnumerable <string> GetAllFulltextCatalogs(NrdoConnection connection)
 {
     return(connection.ExecuteSql("select name from sys.fulltext_catalogs", result => result.GetString("name")));
 }
예제 #13
0
        public override IEnumerable <IntrospectedIndexCustomState> GetAllIndexCustomState(NrdoConnection connection)
        {
            var indexClustered = connection.ExecuteSql("select i.object_id as o_id, i.index_id as i_id, object_schema_name(i.object_id) as t_schema, object_name(i.object_id) as t_name, i.name as i_name, " +
                                                       "type_desc as i_type from sys.indexes i " +
                                                       "where i.type_desc = 'NONCLUSTERED' or i.type_desc = 'CLUSTERED'",
                                                       result => new
            {
                objectId    = result.GetInt("o_id"),
                indexId     = result.GetInt("i_id"),
                tableSchema = result.GetString("t_schema"),
                tableName   = result.GetString("t_name"),
                indexName   = result.GetString("i_name"),
                isClustered = getIsClustered(result.GetString("i_type")),
            });

            var indexColumns = connection.ExecuteSql("select ic.object_id as o_id, ic.index_id as i_id, c.name as c_name " +
                                                     "from sys.index_columns ic, sys.columns c " +
                                                     "where ic.is_included_column = 1 and ic.column_id = c.column_id and ic.object_id = c.object_id",
                                                     result => new
            {
                objectId   = result.GetInt("o_id"),
                indexId    = result.GetInt("i_id"),
                columnName = result.GetString("c_name"),
            });

            return(from index in indexClustered
                   join col in indexColumns on new { index.objectId, index.indexId } equals new { col.objectId, col.indexId } into includedCols
                   select new IntrospectedIndexCustomState(
                       new IntrospectedTable(index.tableSchema, index.tableName),
                       index.indexName,
                       new SqlServerIndexCustomState(index.isClustered, from c in includedCols select c.columnName)));
        }
예제 #14
0
 // INFORMATION_SCHEMA does not include a way to get at non-unique indexes
 public abstract IEnumerable <IntrospectedIndex> GetAllNonUniqueIndexes(NrdoConnection connection);
예제 #15
0
 public int GetSqlServerMajorVersion(NrdoConnection connection)
 {
     // This combination of ServerProperty and ParseName extracts the major number from the sql server version
     return((int)connection.ExecuteSql("SELECT Cast(ParseName(Cast(ServerProperty('ProductVersion') As nvarchar), 4) As int) AS [sql_version]",
                                       result => result.GetInt("sql_version")).Single());
 }
예제 #16
0
 public override string GetEnableFulltextSql(NrdoConnection connection)
 {
     return(GetSqlServerMajorVersion(connection) <= 9 ? "EXEC sp_fulltext_database 'enable'" : null);
 }
예제 #17
0
 // INFORMATION_SCHEMA does not provide a standard way to get triggers.
 public abstract IEnumerable <IntrospectedTrigger> GetAllTriggers(NrdoConnection connection);
예제 #18
0
 // It's slightly hacky to have core nrdo support for SQL server specific features, but figuring out a general extensibility mechanism
 // would be more work than there's time for for now, so these methods pick up clustering and included-field information about indexes
 // on "any database that happens to support it" - which is to say, SQL server.
 public virtual IEnumerable <IntrospectedIndexCustomState> GetAllIndexCustomState(NrdoConnection connection)
 {
     yield break;
 }
예제 #19
0
 public virtual IEnumerable <IntrospectedTable> GetAllTables(NrdoConnection connection)
 {
     return(connection.ExecuteSql("select t.table_schema as t_schema, t.table_name as t_name from information_schema.tables t where t.table_type = 'BASE TABLE'",
                                  result => new IntrospectedTable(result.GetString("t_schema"), result.GetString("t_name"))));
 }
예제 #20
0
 public virtual string GetEnableFulltextSql(NrdoConnection connection)
 {
     return(null);
 }
예제 #21
0
 public override IEnumerable <IntrospectedIndex> GetAllNonUniqueIndexes(NrdoConnection connection)
 {
     throw new NotImplementedException("Determining existing non-unique indexes is not supported on " + DisplayName);
 }
예제 #22
0
 public virtual IEnumerable <IntrospectedView> GetAllViews(NrdoConnection connection)
 {
     return(connection.ExecuteSql("select t.table_schema as t_schema, t.table_name as t_name, t.view_definition as t_def from information_schema.views t",
                                  result => new IntrospectedView(result.GetString("t_schema"), result.GetString("t_name"), ExtractViewBody(result.GetString("t_def")))));
 }
예제 #23
0
        public override IEnumerable <IntrospectedFulltextIndex> GetAllFulltextIndexes(NrdoConnection connection)
        {
            var fulltextIndexes = connection.ExecuteSql(@"
                select f.object_id as o_id, object_schema_name(f.object_id) as t_schema, object_name(f.object_id) as t_name, i.name as i_name, c.name as c_name
	                from sys.fulltext_indexes f, sys.indexes i, sys.fulltext_catalogs c
	                where f.object_id = i.object_id and f.unique_index_id = i.index_id
		                and f.fulltext_catalog_id = c.fulltext_catalog_id"        ,
                                                        result => new
            {
                objectId    = result.GetInt("o_id"),
                tableSchema = result.GetString("t_schema"),
                tableName   = result.GetString("t_name"),
                keyName     = result.GetString("i_name"),
                catalogName = result.GetString("c_name"),
            });

            var columns = connection.ExecuteSql(@"
                select f.object_id as o_id, c.name as c_name
	                from sys.fulltext_index_columns f, sys.columns c
	                where f.object_id = c.object_id and f.column_id = c.column_id"    ,
                                                result => new
            {
                objectId   = result.GetInt("o_id"),
                columnName = result.GetString("c_name"),
            });

            return(from i in fulltextIndexes
                   select new IntrospectedFulltextIndex(new IntrospectedTable(i.tableSchema, i.tableName), i.catalogName, i.keyName,
                                                        from c in columns where c.objectId == i.objectId select c.columnName));
        }
예제 #24
0
 public override bool IsFulltextSupported(NrdoConnection connection)
 {
     return(connection.ExecuteSql("SELECT fulltextserviceproperty('isfulltextinstalled') AS [fulltext_enabled]",
                                  result => result.GetInt("fulltext_enabled") == 1).Single());
 }
예제 #25
0
 public virtual IEnumerable <IntrospectedSequence> GetAllSequences(NrdoConnection connection)
 {
     return(connection.ExecuteSql("select s.sequence_schema as s_schema, s.sequence_name as s_name from information_schema.sequences s",
                                  result => new IntrospectedSequence(result.GetString("s_schema"), result.GetString("s_name"))));
 }
예제 #26
0
 public override IEnumerable <IntrospectedTrigger> GetAllTriggers(NrdoConnection connection)
 {
     throw new NotImplementedException("Determining existing triggers is not supported on " + DisplayName);
 }
예제 #27
0
 public virtual bool IsFulltextSupported(NrdoConnection connection)
 {
     return(IsFulltextIndexSupported);
 }