Esempio n. 1
0
        public void TestSchema()
        {
            using (NuoDbConnection connection = new NuoDbConnection(connectionString))
            {
                DataTable tables = connection.GetSchema("Tables");

                Boolean found = false;
                foreach (DataRow row in tables.Rows)
                {
                    if (row.Field<string>(2).Equals("HOCKEY"))
                        found = true;
                }
                Assert.IsTrue(found, "Table HOCKEY was not found in the list of tables");
            }
        }
        public override DataTable GetSchemaTable()
        {
            if (metadata != null)
            {
                return(metadata);
            }

#if DEBUG
            System.Diagnostics.Trace.WriteLine("NuoDbDataReader.GetSchemaTable(" + statement.CommandText + ")");
#endif
            EncodedDataStream dataStream = new EncodedDataStream();
            dataStream.startMessage(Protocol.GetMetaData);
            dataStream.encodeInt(handle);
            connection.InternalConnection.sendAndReceive(dataStream);
            int numberColumns = dataStream.getInt();

            metadata = new DataTable("SchemaTable");

            // Info on the schema of this table is at http://msdn.microsoft.com/en-us/library/system.data.odbc.odbcdatareader.getschematable.aspx
            // The zero-based ordinal of the column. This column cannot contain a null value.
            metadata.Columns.Add("ColumnOrdinal", typeof(int));
            // The name of the column; this might not be unique. If the column name cannot be determined, a null value is returned.
            // This name always reflects the most recent naming of the column in the current view or command text.
            metadata.Columns.Add("ColumnName", typeof(string));
            // The maximum possible length of a value in the column. For columns that use a fixed-length data type, this is the size of the data type.
            metadata.Columns.Add("ColumnSize", typeof(int));
            // If DbType is a numeric data type, this is the maximum precision of the column. The precision depends on the
            // definition of the column. If DbType is not a numeric data type, do not use the data in this column.
            // If the underlying ODBC driver returns a precision value for a non-numeric data type, this value is used in the schema table.
            metadata.Columns.Add("NumericPrecision", typeof(int));
            // If DbType is Decimal, the number of digits to the right of the decimal point. Otherwise, this is a null value.
            // If the underlying ODBC driver returns a precision value for a non-numeric data type, this value is used in the schema table.
            metadata.Columns.Add("NumericScale", typeof(int));
            // The name of the catalog in the data store that contains the column. NULL if the base catalog name cannot be determined.
            // The default for this column is a null value.
            metadata.Columns.Add("BaseCatalogName", typeof(string));
            // The name of the schema in the data source that contains the column. NULL if the base catalog name cannot be determined.
            // The default for this column is a null value.
            metadata.Columns.Add("BaseSchemaName", typeof(string));
            // The name of the table or view in the data store that contains the column. A null value if the base table name cannot be determined.
            // The default of this column is a null value.
            metadata.Columns.Add("BaseTableName", typeof(string));
            // The name of the column in the data store. This might be different from the column name returned in the ColumnName column if an alias was used.
            // A null value if the base column name cannot be determined or if the rowset column is derived, but not identical to, a column in the data store.
            // The default for this column is a null value.
            metadata.Columns.Add("BaseColumnName", typeof(string));
            // Maps to the common language runtime type of DbType.
            metadata.Columns.Add("DataType", typeof(Type));
            // The underlying driver type.
            metadata.Columns.Add("ProviderType", typeof(int));
            // true if the column contains a Binary Long Object (BLOB) that contains very long data. The definition of very long data is driver-specific.
            metadata.Columns.Add("IsLong", typeof(bool));
            // true if the column assigns values to new rows in fixed increments; otherwise false. The default for this column is false.
            metadata.Columns.Add("IsAutoIncrement", typeof(bool));
            // true if the column cannot be modified; otherwise false.
            metadata.Columns.Add("IsReadOnly", typeof(bool));
            // true: No two rows in the base table (the table returned in BaseTableName) can have the same value in this column.
            // IsUnique is guaranteed to be true if the column represents a key by itself or if there is a constraint of type UNIQUE that applies only to this column.
            // false: The column can contain duplicate values in the base table. The default for this column is false.
            metadata.Columns.Add("IsUnique", typeof(bool));
            // true: The column is one of a set of columns in the rowset that, taken together, uniquely identify the row.
            // The set of columns with IsKey set to true must uniquely identify a row in the rowset. There is no requirement that this set of columns is a minimal set of columns. This set of columns may be generated from a base table primary key, a unique constraint, or a unique index.
            // false: The column is not required to uniquely identify the row.
            metadata.Columns.Add("IsKey", typeof(bool));
            // Set if the column contains a persistent row identifier that cannot be written to, and has no meaningful value except to identity the row.
            metadata.Columns.Add("IsRowVersion", typeof(bool));
            // true if the consumer can set the column to a null value or if the driver cannot determine whether the consumer can set the column to a null value.
            // Otherwise, false. A column may contain null values, even if it cannot be set to a null value.
            metadata.Columns.Add("AllowDBNull", typeof(bool));

            // The SQLDataReader also returns these columns:
            // Returns a string representing the data type of the specified column.
            metadata.Columns.Add("DataTypeName", typeof(string));
            // true: The column is an identity column.
            // false: The column is not an identity column.
            metadata.Columns.Add("IsIdentity", typeof(bool));
            // true: The column is an expression column.
            // false: The column is not an expression column.
            metadata.Columns.Add("IsExpression", typeof(bool));

            metadata.BeginLoadData();
            for (int n = 0; n < numberColumns; ++n)
            {
                DataRow row = metadata.NewRow();
                row["ColumnOrdinal"] = n;
                // data fields must be read in this exact order!
                row["BaseCatalogName"] = dataStream.getString();
                row["BaseSchemaName"]  = dataStream.getString();
                row["BaseTableName"]   = dataStream.getString();
                row["BaseColumnName"]  = dataStream.getString();
                row["ColumnName"]      = dataStream.getString();
                string collationSequence = dataStream.getString();
                row["DataTypeName"]     = dataStream.getString();
                row["ProviderType"]     = NuoDbConnectionInternal.mapJavaSqlToDbType(dataStream.getInt());
                row["ColumnSize"]       = dataStream.getInt();
                row["NumericPrecision"] = dataStream.getInt();
                row["NumericScale"]     = dataStream.getInt();
                if (((DbType)row["ProviderType"] == DbType.Int16 || (DbType)row["ProviderType"] == DbType.Int32 || (DbType)row["ProviderType"] == DbType.Int64) &&
                    (int)row["NumericScale"] != 0)
                {
                    row["ProviderType"] = DbType.Decimal;
                }
                row["DataType"] = Type.GetType(NuoDbConnectionInternal.mapNuoDbToNetType((string)row["DataTypeName"], (int)row["NumericPrecision"], (int)row["NumericScale"]));
                int       flags                  = dataStream.getInt();
                const int rsmdSearchable         = (1 << 1);
                const int rsmdAutoIncrement      = (1 << 2);
                const int rsmdCaseSensitive      = (1 << 3);
                const int rsmdCurrency           = (1 << 4);
                const int rsmdDefinitelyWritable = (1 << 5);
                const int rsmdWritable           = (1 << 6);
                const int rsmdReadOnly           = (1 << 7);
                const int rsmdSigned             = (1 << 8);
                const int rsmdNullable           = (1 << 9);
                row["IsAutoIncrement"] = (flags & rsmdAutoIncrement) != 0;
                row["IsReadOnly"]      = (flags & rsmdReadOnly) != 0;
                row["AllowDBNull"]     = (flags & rsmdNullable) != 0;
                // for the moment, set the column to be a normal one; later we will look for primary indexes
                row["IsKey"]  = row["IsIdentity"] = row["IsUnique"] = false;
                row["IsLong"] = row["IsRowVersion"] = row["IsExpression"] = false;
                metadata.Rows.Add(row);

#if DEBUG
                System.Diagnostics.Trace.WriteLine("-> " + row["ColumnName"] + ", " +
                                                   row["DataTypeName"] + "(" + row["NumericPrecision"] + "," + row["NumericScale"] + ") " +
                                                   row["DataType"]);
#endif
            }
            metadata.EndLoadData();
            // fill in the IsPrimary column
            Dictionary <string, DataTable> schemas = new Dictionary <string, DataTable>();
            foreach (DataRow row in metadata.Rows)
            {
                string    key       = row["BaseSchemaName"] + "|" + row["BaseTableName"];
                DataTable indexInfo = null;
                if (!schemas.ContainsKey(key))
                {
                    indexInfo = connection.GetSchema("IndexColumns", new string[] { null, (string)row["BaseSchemaName"], (string)row["BaseTableName"] });
                    schemas.Add(key, indexInfo);
                }
                else
                {
                    indexInfo = schemas[key];
                }
                DataRow[] rows = indexInfo.Select(String.Format("INDEXCOLUMN_NAME = '{0}' AND INDEXCOLUMN_ISPRIMARY = true", row["BaseColumnName"]));
                if (rows != null && rows.Length > 0)
                {
                    row.BeginEdit();
                    row["IsKey"] = row["IsIdentity"] = true;
                    row.EndEdit();
                }
            }
            return(metadata);
        }