Skip to content

Commit

Permalink
Merge pull request #58 from snowflakedb/pr-57
Browse files Browse the repository at this point in the history
Pr 57
  • Loading branch information
howryu authored Aug 31, 2018
2 parents c38a768 + 1ba9915 commit 8bc422e
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 3 deletions.
70 changes: 68 additions & 2 deletions Snowflake.Data.Tests/SFDbDataReaderIT.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

using System;
using System.Linq;
using System.Collections.Generic;
using System.Data.Common;
using System.Data;
using System.Text;

Expand Down Expand Up @@ -660,5 +660,71 @@ public void TestRetrieveSemiStructuredData()
conn.Close();
}
}

[Test]
public void TestResultSetMetadata()
{
using (IDbConnection conn = new SnowflakeDbConnection())
{
conn.ConnectionString = connectionString;
conn.Open();

IDbCommand cmd = conn.CreateCommand();
cmd.CommandText = "create or replace table meta(c1 number(20, 4), c2 string(100), " +
"c3 double, c4 timestamp_ntz, c5 variant not null, c6 boolean) ";
cmd.ExecuteNonQuery();

cmd.CommandText = "select * from meta";
using (IDataReader reader = cmd.ExecuteReader())
{
var dataTable = reader.GetSchemaTable();
dataTable.DefaultView.Sort = SchemaTableColumn.ColumnName;
dataTable = dataTable.DefaultView.ToTable();

DataRow row = dataTable.Rows[0];
Assert.AreEqual("C1", row[SchemaTableColumn.ColumnName]);
Assert.AreEqual(0, row[SchemaTableColumn.ColumnOrdinal]);
Assert.AreEqual(20, row[SchemaTableColumn.NumericPrecision]);
Assert.AreEqual(4, row[SchemaTableColumn.NumericScale]);
Assert.AreEqual(SFDataType.FIXED, (SFDataType)row[SchemaTableColumn.ProviderType]);
Assert.AreEqual(true, row[SchemaTableColumn.AllowDBNull]);

row = dataTable.Rows[1];
Assert.AreEqual("C2", row[SchemaTableColumn.ColumnName]);
Assert.AreEqual(1, row[SchemaTableColumn.ColumnOrdinal]);
Assert.AreEqual(100, row[SchemaTableColumn.ColumnSize]);
Assert.AreEqual(SFDataType.TEXT, (SFDataType)row[SchemaTableColumn.ProviderType]);
Assert.AreEqual(true, row[SchemaTableColumn.AllowDBNull]);

row = dataTable.Rows[2];
Assert.AreEqual("C3", row[SchemaTableColumn.ColumnName]);
Assert.AreEqual(2, row[SchemaTableColumn.ColumnOrdinal]);
Assert.AreEqual(SFDataType.REAL, (SFDataType)row[SchemaTableColumn.ProviderType]);
Assert.AreEqual(true, row[SchemaTableColumn.AllowDBNull]);

row = dataTable.Rows[3];
Assert.AreEqual("C4", row[SchemaTableColumn.ColumnName]);
Assert.AreEqual(3, row[SchemaTableColumn.ColumnOrdinal]);
Assert.AreEqual(0, row[SchemaTableColumn.NumericPrecision]);
Assert.AreEqual(9, row[SchemaTableColumn.NumericScale]);
Assert.AreEqual(SFDataType.TIMESTAMP_NTZ, (SFDataType)row[SchemaTableColumn.ProviderType]);
Assert.AreEqual(true, row[SchemaTableColumn.AllowDBNull]);

row = dataTable.Rows[4];
Assert.AreEqual("C5", row[SchemaTableColumn.ColumnName]);
Assert.AreEqual(4, row[SchemaTableColumn.ColumnOrdinal]);
Assert.AreEqual(SFDataType.VARIANT, (SFDataType)row[SchemaTableColumn.ProviderType]);
Assert.AreEqual(false, row[SchemaTableColumn.AllowDBNull]);

row = dataTable.Rows[5];
Assert.AreEqual("C6", row[SchemaTableColumn.ColumnName]);
Assert.AreEqual(5, row[SchemaTableColumn.ColumnOrdinal]);
Assert.AreEqual(SFDataType.BOOLEAN, (SFDataType)row[SchemaTableColumn.ProviderType]);
Assert.AreEqual(true, row[SchemaTableColumn.AllowDBNull]);
}

conn.Close();
}
}
}
}
}
45 changes: 45 additions & 0 deletions Snowflake.Data/Client/SnowflakeDbDataReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,14 @@ public class SnowflakeDbDataReader : DbDataReader

private bool isClosed;

private readonly DataTable SchemaTable;

internal SnowflakeDbDataReader(SnowflakeDbCommand command, SFBaseResultSet resultSet)
{
this.dbCommand = command;
this.resultSet = resultSet;
this.isClosed = false;
this.SchemaTable = PopuldateSchemaTable(resultSet);
}
public override object this[string name]
{
Expand Down Expand Up @@ -81,6 +84,48 @@ public override bool IsClosed

public override int RecordsAffected => resultSet.CalculateUpdateCount();

public override DataTable GetSchemaTable()
{
return this.SchemaTable;
}

private DataTable PopuldateSchemaTable(SFBaseResultSet resultSet)
{
var table = new DataTable("SchemaTable");

table.Columns.Add(SchemaTableColumn.ColumnName, typeof(string));
table.Columns.Add(SchemaTableColumn.ColumnOrdinal, typeof(int));
table.Columns.Add(SchemaTableColumn.ColumnSize, typeof(int));
table.Columns.Add(SchemaTableColumn.NumericPrecision, typeof(int));
table.Columns.Add(SchemaTableColumn.NumericScale, typeof(int));
table.Columns.Add(SchemaTableColumn.DataType, typeof(Type));
table.Columns.Add(SchemaTableColumn.AllowDBNull, typeof(bool));
table.Columns.Add(SchemaTableColumn.ProviderType, typeof(SFDataType));

int columnOrdinal = 0;
SFResultSetMetaData sfResultSetMetaData = resultSet.sfResultSetMetaData;
foreach (ExecResponseRowType rowType in sfResultSetMetaData.rowTypes)
{
var row = table.NewRow();

row[SchemaTableColumn.ColumnName] = rowType.name;
row[SchemaTableColumn.ColumnOrdinal] = columnOrdinal;
row[SchemaTableColumn.ColumnSize] = (int)rowType.length;
row[SchemaTableColumn.NumericPrecision] = (int)rowType.precision;
row[SchemaTableColumn.NumericScale] = (int)rowType.scale;
row[SchemaTableColumn.AllowDBNull] = rowType.nullable;

Tuple<SFDataType, Type> types = sfResultSetMetaData.GetTypesByIndex(columnOrdinal);
row[SchemaTableColumn.ProviderType] = types.Item1;
row[SchemaTableColumn.DataType] = types.Item2;

table.Rows.Add(row);
columnOrdinal++;
}

return table;
}

public override bool GetBoolean(int ordinal)
{
return resultSet.GetValue<bool>(ordinal);
Expand Down
3 changes: 2 additions & 1 deletion Snowflake.Data/Core/SFResultSetMetaData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class SFResultSetMetaData

internal readonly string timestampeTZOutputFormat;

List<ExecResponseRowType> rowTypes;
internal List<ExecResponseRowType> rowTypes;

internal readonly SFStatementType statementType;

Expand Down Expand Up @@ -127,6 +127,7 @@ private Type GetNativeTypeForColumn(SFDataType sfType, ExecResponseRowType col)
case SFDataType.TEXT:
case SFDataType.VARIANT:
case SFDataType.OBJECT:
case SFDataType.ARRAY:
return typeof(string);
case SFDataType.DATE:
case SFDataType.TIME:
Expand Down

0 comments on commit 8bc422e

Please sign in to comment.