Ejemplo n.º 1
0
        public override async Task <DataTable> GetSchemaTableAsync(CancellationToken cancellationToken = default)
#endif
        {
            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.PrepareAsync(cancellationToken).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.ExecuteReaderAsync(CommandBehavior.Default, cancellationToken).ConfigureAwait(false);

                    try
                    {
                        if (await reader.ReadAsync(cancellationToken).ConfigureAwait(false))
                        {
                            isReadOnly   = IsReadOnly(reader) || IsExpression(reader);
                            isKeyColumn  = reader.GetInt32(2) == 1;
                            isUnique     = reader.GetInt32(3) == 1;
                            precision    = reader.IsDBNull(4) ? -1 : reader.GetInt32(4);
                            isExpression = IsExpression(reader);
                        }
                    }
                    finally
                    {
#if NET48 || NETSTANDARD2_0
                        reader.Dispose();
#else
                        await reader.DisposeAsync().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.CloseAsync().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 schemaCmd.DisposeAsync().ConfigureAwait(false);
#endif
            }

            return(_schemaTable);
        }