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);
+ }
}
}