/*
* Box Socialâ„¢
* http://boxsocial.net/
* Copyright © 2007, David Lachlan Smith
*
* $Id:$
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
using System;
using System.Collections.Generic;
using System.Data;
using System.Reflection;
using System.Diagnostics;
using System.Text;
using System.Web;
using System.Web.Caching;
using BoxSocial.IO;
namespace BoxSocial.Internals
{
public abstract class Item
{
public const long MYSQL_TEXT = 65535L;
public const long MYSQL_MEDIUM_TEXT = 16777215L;
public const long MYSQL_LONG_TEXT = 4294967295L;
public const long NAMESPACE = 31L;
public const long IP = 50L;
///
/// Database object
///
protected Mysql db;
///
/// Core token
///
protected Core core;
private Assembly assembly;
private List updatedItems;
public delegate void ItemLoadHandler();
public delegate void ItemChangeAuthenticationProviderHandler(object sender, ItemChangeAuthenticationProviderEventArgs e);
public delegate void ItemDeletedEventHandler(object sender, ItemDeletedEventArgs e);
public event ItemLoadHandler ItemLoad;
public event ItemChangeAuthenticationProviderHandler ItemChangeAuthenticationProvider;
public event EventHandler OnUpdate;
public event EventHandler OnDelete;
public event EventHandler ItemUpdated;
public event ItemDeletedEventHandler ItemDeleted;
public Bbcode Bbcode
{
get
{
return core.Bbcode;
}
}
private Functions Functions
{
get
{
return core.Functions;
}
}
protected Item(Core core)
{
this.core = core;
this.db = core.Db;
assembly = Assembly.GetCallingAssembly();
updatedItems = new List();
}
public static string GetPrimaryKey(Type type)
{
List fields = GetFields(type);
string keyField = string.Empty;
foreach (DataFieldInfo field in fields)
{
if ((field.Key & DataFieldKeys.Primary) == DataFieldKeys.Primary)
{
keyField = field.Name;
}
}
if (string.IsNullOrEmpty(keyField))
{
// Error
throw new NoPrimaryKeyException();
}
return keyField;
}
protected void LoadItem(long primaryKey, params FieldValuePair[] keyFields)
{
LoadItem(this.GetType(), primaryKey, keyFields);
}
protected void LoadItem(long primaryKey)
{
LoadItem(this.GetType(), primaryKey, null);
}
protected void LoadItem(Type type, long primaryKey, params FieldValuePair[] keyFields)
{
// 1. Discover primary key
// 2. Build query
// 3. Execute query
// 4. Fill results
string tableName = GetTable(type);
List fields = GetFields(type);
string keyField = string.Empty;
SelectQuery query = new SelectQuery(tableName);
foreach (DataFieldInfo field in fields)
{
if ((field.Key & DataFieldKeys.Primary) == DataFieldKeys.Primary)
{
keyField = field.Name;
}
query.AddFields(field.Name);
}
if (string.IsNullOrEmpty(keyField))
{
// Error
throw new NoPrimaryKeyException();
}
query.AddCondition(keyField, primaryKey);
if (keyFields != null)
{
foreach (FieldValuePair fvp in keyFields)
{
query.AddCondition(fvp.Field, fvp.Value);
}
}
/*DataTable itemTable = Query(query);
if (itemTable.Rows.Count == 1)
{
loadItemInfo(type, itemTable.Rows[0]);
}
else
{
// Error
throw new InvalidItemException(this.GetType().FullName);
}*/
loadItemInfo(type, core.Db.ReaderQuery(query));
}
protected void LoadItem(string uniqueIndex, object value)
{
LoadItem(uniqueIndex, value, false);
}
protected void LoadItem(string uniqueIndex, object value, bool caseInsensitive)
{
// 1. check index is unique
// 2. Build query
// 3. Execute query
// 4. Fill results
string tableName = GetTable(this.GetType());
List fields = GetFields(this.GetType());
string keyField = string.Empty;
SelectQuery query = new SelectQuery(tableName);
foreach (DataFieldInfo field in fields)
{
if (field.Name == uniqueIndex)
{
if ((field.Key & (DataFieldKeys.Unique | DataFieldKeys.Primary)) != DataFieldKeys.None)
{
keyField = field.Name;
}
else
{
throw new FieldNotUniqueIndexException(field.Name);
}
}
query.AddFields(field.Name);
}
if (value is string && caseInsensitive)
{
query.AddCondition(new QueryFunction(keyField, QueryFunctions.ToLowerCase), ((string)value).ToLower());
}
else
{
query.AddCondition(keyField, value);
}
/*DataTable itemTable = Query(query);
if (itemTable.Rows.Count == 1)
{
loadItemInfo(itemTable.Rows[0]);
if (ItemLoad != null)
{
ItemLoad();
}
}
else
{
// Error
throw new InvalidItemException(this.GetType().FullName);
}*/
loadItemInfo(this.GetType(), core.Db.ReaderQuery(query));
}
protected void LoadItem(string ownerIdIndex, string ownerTypeIndex, Primitive owner)
{
// 1. check indexes are unique
// 2. Build query
// 3. Execute query
// 4. Fill results
string tableName = GetTable(this.GetType());
List fields = GetFields(this.GetType());
SelectQuery query = new SelectQuery(tableName);
foreach (DataFieldInfo field in fields)
{
if (field.Name == ownerIdIndex || field.Name == ownerTypeIndex)
{
if ((field.Key & DataFieldKeys.Unique) != DataFieldKeys.Unique)
{
throw new FieldNotUniqueIndexException();
}
}
query.AddFields(field.Name);
}
query.AddCondition(ownerIdIndex, owner.Id);
query.AddCondition(ownerTypeIndex, owner.TypeId);
/*DataTable itemTable = Query(query);
if (itemTable.Rows.Count == 1)
{
loadItemInfo(itemTable.Rows[0]);
if (ItemLoad != null)
{
ItemLoad();
}
}
else
{
// Error
throw new InvalidItemException(this.GetType().FullName);
}*/
loadItemInfo(this.GetType(), core.Db.ReaderQuery(query));
}
protected List getSubTypes()
{
List types = new List();
Type currentType = this.GetType();
Type[] allTypes = currentType.Assembly.GetTypes();
foreach (Type type in allTypes)
{
List fields = GetFields(type);
foreach (DataFieldInfo field in fields)
{
if (field.ParentType == currentType)
{
types.Add(type);
break;
}
}
}
return types;
}
protected void UpdateThis()
{
StackTrace st = new StackTrace();
StackFrame sf = st.GetFrame(1);
updatedItems.Add(sf.GetMethod().Name);
}
protected void SetProperty(string key, object value)
{
try
{
Type thisType = this.GetType();
FieldInfo fi = thisType.GetField(key, BindingFlags.Default | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.DeclaredOnly);
if ((fi.GetValue(this) == null && value != null )|| (!fi.GetValue(this).Equals(value)))
{
fi.SetValue(this, value);
if (!updatedItems.Contains(key))
{
updatedItems.Add(key);
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
protected bool HasPropertyUpdated(string key)
{
if (updatedItems.Contains(key))
{
return true;
}
else
{
return false;
}
}
protected DataTable Query(SelectQuery query)
{
return db.Query(query);
}
protected long Query(InsertQuery query)
{
return db.Query(query);
}
protected long Query(UpdateQuery query)
{
return db.Query(query);
}
protected long Query(DeleteQuery query)
{
return db.Query(query);
}
public string Namespace
{
get
{
return GetNamespace(this.GetType());
}
}
public abstract string Uri
{
get;
}
protected List getTags()
{
List tags = new List();
return tags;
}
protected Primitive fillOwner(long ownerId, long ownerTypeId)
{
Primitive owner;
Type type = core.GetPrimitiveType(ownerTypeId);
if (type.IsSubclassOf(typeof(Primitive)))
{
owner = System.Activator.CreateInstance(type, new object[] { core, ownerId }) as Primitive;
return owner;
}
else
{
return null;
}
}
///
/// returns the field that is linked to the parent of a given type
///
///
///
public static string GetParentField(Type parentType)
{
string returnValue = null;
Type[] types = parentType.Assembly.GetTypes();
foreach (Type type in types)
{
List fields = GetFields(type);
foreach (DataFieldInfo field in fields)
{
if (field.ParentType == parentType)
{
if (string.IsNullOrEmpty(returnValue))
{
returnValue = field.Name;
}
else
{
// TODO: create a new exception
throw new Exception("Multiple children types");
}
}
}
}
if (!string.IsNullOrEmpty(returnValue))
{
return returnValue;
}
else
{
// TODO: Exception
throw new Exception("No parent of type " + parentType.Name + " found.");
}
}
public static string GetParentField(Type parentType, Type childType)
{
string returnValue = null;
List fields = GetFields(childType);
foreach (DataFieldInfo field in fields)
{
if (field.ParentType == parentType)
{
if (string.IsNullOrEmpty(returnValue))
{
returnValue = field.Name;
}
else
{
// TODO: create a new exception
throw new Exception("Multiple children types.");
}
}
}
if (!string.IsNullOrEmpty(returnValue))
{
return returnValue;
}
else
{
// TODO: Exception
throw new Exception("No parent of type " + childType.Name + " found.");
}
}
public SelectQuery GetSelectQueryStub()
{
return GetSelectQueryStub(this.GetType());
}
public static SelectQuery GetSelectQueryStub(Type type)
{
return GetSelectQueryStub(type, true);
}
///
///
///
///
/// Check for redefined _GetSelectQueryStub
///
public static SelectQuery GetSelectQueryStub(Type type, bool check)
{
SelectQuery query;
if (check && type.GetMethod(type.Name + "_GetSelectQueryStub", Type.EmptyTypes) != null)
{
query = (SelectQuery)type.InvokeMember(type.Name + "_GetSelectQueryStub", BindingFlags.Public | BindingFlags.Static | BindingFlags.InvokeMethod, null, null, new object[] { }); //GetSelectQueryStub(typeToGet);
}
else
{
query = new SelectQuery(GetTable(type));
query.AddFields(GetFieldsPrefixed(type));
/*Type[] interfaces = type.GetInterfaces();
foreach (Type i in interfaces)
{
if (i == typeof(IPermissibleItem))
{
//query.AddFields(GetFieldsPrefixed(typeof(AccessControlGrant)));
/* * /
}
}*/
}
return query;
}
public SelectQuery getSelectQueryStub()
{
Type type = this.GetType();
SelectQuery query = new SelectQuery(GetTable(type));
query.AddFields(GetFieldsPrefixed(type));
return query;
}
private static Object itemFieldsCacheLock = new Object();
private static Dictionary> itemFieldsCache = null;
private static void populateItemFieldsCache()
{
object o = null;
System.Web.Caching.Cache cache;
if (HttpContext.Current != null && HttpContext.Current.Cache != null)
{
cache = HttpContext.Current.Cache;
}
else
{
cache = new Cache();
}
try
{
if (cache != null)
{
o = cache.Get("itemFields");
}
}
catch (NullReferenceException)
{
}
lock (itemFieldsCacheLock)
{
if (o != null && o is Dictionary>)
{
itemFieldsCache = (Dictionary>)o;
}
else
{
itemFieldsCache = new Dictionary>();
}
}
}
internal protected static List GetFields(Type type)
{
return GetFields(type, false);
}
internal protected static List GetRawFields(Type type)
{
return GetFields(type, true);
}
internal protected static List GetFields(Type type, bool getRawFields)
{
List returnValue = new List();
if (itemFieldsCache != null)
{
if (itemFieldsCache.ContainsKey(type) && (!getRawFields))
{
return itemFieldsCache[type];
}
}
else
{
populateItemFieldsCache();
}
foreach (FieldInfo fi in type.GetFields(BindingFlags.Default | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.DeclaredOnly))
{
foreach (Attribute attr in Attribute.GetCustomAttributes(fi, typeof(DataFieldAttribute)))
{
DataFieldAttribute dfattr = (DataFieldAttribute)attr;
if (dfattr.FieldName != null)
{
if ((fi.FieldType == typeof(ItemKey)) && (!getRawFields))
{
DataFieldInfo dfiId;
DataFieldInfo dfiTypeId;
dfiId = new DataFieldInfo(dfattr.FieldName + "_id", typeof(long), dfattr.MaxLength, dfattr.Index);
dfiTypeId = new DataFieldInfo(dfattr.FieldName + "_type_id", typeof(long), dfattr.MaxLength, dfattr.Index);
dfiId.ParentType = dfattr.ParentType;
dfiId.ParentFieldName = dfattr.ParentFieldName;
dfiTypeId.ParentType = dfattr.ParentType;
dfiTypeId.ParentFieldName = dfattr.ParentFieldName;
returnValue.Add(dfiId);
returnValue.Add(dfiTypeId);
}
else
{
DataFieldInfo dfi;
dfi = new DataFieldInfo(dfattr.FieldName, fi.FieldType, dfattr.MaxLength, dfattr.Index);
dfi.ParentType = dfattr.ParentType;
dfi.ParentFieldName = dfattr.ParentFieldName;
returnValue.Add(dfi);
}
}
else
{
returnValue.Add(new DataFieldInfo(fi.Name, fi.FieldType, 255));
}
}
}
if ((!itemFieldsCache.ContainsKey(type)) && (!getRawFields))
{
lock (itemFieldsCacheLock)
{
itemFieldsCache.Add(type, returnValue);
}
}
System.Web.Caching.Cache cache;
if (HttpContext.Current != null && HttpContext.Current.Cache != null)
{
cache = HttpContext.Current.Cache;
}
else
{
cache = new Cache();
}
if (cache != null)
{
try
{
cache.Add("itemFields", itemFieldsCache, null, Cache.NoAbsoluteExpiration, new TimeSpan(12, 0, 0), CacheItemPriority.High, null);
}
catch (NullReferenceException)
{
}
}
return returnValue;
}
internal static object GetFieldValue(DataFieldInfo dfi, Item item)
{
foreach (FieldInfo fi in item.GetType().GetFields(BindingFlags.Default | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.DeclaredOnly))
{
foreach (Attribute attr in Attribute.GetCustomAttributes(fi, typeof(DataFieldAttribute)))
{
DataFieldAttribute dfattr = (DataFieldAttribute)attr;
if (dfattr.FieldName != null)
{
if (dfi.Name == dfattr.FieldName)
{
return fi.GetValue(item);
}
}
}
}
return 0;
}
public static string[] GetFieldsPrefixed(Type type)
{
string tableName = GetTable(type);
List fields = GetFields(type);
string[] returnValue = new string[fields.Count];
for (int i = 0; i < fields.Count; i++)
{
returnValue[i] = string.Format("`{0}`.`{1}`",
tableName, fields[i].Name);
}
return returnValue;
}
protected string Table
{
get
{
return GetTable(this.GetType());
}
}
protected string[] FieldsPrefixed
{
get
{
return GetFieldsPrefixed(this.GetType());
}
}
public static string GetTable(Type type)
{
return DataFieldAttribute.GetTable(type);
}
internal protected static string GetNamespace(Type type)
{
foreach (Attribute attr in type.GetCustomAttributes(typeof(DataTableAttribute), false))
{
DataTableAttribute dtattr = (DataTableAttribute)attr;
if (attr != null)
{
if (dtattr.Namespace != null)
{
return dtattr.Namespace;
}
}
}
return type.FullName;
}
public long Update()
{
return Update(this.GetType());
}
public long Update(Type type)
{
if (this is IPermissibleItem)
{
IPermissibleItem iThis = (IPermissibleItem)this;
if (!iThis.Access.Can("EDIT"))
{
throw new UnauthorisedToUpdateItemException();
}
}
if (ItemChangeAuthenticationProvider != null)
{
ItemChangeAuthenticationProvider(this, new ItemChangeAuthenticationProviderEventArgs(ItemChangeAction.Edit));
}
if (OnUpdate != null)
{
OnUpdate(this, new EventArgs());
}
if (updatedItems.Count == 0)
{
return 0;
}
SelectQuery sQuery = new SelectQuery(Item.GetTable(type));
UpdateQuery uQuery = new UpdateQuery(Item.GetTable(type));
foreach (FieldInfo fi in type.GetFields(BindingFlags.Default | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.DeclaredOnly))
{
foreach (Attribute attr in Attribute.GetCustomAttributes(fi, typeof(DataFieldAttribute)))
{
if (updatedItems.Contains(fi.Name))
{
DataFieldAttribute dfattr = (DataFieldAttribute)attr;
if (dfattr.FieldName != null)
{
uQuery.AddField(dfattr.FieldName, fi.GetValue(this));
}
else
{
uQuery.AddField(fi.Name, fi.GetValue(this));
}
}
}
}
List fields = GetRawFields(type);
bool foundKey = false;
bool containsUniqueFields = false;
foreach (DataFieldInfo field in fields)
{
if ((field.Key & DataFieldKeys.Primary) == DataFieldKeys.Primary)
{
sQuery.AddFields(field.Name);
//sQuery.AddCondition(field.Name, ConditionEquality.NotEqual, GetFieldValue(field, this));
sQuery.AddCondition(field.Name, GetFieldValue(field, this));
uQuery.AddCondition(field.Name, GetFieldValue(field, this));
foundKey = true;
}
}
foreach (DataFieldInfo field in fields)
{
if ((field.Key & DataFieldKeys.Unique) == DataFieldKeys.Unique)
{
containsUniqueFields = true;
if (field.Type == typeof(ItemKey))
{
sQuery.AddCondition(field.Name + "_id", ((ItemKey)GetFieldValue(field, this)).Id);
sQuery.AddCondition(field.Name + "_type_id", ((ItemKey)GetFieldValue(field, this)).TypeId);
//uQuery.AddCondition(field.Name + "_id", ((ItemKey)GetFieldValue(field, this)).Id);
//uQuery.AddCondition(field.Name + "_type_id", ((ItemKey)GetFieldValue(field, this)).TypeId);
}
else
{
sQuery.AddCondition(field.Name, GetFieldValue(field, this));
//uQuery.AddCondition(field.Name, GetFieldValue(field, this));
}
}
}
if (!foundKey)
{
foreach (DataFieldInfo field in fields)
{
if ((field.Key & DataFieldKeys.Unique) == DataFieldKeys.Unique)
{
if (field.Type == typeof(ItemKey))
{
uQuery.AddCondition(field.Name + "_id", ((ItemKey)GetFieldValue(field, this)).Id);
uQuery.AddCondition(field.Name + "_type_id", ((ItemKey)GetFieldValue(field, this)).TypeId);
}
else
{
uQuery.AddCondition(field.Name, GetFieldValue(field, this));
}
if (updatedItems.Contains(field.Name))
{
/* cannot change a unique key */
foundKey = false;
break;
}
else
{
foundKey = true;
// continue, all must match
}
}
}
}
if (!foundKey)
{
// Error
throw new NoPrimaryKeyException();
}
// check uniqueness
if (containsUniqueFields)
{
long uniqueness = db.Query(sQuery).Rows.Count;
if (uniqueness != 1)
{
throw new RecordNotUniqueException();
}
}
long result = db.Query(uQuery);
if (result > 0)
{
if (ItemUpdated != null)
{
ItemUpdated(this, new EventArgs());
}
}
return result;
}
protected void AuthenticateAction(ItemChangeAction action)
{
if (ItemChangeAuthenticationProvider != null)
{
ItemChangeAuthenticationProvider(this, new ItemChangeAuthenticationProviderEventArgs(action));
}
}
public static Item Create(Core core, Type type, params FieldValuePair[] fields)
{
return Create(core, type, false, fields);
}
public static Item Create(Core core, Type type, bool suppress, params FieldValuePair[] fields)
{
core.Db.BeginTransaction();
InsertQuery iQuery = new InsertQuery(GetTable(type));
foreach (FieldValuePair field in fields)
{
iQuery.AddField(field.Field, field.Value);
}
long id = core.Db.Query(iQuery);
if (id > 0)
{
if (!suppress)
{
Item newItem = System.Activator.CreateInstance(type, new object[] { core, id }) as Item;
return newItem;
}
else
{
return null;
}
}
else
{
throw new InvalidItemException(type.FullName);
}
}
public static long DeleteItem(Type type, long itemId)
{
/*if (this is IPermissibleItem)
{
IPermissibleItem iThis = (IPermissibleItem)this;
//iThis.Access.SetSessionViewer(core.session);
if (!iThis.Access.Can("DELETE"))
{
throw new UnauthorisedToDeleteItemException();
}
}*/
return 0;
}
public long Delete()
{
return Delete(false);
}
public long Delete(bool parentDeleted)
{
if (this is IPermissibleItem)
{
IPermissibleItem iThis = (IPermissibleItem)this;
//iThis.Access.SetSessionViewer(core.session);
if (!iThis.Access.Can("DELETE"))
{
throw new UnauthorisedToDeleteItemException();
}
}
AuthenticateAction(ItemChangeAction.Delete);
db.BeginTransaction();
DeleteQuery dQuery = new DeleteQuery(Item.GetTable(this.GetType()));
List fields = GetFields(this.GetType());
bool foundKey = false;
foreach (DataFieldInfo field in fields)
{
if ((field.Key & (DataFieldKeys.Primary | DataFieldKeys.Unique)) != DataFieldKeys.None)
{
dQuery.AddCondition(field.Name, GetFieldValue(field, this));
foundKey = true;
}
}
if (!foundKey)
{
// Error
throw new NoPrimaryKeyException();
}
long result = db.Query(dQuery);
if (result > 0)
{
if (ItemDeleted != null)
{
ItemDeleted(this, new ItemDeletedEventArgs(parentDeleted));
}
}
return result;
}
protected void loadItemInfo(System.Data.Common.DbDataReader reader)
{
loadItemInfo(this.GetType(), reader);
}
protected void loadItemInfo(Type type, System.Data.Common.DbDataReader reader)
{
int fieldsLoaded = 0;
int objectFields = 0;
Dictionary fields = new Dictionary();
foreach (FieldInfo fi in type.GetFields(BindingFlags.Default | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.DeclaredOnly))
{
foreach (Attribute attr in Attribute.GetCustomAttributes(fi, typeof(DataFieldAttribute)))
{
DataFieldAttribute dfattr = (DataFieldAttribute)attr;
objectFields++;
string columnPrefix;
if (dfattr.FieldName != null)
{
columnPrefix = dfattr.FieldName;
}
else
{
columnPrefix = fi.Name;
}
fields.Add(columnPrefix, fi);
if (fi.FieldType == typeof(ItemKey))
{
fields.Add(columnPrefix + "_id", fi);
fields.Add(columnPrefix + "_type_id", fi);
}
}
}
/* buffer for item */
long ikBufferId = 0;
long ikBufferTypeId = 0;
if (reader.HasRows)
{
bool rowRead = false; /* past participle */
while (reader.Read())
{
/* only read one row */
if (rowRead)
{
// Error
reader.Close();
reader.Dispose();
throw new InvalidItemException(this.GetType().FullName + " :: Row Count");
}
else
{
rowRead = true;
}
for (int i = 0; i < reader.FieldCount; i++)
{
string column = reader.GetName(i);
object value = null;
if (fields.ContainsKey(column))
{
FieldInfo fi = fields[column];
if (!reader.IsDBNull(i))
{
value = reader.GetValue(i);
}
else
{
if (fi.FieldType == typeof(string))
{
fieldsLoaded++;
continue;
}
}
/*try
{*/
if (fi.FieldType == typeof(ItemKey))
{
if (ikBufferId > 0 && column.EndsWith("_type_id"))
{
fi.SetValue(this, new ItemKey(ikBufferId, (long)value));
fieldsLoaded++;
}
else if (ikBufferTypeId > 0 && column.EndsWith("_id"))
{
fi.SetValue(this, new ItemKey((long)value, ikBufferTypeId));
fieldsLoaded++;
}
else
{
if (column.EndsWith("_id"))
{
ikBufferId = (long)value;
}
else if (column.EndsWith("_type_id"))
{
ikBufferTypeId = (long)value;
}
}
}
else if (fi.FieldType == typeof(bool) && !(value is bool))
{
if (value is byte)
{
fi.SetValue(this, ((byte)value > 0) ? true : false);
fieldsLoaded++;
}
else if (value is sbyte)
{
fi.SetValue(this, ((sbyte)value > 0) ? true : false);
fieldsLoaded++;
}
}
else
{
fi.SetValue(this, value);
fieldsLoaded++;
}
/*}
catch (Exception ex)
{
Display.ShowMessage("Type error on load", Bbcode.Strip(column + " expected type " + fi.FieldType + " type returned was " + value.GetType() + "\n\n" + ex));
}*/
}
}
}
}
if (fieldsLoaded != objectFields)
{
reader.Close();
reader.Dispose();
throw new InvalidItemException(this.GetType().FullName + " :: fieldsLoaded != objectFields");
}
reader.Close();
reader.Dispose();
if (ItemLoad != null)
{
ItemLoad();
}
}
protected void loadItemInfo(DataRow itemRow)
{
loadItemInfo(this.GetType(), itemRow);
}
protected void loadItemInfo(Type type, DataRow itemRow)
{
List columns = new List();
List columnsAttributed = new List();
int columnCount = 0;
foreach (DataColumn column in itemRow.Table.Columns)
{
columns.Add(column.ColumnName);
}
foreach (FieldInfo fi in type.GetFields(BindingFlags.Default | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.DeclaredOnly))
{
foreach (Attribute attr in Attribute.GetCustomAttributes(fi))
{
if (attr is DataFieldAttribute)
{
DataFieldAttribute dfattr = (DataFieldAttribute)attr;
if (fi.FieldType == typeof(ItemKey))
{
string columnPrefix;
if (dfattr.FieldName != null)
{
columnPrefix = dfattr.FieldName;
}
else
{
columnPrefix = fi.Name;
}
columnsAttributed.Add(columnPrefix);
columnsAttributed.Add(columnPrefix + "_id");
columnsAttributed.Add(columnPrefix + "_type_id");
fi.SetValue(this, new ItemKey((long)itemRow[columnPrefix + "_id"], (long)itemRow[columnPrefix + "_type_id"]));
}
else
{
string columnName;
if (dfattr.FieldName != null)
{
columnName = dfattr.FieldName;
}
else
{
columnName = fi.Name;
}
columnsAttributed.Add(columnName);
if (columns.Contains(columnName))
{
columnCount++;
if (!(itemRow[columnName] is DBNull))
{
try
{
if (fi.FieldType == typeof(bool) && !(itemRow[columnName] is bool))
{
if (itemRow[columnName] is byte)
{
fi.SetValue(this, ((byte)itemRow[columnName] > 0) ? true : false);
}
else if (itemRow[columnName] is sbyte)
{
fi.SetValue(this, ((sbyte)itemRow[columnName] > 0) ? true : false);
}
}
else
{
fi.SetValue(this, itemRow[columnName]);
}
}
catch (Exception ex)
{
core.Display.ShowMessage("Type error on load", core.Bbcode.Strip(columnName + " expected type " + fi.FieldType + " type returned was " + itemRow[columnName].GetType() + "\n\n" + ex));
}
}
else
{
// This works only when the non repeated columns are not entirely TEXT
if (fi.FieldType == typeof(string))
{
columnCount++;
}
else
{
throw new InvalidItemException(this.GetType().FullName);
}
}
}
}
}
}
}
if (columnCount == 0)
{
throw new InvalidItemException(this.GetType().FullName);
}
if (ItemLoad != null)
{
ItemLoad();
}
}
protected void MoveUp(string orderField)
{
// TODO: make sure isn't INestableItem
IOrderableItem oItem = (IOrderableItem)this;
UpdateQuery uQuery = new UpdateQuery(GetTable(this.GetType()));
uQuery.AddField(orderField, new QueryOperation(orderField, QueryOperations.Addition, 1));
uQuery.AddCondition(orderField, oItem.Order);
oItem.AddSequenceConditon(uQuery);
core.Db.Query(uQuery);
oItem.Order--;
this.Update();
}
protected void MoveDown(string orderField)
{
// TODO: make sure isn't INestableItem
IOrderableItem oItem = (IOrderableItem)this;
UpdateQuery uQuery = new UpdateQuery(GetTable(this.GetType()));
uQuery.AddField(orderField, new QueryOperation(orderField, QueryOperations.Subtraction, 1));
uQuery.AddCondition(orderField, oItem.Order);
oItem.AddSequenceConditon(uQuery);
core.Db.Query(uQuery);
oItem.Order++;
this.Update();
}
public static void IncrementItemColumn(Core core, Type type, long id, string column, int value)
{
UpdateQuery uQuery = new UpdateQuery(GetTable(type));
uQuery.AddField(column, new QueryOperation(column, QueryOperations.Addition, value));
uQuery.AddCondition(GetPrimaryKey(type), id);
core.Db.Query(uQuery);
}
}
public enum ItemChangeAction
{
Edit,
Delete,
Create,
}
public class ItemChangeAuthenticationProviderEventArgs : EventArgs
{
private ItemChangeAction action;
public ItemChangeAction Action
{
get
{
return action;
}
}
public ItemChangeAuthenticationProviderEventArgs(ItemChangeAction action)
{
this.action = action;
}
}
public class ItemDeletedEventArgs : EventArgs
{
private bool parentDeleted;
public bool ParentDeleted
{
get
{
return parentDeleted;
}
}
public ItemDeletedEventArgs(bool parentDeleted)
{
this.parentDeleted = parentDeleted;
}
}
public class InvalidItemException : Exception
{
public InvalidItemException()
{
}
public InvalidItemException(string type)
: base("Type: " + type)
{
}
}
public class NoPrimaryKeyException : Exception
{
}
public class RecordNotUniqueException : Exception
{
}
public class FieldNotUniqueIndexException : Exception
{
public FieldNotUniqueIndexException()
: base ()
{
}
public FieldNotUniqueIndexException(string field)
: base("Field: " + field)
{
}
}
public class UnauthorisedToCreateItemException : Exception
{
}
public class UnauthorisedToUpdateItemException : Exception
{
}
public class UnauthorisedToDeleteItemException : Exception
{
}
}