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.
273 lines
7.0 KiB
273 lines
7.0 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))
|
|
{
|
|
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))
|
|
{
|
|
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);
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|