using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Common;
using ScrewTurn.Wiki.PluginFramework;
namespace ScrewTurn.Wiki.Plugins.SqlCommon {
///
/// Implements a base class for all SQL-based classes.
///
public abstract class SqlClassBase {
#region Utility Methods
///
/// Gets a value indicating whether a column contains nonexistent or missing value.
///
/// The .
/// The name of the column.
/// true if the column contains a nonexistent or missing value, false otherwise.
protected bool IsDBNull(DbDataReader reader, string column) {
return reader.IsDBNull(reader.GetOrdinal(column));
}
///
/// Gets the value of a nullable column.
///
/// The return type.
/// The .
/// The name of the column.
/// The default value to return when the column contains a null value.
/// The value.
protected T GetNullableColumn(DbDataReader reader, string column, T defaultValue) {
if(IsDBNull(reader, column)) return defaultValue;
else return (T)reader[column];
}
///
/// Reads all the contents of a binary column.
///
/// The .
/// The name of the column.
/// The max size, in bytes, to read. If exceeded, null is returned.
/// The read bytes, or null.
/// This method buffers the data in memory; avoid reading data bigger than a few megabytes.
protected byte[] GetBinaryColumn(DbDataReader reader, string column, int maxSize) {
// 128 KB read buffer
byte[] buffer = new byte[131072];
byte[] tempResult = new byte[maxSize];
int columnOrdinal = reader.GetOrdinal(column);
long read = 0;
long totalRead = 0;
do {
read = reader.GetBytes(columnOrdinal, totalRead, buffer, 0, buffer.Length);
if(totalRead + read > maxSize) return null;
if(read > 0) {
Buffer.BlockCopy(buffer, 0, tempResult, (int)totalRead, (int)read);
}
totalRead += read;
} while(read > 0);
// Copy tempBuffer in final array
buffer = null;
byte[] result = new byte[totalRead];
Buffer.BlockCopy(tempResult, 0, result, 0, result.Length);
return result;
}
///
/// Copies all the contents of a binary column into a .
///
/// The .
/// The name of the column.
/// The destination .
protected int ReadBinaryColumn(DbDataReader reader, string column, System.IO.Stream stream) {
// 128 KB read buffer
byte[] buffer = new byte[131072];
int columnOrdinal = reader.GetOrdinal(column);
int read = 0;
int totalRead = 0;
do {
read = (int)reader.GetBytes(columnOrdinal, totalRead, buffer, 0, buffer.Length);
if(read > 0) {
stream.Write(buffer, 0, read);
}
totalRead += read;
} while(read > 0);
return totalRead;
}
///
/// Logs an exception.
///
/// The exception.
protected abstract void LogException(Exception ex);
///
/// Executes a scalar command, then closes the connection.
///
/// The return type.
/// The command to execute.
/// The default value of the return value, to use when the command fails.
/// The result.
/// The connection is closed after the execution.
protected T ExecuteScalar(DbCommand command, T defaultValue) {
return ExecuteScalar(command, defaultValue, true);
}
///
/// Executes a scalar command, then closes the connection.
///
/// The return type.
/// The command to execute.
/// The default value of the return value, to use when the command fails.
/// A value indicating whether to close the connection after execution.
/// The result.
protected T ExecuteScalar(DbCommand command, T defaultValue, bool close) {
object temp = null;
try {
temp = command.ExecuteScalar();
}
catch(DbException dbex) {
LogException(dbex);
}
finally {
if(close) {
CloseConnection(command.Connection);
}
}
if(temp != null) {
return (T)temp;
}
else return defaultValue;
}
///
/// Executes a non-query command, then closes the connection.
///
/// The command to execute.
/// The rows affected (-1 if the command failed).
/// The connection is closed after the execution.
protected int ExecuteNonQuery(DbCommand command) {
return ExecuteNonQuery(command, true);
}
///
/// Executes a non-query command, then closes the connection if requested.
///
/// The command to execute.
/// A value indicating whether to close the connection after execution.
/// The rows affected (-1 if the command failed).
protected int ExecuteNonQuery(DbCommand command, bool close) {
return ExecuteNonQuery(command, close, true);
}
///
/// Executes a non-query command, then closes the connection if requested.
///
/// The command to execute.
/// A value indicating whether to close the connection after execution.
/// A value indicating whether to log any error.
/// The rows affected (-1 if the command failed).
protected int ExecuteNonQuery(DbCommand command, bool close, bool logError) {
int rows = -1;
try {
rows = command.ExecuteNonQuery();
}
catch(DbException dbex) {
if(logError) LogException(dbex);
}
finally {
if(close) {
CloseConnection(command.Connection);
}
}
return rows;
}
///
/// Executes a reader command, leaving the connection open.
///
/// The command to execute.
/// A value indicating whether to close the connection on error.
/// The data reader, or null if the command fails.
protected DbDataReader ExecuteReader(DbCommand command, bool closeOnError) {
DbDataReader reader = null;
try {
reader = command.ExecuteReader();
}
catch(DbException dbex) {
LogException(dbex);
if(closeOnError) CloseConnection(command.Connection);
}
return reader;
}
///
/// Executes a reader command, leaving the connection open.
///
/// The command to execute.
/// The data reader, or null if the command fails.
/// If the command fails, the connection is closed.
protected DbDataReader ExecuteReader(DbCommand command) {
return ExecuteReader(command, true);
}
///
/// Closes a connection, swallowing all exceptions.
///
/// The connection to close.
protected void CloseConnection(DbConnection connection) {
try {
connection.Close();
}
catch { }
}
///
/// Closes a reader, a command and the associated connection.
///
/// The command.
/// The reader.
protected void CloseReader(DbCommand command, DbDataReader reader) {
try {
reader.Close();
}
catch { }
CloseConnection(command.Connection);
}
///
/// Closes a reader.
///
/// The reader.
protected void CloseReader(DbDataReader reader) {
try {
reader.Close();
}
catch { }
}
///
/// Begins a transaction.
///
/// The connection.
/// The transaction.
protected DbTransaction BeginTransaction(DbConnection connection) {
return connection.BeginTransaction();
}
///
/// Commits a transaction.
///
/// The transaction.
protected void CommitTransaction(DbTransaction transaction) {
// Commit sets transaction.Connection to null
DbConnection connection = transaction.Connection;
transaction.Commit();
transaction.Dispose();
CloseConnection(connection);
}
///
/// Rolls back a transaction.
///
/// The transaction.
protected void RollbackTransaction(DbTransaction transaction) {
// Rollback sets transaction.Connection to null
DbConnection connection = transaction.Connection;
try {
transaction.Rollback();
}
catch { }
transaction.Dispose();
CloseConnection(connection);
}
#endregion
}
}