?? sqlitedatareader.cs
字號:
}
}
// Determine IsUnique properly, which is a pain in the butt!
if (wantUniqueInfo)
{
if ((string)row[SchemaTableOptionalColumn.BaseCatalogName] != strCatalog
|| (string)row[SchemaTableColumn.BaseTableName] != strTable)
{
strCatalog = (string)row[SchemaTableOptionalColumn.BaseCatalogName];
strTable = (string)row[SchemaTableColumn.BaseTableName];
tblIndexes = _command.Connection.GetSchema("Indexes", new string[] {
(string)row[SchemaTableOptionalColumn.BaseCatalogName],
null,
(string)row[SchemaTableColumn.BaseTableName],
null });
}
foreach (DataRow rowIndexes in tblIndexes.Rows)
{
tblIndexColumns = _command.Connection.GetSchema("IndexColumns", new string[] {
(string)row[SchemaTableOptionalColumn.BaseCatalogName],
null,
(string)row[SchemaTableColumn.BaseTableName],
(string)rowIndexes["INDEX_NAME"],
null
});
foreach (DataRow rowColumnIndex in tblIndexColumns.Rows)
{
if (String.Compare((string)rowColumnIndex["COLUMN_NAME"], strColumn, true, CultureInfo.InvariantCulture) == 0)
{
if (tblIndexColumns.Rows.Count == 1) row[SchemaTableColumn.IsUnique] = rowIndexes["UNIQUE"];
break;
}
}
}
}
}
if (String.IsNullOrEmpty(dataType))
{
TypeAffinity affin;
dataType = _activeStatement._sql.ColumnType(_activeStatement, n, out affin);
}
if (String.IsNullOrEmpty(dataType) == false)
row["DataTypeName"] = dataType;
tbl.Rows.Add(row);
}
tbl.AcceptChanges();
tbl.EndLoadData();
return tbl;
}
/// <summary>
/// Retrieves the column as a string
/// </summary>
/// <param name="i">The index of the column to retrieve</param>
/// <returns>string</returns>
public override string GetString(int i)
{
VerifyType(i, DbType.String);
return _activeStatement._sql.GetText(_activeStatement, i);
}
/// <summary>
/// Retrieves the column as an object corresponding to the underlying datatype of the column
/// </summary>
/// <param name="i">The index of the column to retrieve</param>
/// <returns>object</returns>
public override object GetValue(int i)
{
CheckClosed();
SQLiteType typ = GetSQLiteType(i);
typ.Affinity = _activeStatement._sql.ColumnAffinity(_activeStatement, i);
return _activeStatement._sql.GetValue(_activeStatement, i, ref typ);
}
/// <summary>
/// Retreives the values of multiple columns, up to the size of the supplied array
/// </summary>
/// <param name="values">The array to fill with values from the columns in the current resultset</param>
/// <returns>The number of columns retrieved</returns>
public override int GetValues(object[] values)
{
CheckClosed();
SQLiteType typ;
int nMax = _fieldCount;
if (values.Length < nMax) nMax = values.Length;
for (int n = 0; n < nMax; n++)
{
typ = GetSQLiteType(n);
typ.Affinity = _activeStatement._sql.ColumnAffinity(_activeStatement, n);
values[n] = _activeStatement._sql.GetValue(_activeStatement, n, ref typ);
}
return nMax;
}
/// <summary>
/// Returns True if the resultset has rows that can be fetched
/// </summary>
public override bool HasRows
{
get
{
CheckClosed();
return (_readingState != 1);
}
}
/// <summary>
/// Returns True if the data reader is closed
/// </summary>
public override bool IsClosed
{
get { return (_command == null); }
}
/// <summary>
/// Returns True if the specified column is null
/// </summary>
/// <param name="i">The index of the column to retrieve</param>
/// <returns>True or False</returns>
public override bool IsDBNull(int i)
{
CheckClosed();
return _activeStatement._sql.IsNull(_activeStatement, i);
}
/// <summary>
/// Moves to the next resultset in multiple row-returning SQL command.
/// </summary>
/// <returns>True if the command was successful and a new resultset is available, False otherwise.</returns>
public override bool NextResult()
{
CheckClosed();
SQLiteStatement stmt = null;
int fieldCount;
while (true)
{
if (_activeStatement != null && stmt == null)
{
// Reset the previously-executed statement
_activeStatement._sql.Reset(_activeStatement);
// If we're only supposed to return a single rowset, step through all remaining statements once until
// they are all done and return false to indicate no more resultsets exist.
if ((_commandBehavior & CommandBehavior.SingleResult) != 0)
{
for (; ; )
{
stmt = _command.GetStatement(_activeStatementIndex + 1);
if (stmt == null) break;
_activeStatementIndex++;
stmt._sql.Step(stmt);
if (stmt._sql.ColumnCount(stmt) == 0)
{
if (_rowsAffected == -1) _rowsAffected = 0;
_rowsAffected += stmt._sql.Changes;
}
stmt._sql.Reset(stmt); // Gotta reset after every step to release any locks and such!
}
return false;
}
}
// Get the next statement to execute
stmt = _command.GetStatement(_activeStatementIndex + 1);
// If we've reached the end of the statements, return false, no more resultsets
if (stmt == null)
return false;
// If we were on a current resultset, set the state to "done reading" for it
if (_readingState < 1)
_readingState = 1;
_activeStatementIndex++;
fieldCount = stmt._sql.ColumnCount(stmt);
// If the statement is not a select statement or we're not retrieving schema only, then perform the initial step
if ((_commandBehavior & CommandBehavior.SchemaOnly) == 0 || fieldCount == 0)
{
if (stmt._sql.Step(stmt))
{
_readingState = -1;
}
else if (fieldCount == 0) // No rows returned, if fieldCount is zero, skip to the next statement
{
if (_rowsAffected == -1) _rowsAffected = 0;
_rowsAffected += stmt._sql.Changes;
stmt._sql.Reset(stmt);
continue; // Skip this command and move to the next, it was not a row-returning resultset
}
else // No rows, fieldCount is non-zero so stop here
{
_readingState = 1; // This command returned columns but no rows, so return true, but HasRows = false and Read() returns false
}
}
// Ahh, we found a row-returning resultset eligible to be returned!
_activeStatement = stmt;
_fieldCount = fieldCount;
_fieldTypeArray = null;
return true;
}
}
/// <summary>
/// Retrieves the SQLiteType for a given column, and caches it to avoid repetetive interop calls.
/// </summary>
/// <param name="i">The index of the column to retrieve</param>
/// <returns>A SQLiteType structure</returns>
private SQLiteType GetSQLiteType(int i)
{
if (_fieldTypeArray == null) _fieldTypeArray = new SQLiteType[_fieldCount];
if (_fieldTypeArray[i].Affinity == TypeAffinity.Uninitialized || _fieldTypeArray[i].Affinity == TypeAffinity.Null)
_fieldTypeArray[i].Type = SQLiteConvert.TypeNameToDbType(_activeStatement._sql.ColumnType(_activeStatement, i, out _fieldTypeArray[i].Affinity));
return _fieldTypeArray[i];
}
/// <summary>
/// Reads the next row from the resultset
/// </summary>
/// <returns>True if a new row was successfully loaded and is ready for processing</returns>
public override bool Read()
{
CheckClosed();
if (_readingState == -1) // First step was already done at the NextResult() level, so don't step again, just return true.
{
_readingState = 0;
return true;
}
else if (_readingState == 0) // Actively reading rows
{
if (_activeStatement._sql.Step(_activeStatement) == true)
return true;
_readingState = 1; // Finished reading rows
}
return false;
}
/// <summary>
/// Retrieve the count of records affected by an update/insert command. Only valid once the data reader is closed!
/// </summary>
public override int RecordsAffected
{
get { return _rowsAffected; }
}
/// <summary>
/// Indexer to retrieve data from a column given its name
/// </summary>
/// <param name="name">The name of the column to retrieve data for</param>
/// <returns>The value contained in the column</returns>
public override object this[string name]
{
get { return GetValue(GetOrdinal(name)); }
}
/// <summary>
/// Indexer to retrieve data from a column given its i
/// </summary>
/// <param name="i">The index of the column to retrieve</param>
/// <returns>The value contained in the column</returns>
public override object this[int i]
{
get { return GetValue(i); }
}
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -