An alternative to UBB.threads
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
FLocal/Patcher/DB/Transaction.cs

275 lines
7.1 KiB

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.IO;
using System.Linq;
using System.Text;
namespace Patcher.DB
{
class Transaction : IDisposable
{
private DbConnection connection;
private DbTransaction transaction;
private readonly IDBTraits traits;
private bool isClosed;
public Transaction(IDBTraits traits, string connectionString)
{
this.traits = traits;
DbConnection _connection = null;
DbTransaction _transaction = null;
try
{
_connection = traits.CreateConnection(connectionString);
_transaction = _connection.BeginTransaction(IsolationLevel.Serializable);
this.connection = _connection;
this.transaction = _transaction;
} catch(Exception)
{
if(_transaction != null)
{
_transaction.Dispose();
this.transaction = null;
}
if(_connection != null)
{
_connection.Dispose();
this.connection = null;
}
throw;
}
}
private void CheckOpened()
{
if(this.isClosed) throw new ApplicationException("Connection is already closed");
}
private DbCommand CreateTextCommand()
{
this.CheckOpened();
DbCommand command = this.connection.CreateCommand();
try
{
command.Transaction = this.transaction;
command.CommandType = CommandType.Text;
return command;
} catch(Exception)
{
command.Dispose();
throw;
}
}
public string MarkParam(string paramName)
{
return this.traits.MarkParam(paramName);
}
public string EscapeName(string name)
{
return this.traits.EscapeName(name);
}
public void Commit()
{
this.CheckOpened();
this.isClosed = true;
this.transaction.Commit();
this.transaction = null;
this.connection.Close();
this.connection = null;
}
public void Dispose()
{
this.isClosed = true;
if(this.transaction != null)
{
try
{
this.transaction.Rollback();
this.transaction.Dispose();
} catch(SystemException)
{
throw;
} catch(Exception e)
{
Console.WriteLine(e.ToString());
}
this.transaction = null;
}
if(this.connection != null)
{
try
{
if(this.connection.State == ConnectionState.Open)
{
this.connection.Close();
}
this.connection.Dispose();
} catch(SystemException)
{
throw;
} catch(Exception e) //Dispose should not throw exceptions
{
Console.WriteLine(e.ToString());
}
this.connection = null;
}
}
private static DbType DetectParameterType(object value)
{
if(value is string)
{
return DbType.String;
}
if((value is decimal) || (value is int) || (value is long) || (value is short))
{
return DbType.Decimal;
}
if((value is float) || (value is double))
{
return DbType.Double;
}
if(value is DateTime)
{
return DbType.DateTime;
}
return DbType.Object;
}
private DbCommand CreateCommand(string commandText, Dictionary<string, object> parameters)
{
DbCommand command = this.CreateTextCommand();
command.CommandText = commandText;
foreach(var kvp in parameters)
{
DbParameter parameter = command.CreateParameter();
parameter.DbType = DetectParameterType(kvp.Value);
parameter.ParameterName = kvp.Key;
parameter.Value = kvp.Value;
command.Parameters.Add(parameter);
}
return command;
}
public IEnumerable<Dictionary<string, string>> ExecuteReader(string commandText, Dictionary<string, object> parameters)
{
using(DbCommand command = this.CreateCommand(commandText, parameters))
{
Logger.instance.Log(commandText);
using(DbDataReader reader = command.ExecuteReader())
{
//Console.WriteLine(String.Join(";", (from i in Enumerable.Range(0, reader.FieldCount) select i + ":" + reader.GetName(i)).ToArray()));
while(reader.Read())
{
yield return (from i in Enumerable.Range(0, reader.FieldCount) select new KeyValuePair<string, string>(reader.GetName(i), reader.GetValue(i).ToString())).ToDictionary();
}
}
}
}
public IEnumerable<Dictionary<string, string>> ExecuteReader(string commandText)
{
return this.ExecuteReader(commandText, new Dictionary<string, object>());
}
public int ExecuteNonQuery(string commandText, Dictionary<string, object> parameters)
{
using(DbCommand command = this.CreateCommand(commandText, parameters))
{
Logger.instance.Log(commandText);
return command.ExecuteNonQuery();
}
}
public int ExecuteNonQuery(string commandText)
{
return this.ExecuteNonQuery(commandText, new Dictionary<string, object>());
}
//SELECT LINE, TEXT FROM ALL_SOURCE WHERE TYPE = 'PACKAGE BODY' AND NAME = '' AND OWNER = (SELECT USER FROM DUAL) for update
public StoredProcedureBody GetStoredProcedureBody(StoredProcedureReference procedure)
{
return this.traits.GetStoredProcedureBody(this.CreateTextCommand, procedure);
}
public void ReplaceStoredProcedureBody(StoredProcedureReference procedure, StoredProcedureBody newBody)
{
this.traits.ReplaceStoredProcedureBody(this.CreateTextCommand, procedure, newBody);
}
public void RemoveStoredProcedure(StoredProcedureReference procedure)
{
this.traits.RemoveStoredProcedure(this.CreateTextCommand, procedure);
}
public void CreateStoredProcedure(StoredProcedureReference procedure, StoredProcedureBody body)
{
this.traits.CreateStoredProcedure(this.CreateTextCommand, procedure, body);
}
public ColumnOptions GetColumnOptions(ColumnReference column)
{
return this.traits.GetColumnOptions(this.CreateTextCommand, column);
}
public void RemoveColumn(ColumnReference column)
{
this.traits.RemoveColumn(this.CreateTextCommand, column);
}
public void CreateColumn(ColumnDescription description)
{
this.traits.CreateColumn(this.CreateTextCommand, description);
}
public void ModifyColumn(ColumnDescription description)
{
this.traits.ModifyColumn(this.CreateTextCommand, description);
}
public void CreateConstraint(AbstractConstraint constraint)
{
this.traits.CreateConstraint(this.CreateTextCommand, constraint);
}
public void RemoveConstraint(AbstractConstraint constraint)
{
this.traits.RemoveConstraint(this.CreateTextCommand, constraint);
}
public void CreateTable(TableDescription table)
{
this.traits.CreateTable(this.CreateTextCommand, table);
}
public void RemoveTable(TableDescription table)
{
this.traits.RemoveTable(this.CreateTextCommand, table);
}
public string GetViewBody(string viewName)
{
return this.traits.GetViewBody(this.CreateTextCommand, viewName);
}
public void CreateView(string viewName, string body)
{
this.traits.CreateView(this.CreateTextCommand, viewName, body);
}
public void RemoveView(string viewName)
{
this.traits.RemoveView(this.CreateTextCommand, viewName);
}
}
}