PostgresDBTraits implemented; some real things are getting done inside the penartur.Patcher.Web (no actual DB modification yet)

main
Inga 🏳‍🌈 13 years ago
parent 5fa9ff5f4c
commit bea5011afc
  1. 2
      Builder/IISMainHandler/build.txt
  2. 24
      FLocal.Patcher.Common/PatcherConfiguration.cs
  3. 2
      FLocal.Patcher.IISHandler/MainHandler.cs
  4. 4
      Patcher.Web/CheckParams.cs
  5. 40
      Patcher.Web/InteractiveResponseStream.cs
  6. 29
      Patcher.Web/MainHandler.cs
  7. 2
      Patcher.Web/Patcher.Web.csproj
  8. 34
      Patcher.Web/UpdateParams.cs
  9. 38
      Patcher/Checker.cs
  10. 2
      Patcher/DB/DBTraitsFactory.cs
  11. 222
      Patcher/DB/PostgresDBTraits.cs
  12. 12
      Patcher/DB/SQLQueryManager.cs
  13. 5
      Patcher/Patcher.csproj

@ -13,22 +13,30 @@ namespace FLocal.Patcher.Common {
private readonly string _DbDriverName; private readonly string _DbDriverName;
public string DbDriverName { public string DbDriverName {
get { throw new NotImplementedException(); } get {
return this._DbDriverName;
}
} }
private readonly string _GuestConnectionString; private readonly string _GuestConnectionString;
public string GuestConnectionString { public string GuestConnectionString {
get { throw new NotImplementedException(); } get {
return this._GuestConnectionString;
}
} }
private readonly string _PatchesTable; private readonly string _PatchesTable;
public string PatchesTable { public string PatchesTable {
get { throw new NotImplementedException(); } get {
return this._PatchesTable;
}
} }
private readonly string _EnvironmentName; private readonly string _EnvironmentName;
public string EnvironmentName { public string EnvironmentName {
get { throw new NotImplementedException(); } get {
return this._EnvironmentName;
}
} }
public IEnumerable<PatchId> getPatchesList() { public IEnumerable<PatchId> getPatchesList() {
@ -40,10 +48,10 @@ namespace FLocal.Patcher.Common {
} }
protected PatcherConfiguration(NameValueCollection data) : base() { protected PatcherConfiguration(NameValueCollection data) : base() {
this._DbDriverName = data["Patcher.DbDriver"]; this._DbDriverName = data["Patcher.DbDriver"].ToString();
this._EnvironmentName = data["Patcher.EnvironmentName"]; this._EnvironmentName = data["Patcher.EnvironmentName"].ToString();
this._GuestConnectionString = data["ConnectionString"]; this._GuestConnectionString = data["ConnectionString"].ToString();
this._PatchesTable = data["Patcher.PatchesTable"]; this._PatchesTable = data["Patcher.PatchesTable"].ToString();
} }
public static void Init(NameValueCollection data) { public static void Init(NameValueCollection data) {

@ -15,7 +15,7 @@ namespace FLocal.Patcher.IISHandler {
} }
protected override string GetAdminConnectionString(HttpContext context) { protected override string GetAdminConnectionString(HttpContext context) {
throw new NotImplementedException(); return System.Configuration.ConfigurationManager.AppSettings["Patcher.AdminConnectionString"].Replace("{password}", context.Request.Form["data"]);
} }
} }

@ -7,7 +7,7 @@ using Patcher.Data.Patch;
namespace Patcher.Web { namespace Patcher.Web {
class CheckParams : ICheckParams { class CheckParams : ICheckParams {
private readonly IPatcherConfiguration configuration; protected readonly IPatcherConfiguration configuration;
public CheckParams(IPatcherConfiguration configuration) { public CheckParams(IPatcherConfiguration configuration) {
this.configuration = configuration; this.configuration = configuration;
@ -19,7 +19,7 @@ namespace Patcher.Web {
} }
} }
public string ConnectionString { public virtual string ConnectionString {
get { get {
return this.configuration.GuestConnectionString; return this.configuration.GuestConnectionString;
} }

@ -0,0 +1,40 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Web.Core;
using System.Web;
namespace Patcher.Web {
class InteractiveResponseStream : IInteractiveConsole {
private readonly HttpContext context;
public void Report(string message) {
this.context.Response.Output.WriteLine(message);
}
public void Report(string format, params object[] data) {
this.context.Response.Output.WriteLine(format, data);
}
public bool IsInteractive {
get {
return false;
}
}
public bool Ask(string question) {
throw new NotImplementedException();
}
public void WaitForUserAction() {
throw new NotImplementedException();
}
public InteractiveResponseStream(HttpContext context) {
this.context = context;
}
}
}

@ -18,16 +18,35 @@ namespace Patcher.Web {
} }
private void Install(HttpContext context) { private void Install(HttpContext context) {
var writer = context.Response.Output; context.Response.ContentType = "text/plain";
writer.WriteLine("<p>Installing...</p>"); context.Response.Output.WriteLine("Installing...");
System.Threading.Thread.Sleep(TimeSpan.FromSeconds(2)); System.Threading.Thread.Sleep(TimeSpan.FromSeconds(2));
this.patcherInfo.AreNewPatchesInstalled = true; var updater = new Updater(new UpdateParams(this.patcherInfo.configuration, this.GetAdminConnectionString(context)), new InteractiveResponseStream(context));
writer.WriteLine("<p>Installed</p>"); int resultCode = updater.ApplyAll();
if(resultCode == 0) {
this.patcherInfo.AreNewPatchesInstalled = true;
context.Response.Output.WriteLine("Installed");
} else {
context.Response.Output.WriteLine("Failed to install: error code {0}", resultCode);
}
} }
private void ShowInfo(HttpContext context) { private void ShowInfo(HttpContext context) {
var writer = context.Response.Output; var writer = context.Response.Output;
writer.WriteLine("<form method=\"POST\"><input type=\"hidden\" name=\"install\" value=\"install\"/><input type=\"submit\" value=\"Install!\"/></form>"); var checker = new Checker(new CheckParams(this.patcherInfo.configuration));
int totalPatches = 0;
foreach(var patchId in checker.GetPatchesToInstall()) {
writer.WriteLine("<p>{0}: \"{1}\"</p>", patchId.version, patchId.name);
totalPatches++;
}
writer.WriteLine("<p>Total patches: {0}", totalPatches);
if(totalPatches > 0) {
writer.WriteLine("<form method=\"POST\">");
writer.WriteLine("<input type=\"text\" name=\"data\"/><br/>");
writer.WriteLine("<input type=\"hidden\" name=\"install\" value=\"install\"/>");
writer.WriteLine("<input type=\"submit\" value=\"Install!\"/>");
writer.WriteLine("</form>");
}
} }
public void ProcessRequest(HttpContext context) { public void ProcessRequest(HttpContext context) {

@ -47,10 +47,12 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="CheckParams.cs" /> <Compile Include="CheckParams.cs" />
<Compile Include="InteractiveResponseStream.cs" />
<Compile Include="MainHandler.cs" /> <Compile Include="MainHandler.cs" />
<Compile Include="IPatcherConfiguration.cs" /> <Compile Include="IPatcherConfiguration.cs" />
<Compile Include="PatcherInfo.cs" /> <Compile Include="PatcherInfo.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="UpdateParams.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Patcher\Patcher.csproj"> <ProjectReference Include="..\Patcher\Patcher.csproj">

@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using Patcher.Data.Patch;
namespace Patcher.Web {
class UpdateParams : CheckParams, IUpdateParams {
private readonly string AdminConnectionString;
public UpdateParams(IPatcherConfiguration configuration, string AdminConnectionString) : base(configuration) {
this.AdminConnectionString = AdminConnectionString;
}
public override string ConnectionString {
get {
return this.AdminConnectionString;
}
}
public string EnvironmentName {
get {
return configuration.EnvironmentName;
}
}
public Stream loadPatch(PatchId patchId) {
return configuration.loadPatch(patchId);
}
}
}

@ -25,30 +25,30 @@ namespace Patcher {
from patchId in this.checkParams.getPatchesList() from patchId in this.checkParams.getPatchesList()
orderby patchId ascending orderby patchId ascending
select patchId, select patchId,
from row in transaction.ExecuteReader( (
string.Format( from row in transaction.ExecuteReader(
"select {1}, {2} from {0} where {3} = {4}", string.Format(
transaction.EscapeName(this.checkParams.PatchesTable), "select {1}, {2} from {0} where {3} = {4}",
transaction.EscapeName("VERSION"), transaction.EscapeName(this.checkParams.PatchesTable),
transaction.EscapeName("NAME"), transaction.EscapeName("VERSION"),
transaction.EscapeName("STATUS"), transaction.EscapeName("NAME"),
transaction.MarkParam("pstatus") transaction.EscapeName("STATUS"),
), transaction.MarkParam("pstatus")
new Dictionary<string, object> { ),
{ "pstatus", STATUS_INSTALLED }, new Dictionary<string, object> {
} { "pstatus", STATUS_INSTALLED },
) }
let patch = new PatchId(int.Parse(row["VERSION"]), row["NAME"]) )
orderby patch ascending let patch = new PatchId(int.Parse(row["VERSION"]), row["NAME"])
select patch orderby patch ascending
select patch
).ToList()
); );
} }
} }
public bool IsNeedsPatching() { public bool IsNeedsPatching() {
System.Threading.Thread.Sleep(TimeSpan.FromSeconds(2)); return this.GetPatchesToInstall().Any();
return true;
//return this.GetPatchesToInstall().Any();
} }
} }

@ -12,6 +12,8 @@ namespace Patcher.DB {
return OracleDBTraits.instance; return OracleDBTraits.instance;
case "oracle-faketransactional": case "oracle-faketransactional":
return OracleFakeTransactionalDBTraits.instance; return OracleFakeTransactionalDBTraits.instance;
case "postgres":
return PostgresDBTraits.instance;
default: default:
throw new NotImplementedException(); throw new NotImplementedException();
} }

@ -0,0 +1,222 @@
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using Npgsql;
namespace Patcher.DB {
class PostgresDBTraits : IDBTraits {
public static readonly IDBTraits instance = new PostgresDBTraits();
protected PostgresDBTraits() {
}
private static readonly Regex ALPHANUMERIC = new Regex("^[a-zA-Z]\\w*$", RegexOptions.Compiled | RegexOptions.Singleline);
private static string _EscapeName(string name) {
if(!ALPHANUMERIC.IsMatch(name)) throw new ApplicationException("Name should contain only alphanumeric characters");
return string.Format("\"{0}\"", name);
}
string IDBTraits.EscapeName(string name) {
return _EscapeName(name);
}
DbConnection IDBTraits.CreateConnection(string connectionString) {
NpgsqlConnection connection = new NpgsqlConnection(connectionString);
connection.Open();
return connection;
}
string IDBTraits.MarkParam(string paramName) {
if(!ALPHANUMERIC.IsMatch(paramName)) throw new ApplicationException("Name should contain only alphanumeric characters");
return ":" + paramName;
}
string IDBTraits.ParamName(string paramName) {
if(!ALPHANUMERIC.IsMatch(paramName)) throw new ApplicationException("Name should contain only alphanumeric characters");
return paramName;
}
private static void AddParam(DbCommand command, string name, DbType type, object value) {
var param = command.CreateParameter();
param.ParameterName = name;
param.DbType = type;
param.Value = value;
command.Parameters.Add(param);
}
private static bool ParseBoolString(string value) {
switch(value.ToLower()) {
case "n":
return false;
case "y":
return true;
default:
throw new ApplicationException(string.Format("Unknown value {0}", value));
}
}
private static T CastResult<T>(object value) where T : class {
if(DBNull.Value.Equals(value)) {
return null;
} else {
return (T)value;
}
}
private static T? CastScalarResult<T>(object value) where T : struct {
if(DBNull.Value.Equals(value)) {
return null;
} else {
return (T)value;
}
}
private static readonly SQLQueryManager _SQLQueryManager = new SQLQueryManager(_EscapeName);
StoredProcedureBody IDBTraits.GetStoredProcedureBody(Func<DbCommand> commandCreator, StoredProcedureReference procedure) {
throw new NotImplementedException();
}
private static string FormatStoredProcedureHeader(StoredProcedureReference procedure) {
throw new NotImplementedException();
}
void IDBTraits.ReplaceStoredProcedureBody(Func<DbCommand> commandCreator, StoredProcedureReference procedure, StoredProcedureBody newBody) {
throw new NotImplementedException();
}
void IDBTraits.RemoveStoredProcedure(Func<DbCommand> commandCreator, StoredProcedureReference procedure) {
throw new NotImplementedException();
}
void IDBTraits.CreateView(Func<DbCommand> commandCreator, string viewName, string body) {
throw new NotImplementedException();
}
void IDBTraits.RemoveView(Func<DbCommand> commandCreator, string viewName) {
throw new NotImplementedException();
}
void IDBTraits.CreateStoredProcedure(Func<DbCommand> commandCreator, StoredProcedureReference procedure, StoredProcedureBody body) {
throw new NotImplementedException();
}
string IDBTraits.GetViewBody(Func<DbCommand> commandCreator, string name) {
throw new NotImplementedException();
}
ColumnOptions IDBTraits.GetColumnOptions(Func<DbCommand> commandCreator, ColumnReference column) {
throw new NotImplementedException();
}
void IDBTraits.RemoveColumn(Func<DbCommand> commandCreator, ColumnReference column) {
using(DbCommand command = commandCreator()) {
command.CommandText = _SQLQueryManager.RemoveColumn(column);
command.ExecuteNonQuery();
}
}
void IDBTraits.CreateColumn(Func<DbCommand> commandCreator, ColumnDescription description) {
using(DbCommand command = commandCreator()) {
command.CommandText = _SQLQueryManager.CreateColumn(description);
command.ExecuteNonQuery();
}
}
void IDBTraits.ModifyColumn(Func<DbCommand> commandCreator, ColumnDescription description) {
using(DbCommand command = commandCreator()) {
command.CommandText = _SQLQueryManager.ModifyColumnPostgresStyle(description);
Console.WriteLine();
Console.WriteLine(command.CommandText);
command.ExecuteNonQuery();
}
}
private static string GetStringRepresentation(ForeignKeyConstraint.ReferentialAction action) {
switch(action) {
case ForeignKeyConstraint.ReferentialAction.NoAction:
return "NO ACTION";
case ForeignKeyConstraint.ReferentialAction.Cascade:
return "CASCADE";
case ForeignKeyConstraint.ReferentialAction.SetNull:
return "SET NULL";
case ForeignKeyConstraint.ReferentialAction.SetDefault:
return "SET DEFAULT";
default:
throw new ApplicationException("Unknown referential action");
}
}
private void CheckConstraint(Func<DbCommand> commandCreator, ForeignKeyConstraint constraint) {
throw new NotImplementedException();
}
private void CheckConstraint(Func<DbCommand> commandCreator, UniqueConstraint constraint) {
throw new NotImplementedException();
}
private void CheckConstraint(Func<DbCommand> commandCreator, CheckConstraint constraint) {
throw new NotImplementedException();
}
private void CheckConstraint(Func<DbCommand> commandCreator, AbstractConstraint constraint) {
constraint.Accept(fkc => CheckConstraint(commandCreator, fkc), uc => CheckConstraint(commandCreator, uc), cc => CheckConstraint(commandCreator, cc));
}
public void RemoveConstraint(Func<DbCommand> commandCreator, AbstractConstraint constraint) {
CheckConstraint(commandCreator, constraint);
using(DbCommand command = commandCreator()) {
command.CommandText = _SQLQueryManager.DropConstraint(constraint);
Console.WriteLine();
Console.WriteLine(command.CommandText);
command.ExecuteNonQuery();
}
}
public void CreateConstraint(Func<DbCommand> commandCreator, AbstractConstraint constraint) {
using(DbCommand command = commandCreator()) {
command.CommandText = _SQLQueryManager.CreateConstraint(constraint);
Console.WriteLine();
Console.WriteLine(command.CommandText);
command.ExecuteNonQuery();
}
}
public void CreateTable(Func<DbCommand> commandCreator, TableDescription table) {
using(DbCommand command = commandCreator()) {
command.CommandText = _SQLQueryManager.CreateTable(table);
Console.WriteLine();
Console.WriteLine(command.CommandText);
command.ExecuteNonQuery();
}
}
private void CheckTable(Func<DbCommand> commandCreator, TableDescription table) {
throw new NotImplementedException();
}
void IDBTraits.RemoveTable(Func<DbCommand> commandCreator, TableDescription table) {
this.CheckTable(commandCreator, table);
using(DbCommand command = commandCreator()) {
command.CommandText = _SQLQueryManager.DropTable(table.table);
Console.WriteLine();
Console.WriteLine(command.CommandText);
command.ExecuteNonQuery();
}
}
bool IDBTraits.IsDDLTransactional {
get { return true; }
}
}
}

@ -253,6 +253,10 @@ namespace Patcher.DB
); );
} }
private string _ModifyColumnDefinitionPostgresStyle(ColumnDescription description) {
throw new NotImplementedException();
}
private string _TableElementList(TableDescription table) { private string _TableElementList(TableDescription table) {
return string.Format( return string.Format(
"({0})", "({0})",
@ -292,12 +296,16 @@ namespace Patcher.DB
{ {
return _AlterTableStatement(column.tableName, _DropColumnDefinition(column)); return _AlterTableStatement(column.tableName, _DropColumnDefinition(column));
} }
public string ModifyColumnOracleStyle(ColumnDescription description) public string ModifyColumnOracleStyle(ColumnDescription description)
{ {
return _AlterTableStatement(description.column.tableName, _ModifyColumnDefinitionOracleStyle(description)); return _AlterTableStatement(description.column.tableName, _ModifyColumnDefinitionOracleStyle(description));
} }
public string ModifyColumnPostgresStyle(ColumnDescription description) {
return _AlterTableStatement(description.column.tableName, _ModifyColumnDefinitionPostgresStyle(description));
}
public string CreateConstraint(AbstractConstraint constraint) public string CreateConstraint(AbstractConstraint constraint)
{ {
return _AlterTableStatement(constraint.table, _AddTableConstraintDefinition(constraint)); return _AlterTableStatement(constraint.table, _AddTableConstraintDefinition(constraint));

@ -31,6 +31,10 @@
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="Npgsql, Version=2.0.8.0, Culture=neutral, PublicKeyToken=5d8b90d52f46fda7, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\ThirdParty\Npgsql\Npgsql.dll</HintPath>
</Reference>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Core"> <Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework> <RequiredTargetFramework>3.5</RequiredTargetFramework>
@ -80,6 +84,7 @@
<Compile Include="DB\IDBTraits.cs" /> <Compile Include="DB\IDBTraits.cs" />
<Compile Include="DB\OracleDBTraits.cs" /> <Compile Include="DB\OracleDBTraits.cs" />
<Compile Include="DB\OracleFakeTransactionalDBTraits.cs" /> <Compile Include="DB\OracleFakeTransactionalDBTraits.cs" />
<Compile Include="DB\PostgresDBTraits.cs" />
<Compile Include="DB\SQLQueryManager.cs" /> <Compile Include="DB\SQLQueryManager.cs" />
<Compile Include="DB\StoredProcedureBody.cs" /> <Compile Include="DB\StoredProcedureBody.cs" />
<Compile Include="DB\StoredProcedureReference.cs" /> <Compile Include="DB\StoredProcedureReference.cs" />

Loading…
Cancel
Save