private async Task <DataTable> GetSchemaTableImpl(AsyncWrappingCommonArgs async) { CheckState(); if (_schemaTable != null) { return(_schemaTable); } DataRow schemaRow = null; var tableCount = 0; var currentTable = string.Empty; _schemaTable = GetSchemaTableStructure(); /* Prepare statement for schema fields information */ var schemaCmd = new FbCommand(GetSchemaCommandText(), _command.Connection, _command.Connection.InnerConnection.ActiveTransaction); try { schemaCmd.Parameters.Add("@TABLE_NAME", FbDbType.Char, 31); schemaCmd.Parameters.Add("@COLUMN_NAME", FbDbType.Char, 31); await schemaCmd.PrepareImpl(async).ConfigureAwait(false); _schemaTable.BeginLoadData(); for (var i = 0; i < _fields.Count; i++) { var isKeyColumn = false; var isUnique = false; var isReadOnly = false; var precision = 0; var isExpression = false; /* Get Schema data for the field */ schemaCmd.Parameters[0].Value = _fields[i].Relation; schemaCmd.Parameters[1].Value = _fields[i].Name; var reader = await schemaCmd.ExecuteReaderImpl(CommandBehavior.Default, async).ConfigureAwait(false); try { if (await reader.ReadImpl(async).ConfigureAwait(false)) { isReadOnly = (IsReadOnly(reader) || IsExpression(reader)) ? true : false; isKeyColumn = (reader.GetInt32(2) == 1) ? true : false; isUnique = (reader.GetInt32(3) == 1) ? true : false; precision = reader.IsDBNull(4) ? -1 : reader.GetInt32(4); isExpression = IsExpression(reader); } } finally { #if NET48 || NETSTANDARD2_0 reader.Dispose(); #else await async.AsyncSyncCallNoCancellation(reader.DisposeAsync, reader.Dispose).ConfigureAwait(false); #endif } /* Create new row for the Schema Table */ schemaRow = _schemaTable.NewRow(); schemaRow["ColumnName"] = GetName(i); schemaRow["ColumnOrdinal"] = i; schemaRow["ColumnSize"] = _fields[i].GetSize(); if (_fields[i].IsDecimal()) { schemaRow["NumericPrecision"] = schemaRow["ColumnSize"]; if (precision > 0) { schemaRow["NumericPrecision"] = precision; } schemaRow["NumericScale"] = _fields[i].NumericScale * (-1); } schemaRow["DataType"] = GetFieldType(i); schemaRow["ProviderType"] = GetProviderType(i); schemaRow["IsLong"] = _fields[i].IsLong(); schemaRow["AllowDBNull"] = _fields[i].AllowDBNull(); schemaRow["IsRowVersion"] = false; schemaRow["IsAutoIncrement"] = false; schemaRow["IsReadOnly"] = isReadOnly; schemaRow["IsKey"] = isKeyColumn; schemaRow["IsUnique"] = isUnique; schemaRow["IsAliased"] = _fields[i].IsAliased(); schemaRow["IsExpression"] = isExpression; schemaRow["BaseSchemaName"] = DBNull.Value; schemaRow["BaseCatalogName"] = DBNull.Value; schemaRow["BaseTableName"] = _fields[i].Relation; schemaRow["BaseColumnName"] = _fields[i].Name; _schemaTable.Rows.Add(schemaRow); if (!string.IsNullOrEmpty(_fields[i].Relation) && currentTable != _fields[i].Relation) { tableCount++; currentTable = _fields[i].Relation; } await schemaCmd.Close(async).ConfigureAwait(false); } if (tableCount > 1) { foreach (DataRow row in _schemaTable.Rows) { row["IsKey"] = false; row["IsUnique"] = false; } } _schemaTable.EndLoadData(); } finally { #if NET48 || NETSTANDARD2_0 schemaCmd.Dispose(); #else await async.AsyncSyncCallNoCancellation(schemaCmd.DisposeAsync, schemaCmd.Dispose).ConfigureAwait(false); #endif } return(_schemaTable); }
public override DataTable GetSchemaTable() { CheckState(); if (_schemaTable != null) { return(_schemaTable); } DataRow schemaRow = null; var tableCount = 0; var currentTable = string.Empty; _schemaTable = GetSchemaTableStructure(); /* Prepare statement for schema fields information */ var schemaCmd = new FbCommand( GetSchemaCommandText(), _command.Connection, _command.Connection.InnerConnection.ActiveTransaction); schemaCmd.Parameters.Add("@TABLE_NAME", FbDbType.Char, 31); schemaCmd.Parameters.Add("@COLUMN_NAME", FbDbType.Char, 31); schemaCmd.Prepare(); _schemaTable.BeginLoadData(); for (var i = 0; i < _fields.Count; i++) { var isKeyColumn = false; var isUnique = false; var isReadOnly = false; var precision = 0; var isExpression = false; /* Get Schema data for the field */ schemaCmd.Parameters[0].Value = _fields[i].Relation; schemaCmd.Parameters[1].Value = _fields[i].Name; using (var r = schemaCmd.ExecuteReader()) { if (r.Read()) { isReadOnly = (IsReadOnly(r) || IsExpression(r)) ? true : false; isKeyColumn = (r.GetInt32(2) == 1) ? true : false; isUnique = (r.GetInt32(3) == 1) ? true : false; precision = r.IsDBNull(4) ? -1 : r.GetInt32(4); isExpression = IsExpression(r); } } /* Create new row for the Schema Table */ schemaRow = _schemaTable.NewRow(); schemaRow["ColumnName"] = GetName(i); schemaRow["ColumnOrdinal"] = i; schemaRow["ColumnSize"] = _fields[i].GetSize(); if (_fields[i].IsDecimal()) { schemaRow["NumericPrecision"] = schemaRow["ColumnSize"]; if (precision > 0) { schemaRow["NumericPrecision"] = precision; } schemaRow["NumericScale"] = _fields[i].NumericScale * (-1); } schemaRow["DataType"] = GetFieldType(i); schemaRow["ProviderType"] = GetProviderType(i); schemaRow["IsLong"] = _fields[i].IsLong(); schemaRow["AllowDBNull"] = _fields[i].AllowDBNull(); schemaRow["IsRowVersion"] = false; schemaRow["IsAutoIncrement"] = false; schemaRow["IsReadOnly"] = isReadOnly; schemaRow["IsKey"] = isKeyColumn; schemaRow["IsUnique"] = isUnique; schemaRow["IsAliased"] = _fields[i].IsAliased(); schemaRow["IsExpression"] = isExpression; schemaRow["BaseSchemaName"] = DBNull.Value; schemaRow["BaseCatalogName"] = DBNull.Value; schemaRow["BaseTableName"] = _fields[i].Relation; schemaRow["BaseColumnName"] = _fields[i].Name; _schemaTable.Rows.Add(schemaRow); if (!string.IsNullOrEmpty(_fields[i].Relation) && currentTable != _fields[i].Relation) { tableCount++; currentTable = _fields[i].Relation; } /* Close statement */ schemaCmd.Close(); } if (tableCount > 1) { foreach (DataRow row in _schemaTable.Rows) { row["IsKey"] = false; row["IsUnique"] = false; } } _schemaTable.EndLoadData(); /* Dispose command */ schemaCmd.Dispose(); return(_schemaTable); }
public override DataTable GetSchemaTable() { this.CheckState(); if (this.schemaTable != null) { return(this.schemaTable); } #region Variables DataRow schemaRow = null; int tableCount = 0; string currentTable = string.Empty; this.schemaTable = GetSchemaTableStructure(); const Int16 batchLimit = 90; //Could be adjusted as needed. Int16 paramCounter = 0; //Counter for the whole batch process Int16 batchRounds = 0; //counter for each batch (limited by batchlimit) Hashtable relationList = new Hashtable(); //HashTable to store the query's unique Field Tables Names. List <RDBTableInfo> fieldList = new List <RDBTableInfo>(this.fields.Count + 1); //List to store the whole statement Schema Field Values. const Int16 metadataColSize = 31; //Firebird MAX Column Size. Int16 batchID = 0; //Batch marker. When batchlimit reaches its limit it increases by one the value. StringBuilder sb = new StringBuilder(); //Stores dynamic generated schema query. #endregion // Prepare statement for schema fields information //Asign current active schema command connection and transaccion FbCommand schemaCmd = new FbCommand(); schemaCmd.Connection = this.command.Connection; schemaCmd.Transaction = this.command.Connection.InnerConnection.ActiveTransaction; for (paramCounter = 0; paramCounter < this.FieldCount; paramCounter++) { if (batchRounds >= batchLimit) //Process field params until batch limit is reached. { batchID++; batchRounds = 0; } RDBTableInfo rdbinfo = new RDBTableInfo(); rdbinfo.Ordinal = paramCounter; rdbinfo.FieldName = this.fields[paramCounter].Name; rdbinfo.RelationName = this.fields[paramCounter].Relation; rdbinfo.BatchID = batchID; fieldList.Add(rdbinfo); batchRounds++; } //Process batch schema query for (Int16 i = 0; i <= batchID; i++) { sb.Length = 0; relationList.Clear(); List <RDBTableInfo> rdblBatch = new List <RDBTableInfo>(this.fields.Count + 1); //Find all RDBTableInfo elements according to batchID rdblBatch = fieldList.FindAll(rdbti => rdbti.BatchID == i); //Just add the needed tables according to the fieldnames on the current batch. for (Int16 j = 0; j < rdblBatch.Count; j++) { //Keep a list of unique relation names (tables) from all the fieldlist. if (!relationList.ContainsValue(rdblBatch[j].RelationName)) { relationList.Add(relationList.Count, rdblBatch[j].RelationName); } } if (schemaCmd.Parameters.Count > 0) //Clear previous command parameters. { schemaCmd.Parameters.Clear(); } //Get the Base Squema query to start generating Dynamic Schema query sb.Append(GetSchemaCommandTextBase()); //Perform batch field query against table schema //Add relation (table names) to schemaCmd for (int j = 0; j < relationList.Count; j++) { if (j > 0) //More than one table in query statement { sb.Append(" OR "); } List <RDBTableInfo> tmpList = rdblBatch.FindAll(rdbti => rdbti.RelationName.Equals(relationList[j])); sb.AppendFormat(" (rfr.rdb$field_name in {0} AND rfr.rdb$relation_name='{1}') ", GetParamExpression(tmpList.Count), relationList[j]); for (int k = 0; k < tmpList.Count; k++) { schemaCmd.Parameters.Add("@COLUMN_NAME", FbDbType.Char, metadataColSize).Value = tmpList[k].FieldName; } tmpList = null; } //set order to schema query sb.Append(" ORDER BY rfr.rdb$relation_name, rfr.rdb$field_position"); schemaCmd.CommandText = sb.ToString(); schemaCmd.Prepare(); schemaTable.BeginLoadData(); //Reset Column Values int Ordinal = 0; int batchCount = 0; //perform batch query using (FbDataReader r = schemaCmd.ExecuteReader()) { batchCount = 0;//reset batch counter while (r.Read()) { rdblBatch[batchCount].isReadOnly = (IsReadOnly(r) || IsExpression(r)) ? true : false; rdblBatch[batchCount].isKeyColumn = (r.GetInt32(2) == 1) ? true : false; rdblBatch[batchCount].isUnique = (r.GetInt32(3) == 1) ? true : false; rdblBatch[batchCount].precision = r.IsDBNull(4) ? -1 : r.GetInt32(4); rdblBatch[batchCount].isExpression = IsExpression(r); batchCount++; } } for (int j = 0; j < rdblBatch.Count; j++) { Ordinal = rdblBatch[j].Ordinal; // Create new row for the Schema Table schemaRow = schemaTable.NewRow(); schemaRow["ColumnName"] = this.GetName(Ordinal); schemaRow["ColumnOrdinal"] = Ordinal; schemaRow["ColumnSize"] = this.fields[Ordinal].GetSize(); if (fields[Ordinal].IsDecimal()) { schemaRow["NumericPrecision"] = schemaRow["ColumnSize"]; if (rdblBatch[j].precision > 0) { schemaRow["NumericPrecision"] = rdblBatch[j].precision; } schemaRow["NumericScale"] = this.fields[Ordinal].NumericScale * (-1); } schemaRow["DataType"] = this.GetFieldType(Ordinal); schemaRow["ProviderType"] = this.GetProviderType(Ordinal); schemaRow["IsLong"] = this.fields[Ordinal].IsLong(); schemaRow["AllowDBNull"] = this.fields[Ordinal].AllowDBNull(); schemaRow["IsRowVersion"] = false; schemaRow["IsAutoIncrement"] = false; schemaRow["IsReadOnly"] = rdblBatch[j].isReadOnly; schemaRow["IsKey"] = rdblBatch[j].isKeyColumn; schemaRow["IsUnique"] = rdblBatch[j].isUnique; schemaRow["IsAliased"] = this.fields[Ordinal].IsAliased(); schemaRow["IsExpression"] = rdblBatch[j].isExpression; schemaRow["BaseSchemaName"] = DBNull.Value; schemaRow["BaseCatalogName"] = DBNull.Value; schemaRow["BaseTableName"] = this.fields[Ordinal].Relation; schemaRow["BaseColumnName"] = this.fields[Ordinal].Name; schemaTable.Rows.Add(schemaRow); if (!String.IsNullOrEmpty(this.fields[Ordinal].Relation) && currentTable != this.fields[Ordinal].Relation) { tableCount++; currentTable = this.fields[Ordinal].Relation; } } schemaTable.EndLoadData(); rdblBatch = null; }//Finish Batch Round Iteration schemaCmd.Close(); if (tableCount > 1) { foreach (DataRow row in schemaTable.Rows) { row["IsKey"] = false; row["IsUnique"] = false; } } //Dispose command schemaCmd.Dispose(); relationList = null; fieldList = null; return(schemaTable); }