From f330e5a73a518ad978e3f56e9851e33831815a04 Mon Sep 17 00:00:00 2001 From: inga-lovinde <52715130+inga-lovinde@users.noreply.github.com> Date: Mon, 7 Jun 2010 18:25:37 +0000 Subject: [PATCH] (***UNTESTED***) Implemented SqlDataObject; implemented Category and Board dataobjects; fixed some bugs in registry and abstractdataobject --- Common/Common.csproj | 3 + Common/Config.cs | 8 +++ Common/SqlObject.cs | 95 +++++++++++++++++++++++++ Common/dataobjects/Board.cs | 62 ++++++++++++++++ Common/dataobjects/Category.cs | 30 ++++++++ Core/Config.cs | 5 +- Core/DataObject.cs | 10 ++- Core/Registry.cs | 5 +- IISMainHandler/handlers/DebugHandler.cs | 14 ++++ 9 files changed, 227 insertions(+), 5 deletions(-) create mode 100644 Common/SqlObject.cs create mode 100644 Common/dataobjects/Board.cs create mode 100644 Common/dataobjects/Category.cs diff --git a/Common/Common.csproj b/Common/Common.csproj index af20f39..9d4be41 100644 --- a/Common/Common.csproj +++ b/Common/Common.csproj @@ -46,7 +46,10 @@ + + + diff --git a/Common/Config.cs b/Common/Config.cs index e7afc60..9e64226 100644 --- a/Common/Config.cs +++ b/Common/Config.cs @@ -10,8 +10,11 @@ namespace FLocal.Common { public readonly string InitTime; + public readonly Core.DB.IDBConnection mainConnection; + protected Config(NameValueCollection data) : base(data) { this.InitTime = DateTime.Now.ToLongTimeString(); + this.mainConnection = new MySQLConnector.Connection(data["connectionString"]); } public static void Init(NameValueCollection data) { @@ -22,6 +25,11 @@ namespace FLocal.Common { doReInit(() => new Config(data)); } + public override void Dispose() { + this.mainConnection.Dispose(); + base.Dispose(); + } + } } diff --git a/Common/SqlObject.cs b/Common/SqlObject.cs new file mode 100644 index 0000000..4cdea91 --- /dev/null +++ b/Common/SqlObject.cs @@ -0,0 +1,95 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using FLocal.Core; +using FLocal.Core.DB; + +namespace FLocal.Common { + abstract public class SqlObject : Core.DataObject where T : SqlObject, new() { + + protected SqlObject() : base() { + } + + abstract protected ITableSpec table { + get; + } + + private bool isLoaded = false; + + private object lockFiller = new object(); + private object lockInitializer = new object(); + + abstract protected void doFromHash(Dictionary data); + + protected void fromHash(Dictionary data) { + lock(this.lockFiller) { + if(data[this.table.idName] != this.id.ToString()) { + throw new CriticalException("Id mismatch"); + } + this.doFromHash(data); + } + } + + private void doLoad() { + this.fromHash(Config.instance.mainConnection.LoadById(this.table, this.id.ToString())); + } + + protected void Load() { + lock(this.lockInitializer) { + if(this.isLoaded) throw new CriticalException("already initialized"); + this.doLoad(); + this.isLoaded = true; + } + } + + protected void LoadIfNotLoaded() { + lock(this.lockInitializer) { + if(!this.isLoaded) { + this.doLoad(); + this.isLoaded = true; + } + } + } + + public void ReLoad() { + this.doLoad(); + } + + protected override void AfterCreate(bool forLoadingFromHash) { + base.AfterCreate(forLoadingFromHash); + if(!forLoadingFromHash) this.Load(); + } + + public static List LoadByIds(List ids) { + + Dictionary rawRes = LoadByIdsForLoadingFromHash(ids); + + List idsToQuery = new List(); + foreach(int id in ids) { + if(!rawRes[id].isLoaded) { + idsToQuery.Add(id); + } + } + + if(idsToQuery.Count > 0) { + ITableSpec table = rawRes[idsToQuery[0]].table; + List> rawData = Config.instance.mainConnection.LoadByIds(table, new List(from int id in idsToQuery select id.ToString())); + foreach(Dictionary row in rawData) { + int id = int.Parse(row[table.idName]); + if(!rawRes.ContainsKey(id)) throw new CriticalException("wrong id"); + rawRes[id].fromHash(row); + } + } + + List res = new List(); + foreach(int id in ids) { + if(!rawRes[id].isLoaded) throw new CriticalException("not loaded"); + res.Add(rawRes[id]); + } + + return res; + } + + } +} diff --git a/Common/dataobjects/Board.cs b/Common/dataobjects/Board.cs new file mode 100644 index 0000000..248eb28 --- /dev/null +++ b/Common/dataobjects/Board.cs @@ -0,0 +1,62 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace FLocal.Common.dataobjects { + public class Board : SqlObject { + + private class TableSpec : FLocal.Core.DB.ITableSpec { + public static readonly TableSpec instance = new TableSpec(); + public string name { get { return "boards"; } } + public string idName { get { return "id"; } } + } + + protected override FLocal.Core.DB.ITableSpec table { get { return TableSpec.instance; } } + + private string _name; + public string name { + get { + this.LoadIfNotLoaded(); + return this._name; + } + } + + private string _description; + public string description { + get { + this.LoadIfNotLoaded(); + return this._description; + } + } + + private int _lastPostId; + public int lastPostId { + get { + this.LoadIfNotLoaded(); + return this._lastPostId; + } + } + + private int _categoryId; + public int categoryId { + get { + this.LoadIfNotLoaded(); + return this._categoryId; + } + } + public Category category { + get { + return Category.LoadById(this.categoryId); + } + } + + protected override void doFromHash(Dictionary data) { + this._name = data["name"]; + this._description = data["description"]; + this._lastPostId = int.Parse(data["lastPostId"]); + this._categoryId = int.Parse(data["categoryId"]); + } + + } +} diff --git a/Common/dataobjects/Category.cs b/Common/dataobjects/Category.cs new file mode 100644 index 0000000..67adb7f --- /dev/null +++ b/Common/dataobjects/Category.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace FLocal.Common.dataobjects { + public class Category : SqlObject { + + private class TableSpec : FLocal.Core.DB.ITableSpec { + public static readonly TableSpec instance = new TableSpec(); + public string name { get { return "categories"; } } + public string idName { get { return "id"; } } + } + + protected override FLocal.Core.DB.ITableSpec table { get { return TableSpec.instance; } } + + private string _name; + public string name { + get { + this.LoadIfNotLoaded(); + return this._name; + } + } + + protected override void doFromHash(Dictionary data) { + this._name = data["name"]; + } + + } +} diff --git a/Core/Config.cs b/Core/Config.cs index 4a51ea2..1acf2d3 100644 --- a/Core/Config.cs +++ b/Core/Config.cs @@ -6,7 +6,7 @@ using System.Collections.Specialized; namespace FLocal.Core { - public class Config where T : Config { + public abstract class Config : IDisposable where T : Config { private static T _instance = null; @@ -49,5 +49,8 @@ namespace FLocal.Core { } } + public virtual void Dispose() { + } + } } diff --git a/Core/DataObject.cs b/Core/DataObject.cs index 135d187..d7ad6e3 100644 --- a/Core/DataObject.cs +++ b/Core/DataObject.cs @@ -29,7 +29,7 @@ namespace FLocal.Core { private bool isJustCreated; - internal DataObject() { + protected DataObject() { Debug.Assert(this is T); this.isJustCreated = true; this._id = null; @@ -39,6 +39,14 @@ namespace FLocal.Core { return registry.Get(id, false); } + protected static Dictionary LoadByIdsForLoadingFromHash(List ids) { + Dictionary res = new Dictionary(); + foreach(TKey id in ids) { + res[id] = registry.Get(id, true); + } + return res; + } + protected virtual void AfterCreate(bool forLoadingFromHash) { } internal override void CreateByIdFromRegistry(TKey id, bool forLoadingFromHash) { diff --git a/Core/Registry.cs b/Core/Registry.cs index d364ee2..948e53c 100644 --- a/Core/Registry.cs +++ b/Core/Registry.cs @@ -47,10 +47,9 @@ namespace FLocal.Core { return this.Get(id, forLoadingFromHash); } -/* public bool IsCached(TKey id) { - if(this.locks.Contains(id)) throw new CriticalException("locked"); + public bool IsCached(TKey id) { return this.storage.ContainsKey(id); - }*/ + } internal void Delete(TKey[] idsToDelete) { foreach(TKey id in idsToDelete) { diff --git a/IISMainHandler/handlers/DebugHandler.cs b/IISMainHandler/handlers/DebugHandler.cs index 52449ff..6d1180d 100644 --- a/IISMainHandler/handlers/DebugHandler.cs +++ b/IISMainHandler/handlers/DebugHandler.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Web; +using FLocal.Common.dataobjects; namespace FLocal.IISHandler.handlers { class DebugHandler : ISpecificHandler { @@ -20,6 +21,19 @@ namespace FLocal.IISHandler.handlers { context.httpresponse.WriteLine("PathInfo: " + context.httprequest.PathInfo); context.httpresponse.WriteLine("AppInfo: " + context.config.AppInfo); context.httpresponse.WriteLine("InitTime: " + context.config.InitTime); + if(context.httprequest.Path == "/test/") { + using(Core.DB.Transaction transaction = context.config.mainConnection.beginTransaction(System.Data.IsolationLevel.Snapshot)) { + context.httpresponse.WriteLine(transaction.GetHashCode().ToString()); + } + } + if(context.httprequest.Path == "/boards") { + /*Board board = Board.LoadById(1); + context.httpresponse.WriteLine("name: " + board.name); + context.httpresponse.WriteLine("description: " + board.description); + context.httpresponse.WriteLine("categoryname: " + board.category.name);*/ + Category category = Category.LoadById(1); + context.httpresponse.WriteLine("categoryname: " + category.name); + } } }