コード例 #1
0
        /// <summary>
        /// Retrieve a Collection of DataObjects Sets from database filtered by Parametrized Where Expression
        /// </summary>
        /// <param name="tableHandler">Table Handler for these DataObjects</param>
        /// <param name="whereExpression">Parametrized Where Expression</param>
        /// <param name="parameters">Parameters for filtering</param>
        /// <param name="isolation">Isolation Level</param>
        /// <returns>Collection of DataObjects Sets matching Parametrized Where Expression</returns>
        protected override IList <IList <DataObject> > SelectObjectsImpl(DataTableHandler tableHandler, string whereExpression, IEnumerable <IEnumerable <QueryParameter> > parameters, Transaction.IsolationLevel isolation)
        {
            var columns = tableHandler.FieldElementBindings.ToArray();

            string command = null;

            if (!string.IsNullOrEmpty(whereExpression))
            {
                command = string.Format("SELECT {0} FROM `{1}` WHERE {2}",
                                        string.Join(", ", columns.Select(col => string.Format("`{0}`", col.ColumnName))),
                                        tableHandler.TableName,
                                        whereExpression);
            }
            else
            {
                command = string.Format("SELECT {0} FROM `{1}`",
                                        string.Join(", ", columns.Select(col => string.Format("`{0}`", col.ColumnName))),
                                        tableHandler.TableName);
            }

            var primary     = columns.FirstOrDefault(col => col.PrimaryKey != null);
            var dataObjects = new List <IList <DataObject> >();

            ExecuteSelectImpl(command, parameters, reader => FillQueryResultList(reader, tableHandler, columns, primary, dataObjects));

            return(dataObjects.ToArray());
        }
コード例 #2
0
		public void TestAllAvailableTables()
		{
			foreach (Assembly assembly in new [] { typeof(GameServer).Assembly, typeof(DataObject).Assembly })
			{
				// Walk through each type in the assembly
				foreach (Type type in assembly.GetTypes())
				{
					if (!type.IsClass || type.IsAbstract)
						continue;
					
					var attrib = type.GetCustomAttributes<DataTable>(false);
					if (attrib.Any())
					{
						Assert.DoesNotThrow( () => {
						                    	var dth = new DataTableHandler(type);
						                    	Database.CheckOrCreateTableImpl(dth);
						                    }, "Registering All Projects Tables should not throw Exceptions... (Failed on Type {0})", type.FullName);
						
						Database.RegisterDataObject(type);
						var selectall = typeof(IObjectDatabase).GetMethod("SelectAllObjects", new Type[] { }).MakeGenericMethod(type);
						object objs = null;
						Assert.DoesNotThrow( () => { objs = selectall.Invoke(Database, new object[] { }); }, "Registered tables should not Throw Exception on Select All... (Failed on Type {0})", type);
						Assert.IsNotNull(objs);
					}
				}
			}
		}
コード例 #3
0
        /// <summary>
        /// Register Data Object Type if not already Registered
        /// </summary>
        /// <param name="dataObjectType">DataObject Type</param>
        public override void RegisterDataObject(Type dataObjectType)
        {
            var tableName = AttributesUtils.GetTableOrViewName(dataObjectType);
            var isView    = AttributesUtils.GetViewName(dataObjectType) != null;
            var viewAs    = AttributesUtils.GetViewAs(dataObjectType);

            DataTableHandler existingHandler;

            if (TableDatasets.TryGetValue(tableName, out existingHandler))
            {
                if (dataObjectType != existingHandler.ObjectType)
                {
                    throw new DatabaseException(string.Format("Table Handler Duplicate for Type: {2}, Table Name '{0}' Already Registered with Type : {1}", tableName, existingHandler.ObjectType, dataObjectType));
                }

                return;
            }

            var dataTableHandler = new DataTableHandler(dataObjectType);

            try
            {
                if (isView)
                {
                    if (!string.IsNullOrEmpty(viewAs))
                    {
                        ExecuteNonQueryImpl(string.Format("DROP VIEW IF EXISTS `{0}`", tableName));
                        ExecuteNonQueryImpl(string.Format("CREATE VIEW `{0}` AS {1}", tableName, string.Format(viewAs, string.Format("`{0}`", AttributesUtils.GetTableName(dataObjectType)))));
                    }
                }
                else
                {
                    CheckOrCreateTableImpl(dataTableHandler);
                }

                lock (Lock)
                {
                    TableDatasets.Add(tableName, dataTableHandler);
                }

                // Init PreCache
                if (dataTableHandler.UsesPreCaching)
                {
                    var primary = dataTableHandler.PrimaryKeys.Single();
                    var objects = MultipleSelectObjectsImpl(dataTableHandler, new [] { WhereClause.Empty }).First();

                    foreach (var obj in objects)
                    {
                        dataTableHandler.SetPreCachedObject(primary.GetValue(obj), obj);
                    }
                }
            }
            catch (Exception e)
            {
                if (log.IsErrorEnabled)
                {
                    log.ErrorFormat("RegisterDataObject: Error While Registering Table \"{0}\"\n{1}", tableName, e);
                }
            }
        }
コード例 #4
0
        private void FillQueryResultList(IDataReader reader, DataTableHandler tableHandler, ElementBinding[] columns, ElementBinding primary, List <IList <DataObject> > resultList)
        {
            var list = new List <DataObject>();

            var data = new object[reader.FieldCount];

            while (reader.Read())
            {
                reader.GetValues(data);
                var obj = Activator.CreateInstance(tableHandler.ObjectType) as DataObject;

                // Fill Object
                var current = 0;
                foreach (var column in columns)
                {
                    DatabaseSetValue(obj, column, data[current]);
                    current++;
                }

                // Set Primary Key
                if (primary != null)
                {
                    obj.ObjectId = primary.GetValue(obj).ToString();
                }

                list.Add(obj);
                obj.Dirty       = false;
                obj.IsPersisted = true;
            }
            resultList.Add(list.ToArray());
        }
コード例 #5
0
        /// <summary>
        /// Retrieve a Collection of DataObjects from database based on their primary key values
        /// </summary>
        /// <param name="tableHandler">Table Handler for the DataObjects to Retrieve</param>
        /// <param name="keys">Collection of Primary Key Values</param>
        /// <returns>Collection of DataObject with primary key matching values</returns>
        protected override IEnumerable <DataObject> FindObjectByKeyImpl(DataTableHandler tableHandler, IEnumerable <object> keys)
        {
            // Primary Key
            var primary = tableHandler.FieldElementBindings.Where(bind => bind.PrimaryKey != null)
                          .Select(bind => new { ColumnName = string.Format("`{0}`", bind.ColumnName), ParamName = string.Format("@{0}", bind.ColumnName), ParamType = bind.ValueType }).ToArray();

            if (!primary.Any())
            {
                throw new DatabaseException(string.Format("Table {0} has no primary key for finding by key...", tableHandler.TableName));
            }

            var whereClauses = new List <WhereClause>();

            foreach (var key in keys)
            {
                var whereClause = WhereClause.Empty;
                foreach (var column in primary)
                {
                    whereClause = whereClause.And(DB.Column(column.ColumnName).IsEqualTo(key));
                }
                whereClauses.Add(whereClause);
            }

            var resultByKeys = MultipleSelectObjectsImpl(tableHandler, whereClauses).Select(results => results.SingleOrDefault());

            return(resultByKeys.ToArray());
        }
コード例 #6
0
		public void TestWrongDataObject()
		{
			Assert.Throws(typeof(ArgumentException), () => {
			              	var dth = new DataTableHandler(typeof(AttributesUtils));
			              	Database.CheckOrCreateTableImpl(dth);
			              }, "Registering a wrong DataObject should throw Argument Exception");
		}
コード例 #7
0
        /// <summary>
        /// Deletes DataObjects from the database.
        /// </summary>
        /// <param name="dataObjects">DataObjects to delete from the database</param>
        /// <param name="tableHandler">Table Handler for the DataObjects Collection</param>
        /// <returns>True if objects were deleted successfully; false otherwise</returns>
        protected override IEnumerable <bool> DeleteObjectImpl(DataTableHandler tableHandler, IEnumerable <DataObject> dataObjects)
        {
            var success = new List <bool>();

            if (!dataObjects.Any())
            {
                return(success);
            }

            try
            {
                // Get Primary Keys
                var primary = tableHandler.FieldElementBindings.Where(bind => bind.PrimaryKey != null).ToArray();

                if (!primary.Any())
                {
                    throw new DatabaseException(string.Format("Table {0} has no primary key for deletion...", tableHandler.TableName));
                }

                var command = string.Format("DELETE FROM `{0}` WHERE {1}", tableHandler.TableName,
                                            string.Join(" AND ", primary.Select(col => string.Format("`{0}` = @{0}", col.ColumnName))));

                var objs       = dataObjects.ToArray();
                var parameters = objs.Select(obj => primary.Select(pk => new QueryParameter(string.Format("@{0}", pk.ColumnName), pk.GetValue(obj), pk.ValueType)));

                var affected        = ExecuteNonQueryImpl(command, parameters);
                var resultByObjects = affected.Select((result, index) => new { Result = result, DataObject = objs[index] });

                foreach (var result in resultByObjects)
                {
                    if (result.Result > 0)
                    {
                        result.DataObject.IsPersisted = false;
                        result.DataObject.IsDeleted   = true;
                        success.Add(true);
                    }
                    else
                    {
                        if (Log.IsErrorEnabled)
                        {
                            Log.ErrorFormat("Error deleting data object from table {0} Object = {1} --- keyvalue changed? {2}\n{3}", tableHandler.TableName, result.DataObject, command, Environment.StackTrace);
                        }

                        success.Add(false);
                    }
                }
            }
            catch (Exception e)
            {
                if (Log.IsErrorEnabled)
                {
                    Log.ErrorFormat("Error while deleting data object in table: {0}\n{1}", tableHandler.TableName, e);
                }
            }

            return(success);
        }
コード例 #8
0
        /// <summary>
        /// Retrieve a Collection of DataObjects Sets from database filtered by Parametrized Where Expression
        /// </summary>
        /// <param name="tableHandler">Table Handler for these DataObjects</param>
        /// <param name="whereExpression">Parametrized Where Expression</param>
        /// <param name="parameters">Parameters for filtering</param>
        /// <param name="isolation">Isolation Level</param>
        /// <returns>Collection of DataObjects Sets matching Parametrized Where Expression</returns>
        protected override IList <IList <DataObject> > SelectObjectsImpl(DataTableHandler tableHandler, string whereExpression, IEnumerable <IEnumerable <QueryParameter> > parameters, Transaction.IsolationLevel isolation)
        {
            var columns = tableHandler.FieldElementBindings.ToArray();

            string command = null;

            if (!string.IsNullOrEmpty(whereExpression))
            {
                command = string.Format(
                    "SELECT {0} FROM `{1}` WHERE {2}",
                    string.Join(", ", columns.Select(col => string.Format("`{0}`", col.ColumnName))),
                    tableHandler.TableName,
                    whereExpression);
            }
            else
            {
                command = string.Format(
                    "SELECT {0} FROM `{1}`",
                    string.Join(", ", columns.Select(col => string.Format("`{0}`", col.ColumnName))),
                    tableHandler.TableName);
            }

            var primary     = columns.FirstOrDefault(col => col.PrimaryKey != null);
            var dataObjects = new List <IList <DataObject> >();

            ExecuteSelectImpl(command, parameters, reader => {
                var list = new List <DataObject>();

                var data = new object[reader.FieldCount];
                while (reader.Read())
                {
                    reader.GetValues(data);
                    var obj = Activator.CreateInstance(tableHandler.ObjectType) as DataObject;

                    // Fill Object
                    var current = 0;
                    foreach (var column in columns)
                    {
                        DatabaseSetValue(obj, column, data[current]);
                        current++;
                    }

                    // Set Primary Key
                    if (primary != null)
                    {
                        obj.ObjectId = primary.GetValue(obj).ToString();
                    }

                    list.Add(obj);
                    obj.Dirty       = false;
                    obj.IsPersisted = true;
                }
                dataObjects.Add(list.ToArray());
            }, isolation);

            return(dataObjects.ToArray());
        }
コード例 #9
0
ファイル: ObjectDatabase.cs プロジェクト: tony898/DOLSharp
        protected void ReloadCache(string tableName)
        {
            DataTableHandler handler = TableDatasets[tableName];

            ICache cache = handler.Cache;

            foreach (object o in cache.Keys)
            {
                ReloadObject(cache[o] as DataObject);
            }
        }
コード例 #10
0
        /// <summary>
        /// Register Data Object Type if not already Registered
        /// </summary>
        /// <param name="dataObjectType">DataObject Type</param>
        public virtual void RegisterDataObject(Type dataObjectType)
        {
            var tableName = AttributesUtils.GetTableOrViewName(dataObjectType);

            if (TableDatasets.ContainsKey(tableName))
            {
                return;
            }

            var dataTableHandler = new DataTableHandler(dataObjectType);

            TableDatasets.Add(tableName, dataTableHandler);
        }
コード例 #11
0
        protected override IList <IList <DataObject> > MultipleSelectObjectsImpl(DataTableHandler tableHandler, IEnumerable <WhereClause> whereClauseBatch)
        {
            var columns = tableHandler.FieldElementBindings.ToArray();

            string selectFromExpression = string.Format("SELECT {0} FROM `{1}` ",
                                                        string.Join(", ", columns.Select(col => string.Format("`{0}`", col.ColumnName))),
                                                        tableHandler.TableName);

            var primary     = columns.FirstOrDefault(col => col.PrimaryKey != null);
            var dataObjects = new List <IList <DataObject> >();

            ExecuteSelectImpl(selectFromExpression, whereClauseBatch, reader => FillQueryResultList(reader, tableHandler, columns, primary, dataObjects));

            return(dataObjects.ToArray());
        }
コード例 #12
0
ファイル: DatabaseUtils.cs プロジェクト: NetDwarf/DOLSharp
        /// <summary>
        /// List all Unique Members of a DataTable, Using them for duplicate Matching.
        /// </summary>
        /// <param name="objectType">DataObject Type</param>
        /// <returns>List of MemberInfo having Unique Attributes</returns>
        public static ElementBinding[][] GetUniqueMembers(Type objectType)
        {
            var tableHandler = new DataTableHandler(objectType);

            var uniques = tableHandler.Table.Constraints.OfType <UniqueConstraint>().Where(constraint => !constraint.IsPrimaryKey)
                          .Select(constraint => constraint.Columns
                                  .Select(col => tableHandler.FieldElementBindings.Single(bind => bind.ColumnName.Equals(col.ColumnName, StringComparison.OrdinalIgnoreCase)))
                                  .ToArray());

            var primary = tableHandler.FieldElementBindings.Where(bind => bind.PrimaryKey != null &&
                                                                  !bind.PrimaryKey.AutoIncrement &&
                                                                  !bind.ColumnName.Equals(tableHandler.PrimaryKeyColumnName, StringComparison.OrdinalIgnoreCase))
                          .ToArray();

            return(new [] { primary }.Concat(uniques).ToArray());
        }
コード例 #13
0
		/// <summary>
		/// List all Unique Members of a DataTable, Using them for duplicate Matching.
		/// </summary>
		/// <param name="objectType">DataObject Type</param>
		/// <returns>List of MemberInfo having Unique Attributes</returns>
		public static ElementBinding[][] GetUniqueMembers(Type objectType)
		{
			var tableHandler = new DataTableHandler(objectType);
			
			var uniques = tableHandler.Table.Constraints.OfType<UniqueConstraint>().Where(constraint => !constraint.IsPrimaryKey)
				.Select(constraint => constraint.Columns
				        .Select(col => tableHandler.FieldElementBindings.Single(bind => bind.ColumnName.Equals(col.ColumnName, StringComparison.OrdinalIgnoreCase)))
				        .ToArray());
			
			var primary = tableHandler.FieldElementBindings.Where(bind => bind.PrimaryKey != null
			                                                      && !bind.PrimaryKey.AutoIncrement
			                                                      && !bind.ColumnName.Equals(string.Format("{0}_ID", tableHandler.TableName), StringComparison.OrdinalIgnoreCase))
				.ToArray();
			
			return new [] { primary }.Concat(uniques).ToArray();
		}
コード例 #14
0
ファイル: ObjectDatabase.cs プロジェクト: tony898/DOLSharp
        /// <summary>
        /// Selects object from the db and updates or adds entry in the pre-cache
        /// </summary>
        /// <param name="objectType"></param>
        /// <param name="key"></param>
        public bool UpdateInCache <TObject>(object key)
            where TObject : DataObject
        {
            MemberInfo[] members = typeof(TObject).GetMembers();
            var          ret     = (TObject)Activator.CreateInstance(typeof(TObject));

            string           tableName   = ret.TableName;
            DataTableHandler dth         = TableDatasets[tableName];
            string           whereClause = null;

            if (!dth.UsesPreCaching || key == null)
            {
                return(false);
            }

            // Escape PK value
            key = Escape(key.ToString());

            for (int i = 0; i < members.Length; i++)
            {
                object[] keyAttrib = members[i].GetCustomAttributes(typeof(PrimaryKey), true);
                if (keyAttrib.Length > 0)
                {
                    whereClause = "`" + members[i].Name + "` = '" + key + "'";
                    break;
                }
            }

            if (whereClause == null)
            {
                whereClause = "`" + ret.TableName + "_ID` = '" + key + "'";
            }

            var objs = SelectObjects <TObject>(whereClause);

            if (objs.Count > 0)
            {
                dth.SetPreCachedObject(key, objs[0]);
                return(true);
            }

            return(false);
        }
コード例 #15
0
ファイル: DatabaseUtils.cs プロジェクト: NetDwarf/DOLSharp
        /// <summary>
        /// List Remarkable Members of a DataTable, Using them for Default Ordering
        /// This includes non-generated Primary Key, Unique Field, and Indexed Fields (optionnaly)
        /// </summary>
        /// <param name="objectType">DataObject Type</param>
        /// <param name="forceIndexes">Returns Indexes even if enough Unique type have been gathered</param>
        /// <returns>List of Remkarkable MemberInfo of given DataObject</returns>
        public static ElementBinding[] GetRemarkableMembers(Type objectType, bool forceIndexes)
        {
            var tableHandler = new DataTableHandler(objectType);

            // Find unique Fields
            var remarkableMember = GetUniqueMembers(objectType);

            // We don't have enough fields, Try indexes !
            if (remarkableMember.Length < 1 || forceIndexes)
            {
                var indexes = tableHandler.Table.ExtendedProperties["INDEXES"] as Dictionary <string, DataColumn[]>;

                return(remarkableMember.SelectMany(constraint => constraint)
                       .Concat(indexes.SelectMany(index => index.Value).Select(col => tableHandler.FieldElementBindings
                                                                               .Single(bind => bind.ColumnName.Equals(col.ColumnName, StringComparison.OrdinalIgnoreCase))))
                       .ToArray());
            }

            return(remarkableMember.SelectMany(constraint => constraint).ToArray());
        }
コード例 #16
0
		/// <summary>
		/// List Remarkable Members of a DataTable, Using them for Default Ordering
		/// This includes non-generated Primary Key, Unique Field, and Indexed Fields (optionnaly)
		/// </summary>
		/// <param name="objectType">DataObject Type</param>
		/// <param name="forceIndexes">Returns Indexes even if enough Unique type have been gathered</param>
		/// <returns>List of Remkarkable MemberInfo of given DataObject</returns>
		public static ElementBinding[] GetRemarkableMembers(Type objectType, bool forceIndexes)
		{
			var tableHandler = new DataTableHandler(objectType);
			
			// Find unique Fields
			var remarkableMember = GetUniqueMembers(objectType);
			
			// We don't have enough fields, Try indexes !
			if (remarkableMember.Length < 1 || forceIndexes)
			{
				var indexes = tableHandler.Table.ExtendedProperties["INDEXES"] as Dictionary<string, DataColumn[]>;
				
				return remarkableMember.SelectMany(constraint => constraint)
					.Concat(indexes.SelectMany(index => index.Value).Select(col => tableHandler.FieldElementBindings
					                                                        .Single(bind => bind.ColumnName.Equals(col.ColumnName, StringComparison.OrdinalIgnoreCase))))
					.ToArray();
			}

			return remarkableMember.SelectMany(constraint => constraint).ToArray();
		}
コード例 #17
0
        /// <summary>
        /// Retrieve a Collection of DataObjects from database based on their primary key values
        /// </summary>
        /// <param name="tableHandler">Table Handler for the DataObjects to Retrieve</param>
        /// <param name="keys">Collection of Primary Key Values</param>
        /// <returns>Collection of DataObject with primary key matching values</returns>
        protected override IEnumerable <DataObject> FindObjectByKeyImpl(DataTableHandler tableHandler, IEnumerable <object> keys)
        {
            // Primary Key
            var primary = tableHandler.FieldElementBindings.Where(bind => bind.PrimaryKey != null)
                          .Select(bind => new { ColumnName = string.Format("`{0}`", bind.ColumnName), ParamName = string.Format("@{0}", bind.ColumnName) }).ToArray();

            if (!primary.Any())
            {
                throw new DatabaseException(string.Format("Table {0} has no primary key for finding by key...", tableHandler.TableName));
            }

            var whereClause = string.Format("{0}",
                                            string.Join(" AND ", primary.Select(col => string.Format("{0} = {1}", col.ColumnName, col.ParamName))));

            var keysArray  = keys.ToArray();
            var parameters = keysArray.Select(key => primary.Select(col => new QueryParameter(col.ParamName, key)));

            var objs = SelectObjectsImpl(tableHandler, whereClause, parameters, Transaction.IsolationLevel.DEFAULT);

            var resultByKeys = objs.Select((results, index) => new { Key = keysArray[index], DataObject = results.SingleOrDefault() });

            return(resultByKeys.Select(obj => obj.DataObject).ToArray());
        }
コード例 #18
0
ファイル: ObjectDatabase.cs プロジェクト: tony898/DOLSharp
        protected void DeleteFromCache(string tableName, DataObject obj)
        {
            DataTableHandler handler = TableDatasets[tableName];

            handler.SetCacheObject(obj.ObjectId, null);
        }
コード例 #19
0
ファイル: ObjectDatabase.cs プロジェクト: tony898/DOLSharp
        public void RegisterDataObject(Type objType)
        {
            if (TableDatasets.ContainsKey(GetTableOrViewName(objType)))
            {
                return;
            }

            bool       primaryKeySpecified    = false;
            bool       useAutoIncrementColumn = false;
            bool       relations          = false;
            MemberInfo primaryIndexMember = null;

            string tableName = GetTableOrViewName(objType);
            var    ds        = new DataSet();
            var    table     = new DataTable(tableName);

            MemberInfo[] myMembers = objType.GetMembers();

            for (int i = 0; i < myMembers.Length; i++)
            {
                //object[] myAttributes = myMembers[i].GetCustomAttributes(true);
                //object[] myAttributes = myMembers[i].GetCustomAttributes(typeof(DOL.Database.Attributes.DataElement), true);

                object[] myAttributes = myMembers[i].GetCustomAttributes(typeof(PrimaryKey), true);

                if (myAttributes.Length > 0)
                {
                    primaryKeySpecified = true;
                    if (myMembers[i] is PropertyInfo)
                    {
                        table.Columns.Add(myMembers[i].Name, ((PropertyInfo)myMembers[i]).PropertyType);
                    }
                    else
                    {
                        table.Columns.Add(myMembers[i].Name, ((FieldInfo)myMembers[i]).FieldType);
                    }

                    table.Columns[myMembers[i].Name].AutoIncrement = ((PrimaryKey)myAttributes[0]).AutoIncrement;

                    useAutoIncrementColumn = table.Columns[myMembers[i].Name].AutoIncrement;

                    var index = new DataColumn[1];
                    index[0]           = table.Columns[myMembers[i].Name];
                    primaryIndexMember = myMembers[i];
                    table.PrimaryKey   = index;
                    continue;
                }

                myAttributes = myMembers[i].GetCustomAttributes(typeof(DataElement), true);

                if (myAttributes.Length > 0)
                {
                    //if(myAttributes[0] is Attributes.DataElement)
                    //{
                    if (myMembers[i] is PropertyInfo)
                    {
                        table.Columns.Add(myMembers[i].Name, ((PropertyInfo)myMembers[i]).PropertyType);
                    }
                    else
                    {
                        table.Columns.Add(myMembers[i].Name, ((FieldInfo)myMembers[i]).FieldType);
                    }

                    table.Columns[myMembers[i].Name].AllowDBNull = ((DataElement)myAttributes[0]).AllowDbNull;
                    if (((DataElement)myAttributes[0]).Unique)
                    {
                        table.Constraints.Add(new UniqueConstraint("UNIQUE_" + myMembers[i].Name, table.Columns[myMembers[i].Name]));
                    }

                    if (((DataElement)myAttributes[0]).IndexColumns != string.Empty)
                    {
                        table.Columns[myMembers[i].Name].ExtendedProperties.Add("INDEX", true);
                        table.Columns[myMembers[i].Name].ExtendedProperties.Add("INDEXCOLUMNS", ((DataElement)myAttributes[0]).IndexColumns);
                    }
                    else if (((DataElement)myAttributes[0]).Index)
                    {
                        table.Columns[myMembers[i].Name].ExtendedProperties.Add("INDEX", true);
                    }

                    if (((DataElement)myAttributes[0]).Varchar > 0)
                    {
                        table.Columns[myMembers[i].Name].ExtendedProperties.Add("VARCHAR", ((DataElement)myAttributes[0]).Varchar);
                    }

                    //if(myAttributes[0] is Attributes.PrimaryKey)
                    myAttributes = GetRelationAttributes(myMembers[i]);

                    //if(myAttributes[0] is Attributes.Relation)
                    if (myAttributes.Length > 0)
                    {
                        relations = true;
                    }
                }
            }

            if (useAutoIncrementColumn == false)
            {
                // We define the Tablename_ID column that will always contain a generated unique ID

                DataColumn idColumn = table.Columns.Add(tableName + "_ID", typeof(string));

                if (primaryKeySpecified)
                {
                    // if another primary key is defined on this table but the TableName_ID column is still being used then force
                    // the creation of a unique index on the the TableName_ID column
                    table.Constraints.Add(new UniqueConstraint(idColumn.ColumnName, idColumn));
                }
            }

            if (primaryKeySpecified == false)
            {
                var index = new DataColumn[1];
                index[0]         = table.Columns[tableName + "_ID"];
                table.PrimaryKey = index;
            }

            if (Connection.IsSQLConnection)
            {
                Connection.CheckOrCreateTable(table);
            }

            ds.DataSetName        = tableName;
            ds.EnforceConstraints = true;
            ds.CaseSensitive      = false;
            ds.Tables.Add(table);

            var dth = new DataTableHandler(ds);

            dth.HasRelations   = relations;
            dth.UsesPreCaching = DataObject.GetPreCachedFlag(objType);

            TableDatasets.Add(tableName, dth);

            //if (dth.UsesPreCaching && Connection.IsSQLConnection)
            //{
            //    // not useful for xml connection
            //    if (Log.IsDebugEnabled)
            //        Log.Debug("Precaching of " + table.TableName + "...");

            //    var objects = SQLSelectObjects<TObject>("");

            //    object key;
            //    for (int i = 0; i < objects.Length; i++)
            //    {
            //        key = null;
            //        if (primaryIndexMember == null)
            //        {
            //            key = objects[i].ObjectId;
            //        }
            //        else
            //        {
            //            if (primaryIndexMember is PropertyInfo)
            //            {
            //                key = ((PropertyInfo) primaryIndexMember).GetValue(objects[i], null);
            //            }
            //            else if (primaryIndexMember is FieldInfo)
            //            {
            //                key = ((FieldInfo) primaryIndexMember).GetValue(objects[i]);
            //            }
            //        }
            //        if (key != null)
            //        {
            //            dth.SetPreCachedObject(key, objects[i]);
            //        }
            //        else
            //        {
            //            if (Log.IsErrorEnabled)
            //                Log.Error("Primary key is null! " + ((primaryIndexMember != null) ? primaryIndexMember.Name : ""));
            //        }
            //    }

            //    if (Log.IsDebugEnabled)
            //        Log.Debug("Precaching of " + table.TableName + " finished!");
            //}
        }
コード例 #20
0
 /// <summary>
 /// Deletes DataObjects from the database.
 /// </summary>
 /// <param name="dataObjects">DataObjects to delete from the database</param>
 /// <param name="tableHandler">Table Handler for the DataObjects Collection</param>
 /// <returns>True if objects were deleted successfully; false otherwise</returns>
 protected abstract IEnumerable <bool> DeleteObjectImpl(DataTableHandler tableHandler, IEnumerable <DataObject> dataObjects);
コード例 #21
0
 /// <summary>
 /// Retrieve a Collection of DataObjects Sets from database filtered by Parametrized Where Expression
 /// </summary>
 /// <param name="tableHandler">Table Handler for these DataObjects</param>
 /// <param name="whereExpression">Parametrized Where Expression</param>
 /// <param name="parameters">Parameters for filtering</param>
 /// <param name="isolation">Isolation Level</param>
 /// <returns>Collection of DataObjects Sets matching Parametrized Where Expression</returns>
 protected abstract IList <IList <DataObject> > SelectObjectsImpl(DataTableHandler tableHandler, string whereExpression, IEnumerable <IEnumerable <QueryParameter> > parameters, Transaction.IsolationLevel isolation);
コード例 #22
0
 protected abstract IList <IList <DataObject> > MultipleSelectObjectsImpl(DataTableHandler tableHandler, IEnumerable <WhereClause> whereClauseBatch);
コード例 #23
0
        /// <summary>
        /// Delete Relations Objects attached to DataObjects
        /// </summary>
        /// <param name="tableHandler">TableHandler for Source DataObjects Relation</param>
        /// <param name="dataObjects">DataObjects to parse</param>
        /// <returns>True if all Relations were deleted</returns>
        public bool DeleteObjectRelations(DataTableHandler tableHandler, IEnumerable <DataObject> dataObjects)
        {
            var success = true;

            foreach (var relation in tableHandler.ElementBindings.Where(bind => bind.Relation != null && bind.Relation.AutoDelete))
            {
                // Relation Check
                var remoteHandler = GetTableHandler(relation.ValueType);
                if (remoteHandler == null)
                {
                    if (log.IsErrorEnabled)
                    {
                        log.ErrorFormat("DeleteObjectRelations: Remote Table for Type ({0}) is not registered !", relation.ValueType.FullName);
                    }
                    success = false;
                    continue;
                }

                // Check For Array Type
                var groups = relation.ValueType.HasElementType
                                        ? dataObjects.Select(obj => new { Source = obj, Enumerable = (IEnumerable <DataObject>)relation.GetValue(obj) })
                             .Where(obj => obj.Enumerable != null).Select(obj => obj.Enumerable.Select(rel => new { Local = obj.Source, Remote = rel }))
                             .SelectMany(obj => obj).Where(obj => obj.Remote != null && obj.Remote.IsPersisted)
                                        : dataObjects.Select(obj => new { Local = obj, Remote = (DataObject)relation.GetValue(obj) }).Where(obj => obj.Remote != null && obj.Remote.IsPersisted);

                foreach (var grp in groups.GroupBy(obj => obj.Remote.AllowDelete))
                {
                    if (grp.Key)
                    {
                        var objs    = grp.ToArray();
                        var results = DeleteObjectImpl(remoteHandler, objs.Select(obj => obj.Remote));

                        var resultsByObjs = results.Select((result, index) => new { Success = result, RelObject = objs[index] });

                        foreach (var resultGrp in resultsByObjs.GroupBy(obj => obj.Success))
                        {
                            if (resultGrp.Key)
                            {
                                // Delete in Precache if tablehandler use it
                                if (remoteHandler.UsesPreCaching)
                                {
                                    var primary = remoteHandler.PrimaryKey;
                                    if (primary != null)
                                    {
                                        foreach (var successObj in resultGrp.Select(obj => obj.RelObject.Remote))
                                        {
                                            remoteHandler.DeletePreCachedObject(primary.GetValue(successObj));
                                        }
                                    }
                                }
                            }
                            else
                            {
                                foreach (var result in resultGrp)
                                {
                                    if (log.IsErrorEnabled)
                                    {
                                        log.ErrorFormat("DeleteObjectRelations: Deleting Relation ({0}) of DataObject ({1}) failed for Object ({2})",
                                                        relation.ValueType, result.RelObject.Local, result.RelObject.Remote);
                                    }
                                }
                                success = false;
                            }
                        }
                    }
                    else
                    {
                        // Objects that could not be deleted can lead to failure
                        if (log.IsWarnEnabled)
                        {
                            foreach (var obj in grp)
                            {
                                log.WarnFormat("DeleteObjectRelations: DataObject ({0}) not allowed to be deleted from Database", obj);
                            }
                        }
                        success = false;
                    }
                }
            }
            return(success);
        }
コード例 #24
0
        /// <summary>
        /// Populate or Refresh Object Relation Implementation
        /// </summary>
        /// <param name="relationBind">Element Binding for Relation Field</param>
        /// <param name="localBind">Local Binding for Value Match</param>
        /// <param name="remoteBind">Remote Binding for Column Match</param>
        /// <param name="remoteHandler">Remote Table Handler for Cache Retrieving</param>
        /// <param name="dataObjects">DataObjects to Populate</param>
        protected virtual void FillObjectRelationsImpl(ElementBinding relationBind, ElementBinding localBind, ElementBinding remoteBind, DataTableHandler remoteHandler, IEnumerable <DataObject> dataObjects)
        {
            var type          = relationBind.ValueType;
            var isElementType = false;

            if (type.HasElementType)
            {
                type          = type.GetElementType();
                isElementType = true;
            }

            var objects = dataObjects.ToArray();
            IEnumerable <IEnumerable <DataObject> > objsResults = null;

            // Handle Cache Search if relevent or use a Select Query
            if (remoteHandler.UsesPreCaching)
            {
                // Search with Primary Key or use a Where Clause
                if (remoteHandler.PrimaryKeys.All(pk => pk.ColumnName.Equals(remoteBind.ColumnName, StringComparison.OrdinalIgnoreCase)))
                {
                    objsResults = objects.Select(obj => {
                        var local = localBind.GetValue(obj);
                        if (local == null)
                        {
                            return(new DataObject[0]);
                        }

                        var retrieve = remoteHandler.GetPreCachedObject(local);
                        if (retrieve == null)
                        {
                            return(new DataObject[0]);
                        }

                        return(new [] { retrieve });
                    });
                }
                else
                {
                    objsResults = objects
                                  .Select(obj => remoteHandler.SearchPreCachedObjects(rem => {
                        var local  = localBind.GetValue(obj);
                        var remote = remoteBind.GetValue(rem);
                        if (local == null || remote == null)
                        {
                            return(false);
                        }

                        if (localBind.ValueType == typeof(string) || remoteBind.ValueType == typeof(string))
                        {
                            return(remote.ToString().Equals(local.ToString(), StringComparison.OrdinalIgnoreCase));
                        }

                        return(remote == local);
                    }));
                }
            }
            else
            {
                var whereClauses = objects.Select(obj => DB.Column(remoteBind.ColumnName).IsEqualTo(localBind.GetValue(obj)));
                objsResults = MultipleSelectObjectsImpl(remoteHandler, whereClauses);
            }

            var resultByObjs = objsResults.Select((obj, index) => new { DataObject = objects[index], Results = obj }).ToArray();

            // Store Relations
            foreach (var result in resultByObjs)
            {
                if (isElementType)
                {
                    if (result.Results.Any())
                    {
                        MethodInfo castMethod    = typeof(Enumerable).GetMethod("OfType").MakeGenericMethod(type);
                        MethodInfo methodToArray = typeof(Enumerable).GetMethod("ToArray").MakeGenericMethod(type);
                        relationBind.SetValue(result.DataObject, methodToArray.Invoke(null, new object[] { castMethod.Invoke(null, new object[] { result.Results }) }));
                    }
                    else
                    {
                        relationBind.SetValue(result.DataObject, null);
                    }
                }
                else
                {
                    relationBind.SetValue(result.DataObject, result.Results.SingleOrDefault());
                }
            }

            // Fill Sub Relations
            FillObjectRelations(resultByObjs.SelectMany(result => result.Results), false);
        }
コード例 #25
0
        /// <summary>
        /// Adds new DataObjects to the database.
        /// </summary>
        /// <param name="dataObjects">DataObjects to add to the database</param>
        /// <param name="tableHandler">Table Handler for the DataObjects Collection</param>
        /// <returns>True if objects were added successfully; false otherwise</returns>
        protected override IEnumerable <bool> AddObjectImpl(DataTableHandler tableHandler, IEnumerable <DataObject> dataObjects)
        {
            var success = new List <bool>();

            if (!dataObjects.Any())
            {
                return(success);
            }

            try
            {
                // Check Primary Keys
                var usePrimaryAutoInc = tableHandler.FieldElementBindings.Any(bind => bind.PrimaryKey != null && bind.PrimaryKey.AutoIncrement);

                // Columns
                var columns = tableHandler.FieldElementBindings.Where(bind => bind.PrimaryKey == null || !bind.PrimaryKey.AutoIncrement)
                              .Select(bind => new { Binding = bind, ColumnName = string.Format("`{0}`", bind.ColumnName), ParamName = string.Format("@{0}", bind.ColumnName) }).ToArray();

                // Prepare SQL Query
                var command = string.Format("INSERT INTO `{0}` ({1}) VALUES({2})", tableHandler.TableName,
                                            string.Join(", ", columns.Select(col => col.ColumnName)),
                                            string.Join(", ", columns.Select(col => col.ParamName)));

                var objs = dataObjects.ToArray();

                // Init Object Id GUID
                foreach (var obj in objs.Where(obj => obj.ObjectId == null))
                {
                    obj.ObjectId = IDGenerator.GenerateID();
                }

                // Build Parameters
                var parameters = objs.Select(obj => columns.Select(col => new QueryParameter(col.ParamName, col.Binding.GetValue(obj))));

                // Primary Key Auto Inc Handler
                if (usePrimaryAutoInc)
                {
                    var lastId = ExecuteScalarImpl(command, parameters, true);

                    var binding         = tableHandler.FieldElementBindings.First(bind => bind.PrimaryKey != null && bind.PrimaryKey.AutoIncrement);
                    var resultByObjects = lastId.Select((result, index) => new { Result = Convert.ToInt64(result), DataObject = objs[index] });

                    foreach (var result in resultByObjects)
                    {
                        if (result.Result > 0)
                        {
                            DatabaseSetValue(result.DataObject, binding, result.Result);
                            result.DataObject.ObjectId    = result.Result.ToString();
                            result.DataObject.Dirty       = false;
                            result.DataObject.IsPersisted = true;
                            result.DataObject.IsDeleted   = false;
                            success.Add(true);
                        }
                        else
                        {
                            if (Log.IsErrorEnabled)
                            {
                                Log.ErrorFormat("Error adding data object into {0} Object = {1}, UsePrimaryAutoInc, Query = {2}", tableHandler.TableName, result.DataObject, command);
                            }

                            success.Add(false);
                        }
                    }
                }
                else
                {
                    var affected        = ExecuteNonQueryImpl(command, parameters);
                    var resultByObjects = affected.Select((result, index) => new { Result = result, DataObject = objs[index] });

                    foreach (var result in resultByObjects)
                    {
                        if (result.Result > 0)
                        {
                            result.DataObject.Dirty       = false;
                            result.DataObject.IsPersisted = true;
                            result.DataObject.IsDeleted   = false;
                            success.Add(true);
                        }
                        else
                        {
                            if (Log.IsErrorEnabled)
                            {
                                Log.ErrorFormat("Error adding data object into {0} Object = {1} Query = {2}", tableHandler.TableName, result.DataObject, command);
                            }

                            success.Add(false);
                        }
                    }
                }
            }
            catch (Exception e)
            {
                if (Log.IsErrorEnabled)
                {
                    Log.ErrorFormat("Error while adding data objects in table: {0}\n{1}", tableHandler.TableName, e);
                }
            }

            return(success);
        }
コード例 #26
0
		/// <summary>
		/// Check the XML Package Given for Replace or Insert Apply
		/// </summary>
		/// <param name="xml">FileInfo for XML Package</param>
		/// <param name="replace">Enforce Replace Mode</param>
		/// <returns>True if success, False if any errors</returns>
		private bool CheckXMLPackageAndApply(FileInfo xml, bool replace)
		{
			
			var packageName = string.Format("{0}{1}{2}", xml.Directory.Name, Path.DirectorySeparatorChar, xml.Name);
			
			if (log.IsInfoEnabled)
				log.InfoFormat("Auto Loading XML File {0} into Database (Mode:{1})", packageName, replace ? "Replace" : "Insert");
			
			var result = true;
			
			try
			{
				//Load the XML File
				var xmlTable = LoaderUnloaderXML.LoadXMLTableFromFile(xml);
				if (xmlTable.Length > 0)
				{
					// Guess Object Type
					var xmlType = xmlTable.First().GetType();
					var tableHandler = new DataTableHandler(xmlType);
					
					// Find unique Fields
					var uniqueMember = DatabaseUtils.GetUniqueMembers(xmlType);
					
					// Get all object "Method" Through Reflection
					var classMethod = GameServer.Database.GetType().GetMethod("SelectAllObjects", Type.EmptyTypes);
					var genericMethod = classMethod.MakeGenericMethod(xmlType);
					var existingObjects = ((IEnumerable)genericMethod.Invoke(GameServer.Database, new object[]{})).Cast<DataObject>().ToArray();
					
					// Store Object to Alter
					var toDelete = new ConcurrentBag<DataObject>();
					var toAdd = new ConcurrentBag<DataObject>();
					
					// Check if an Object already exists
					xmlTable.AsParallel().ForAll(obj => {
					                             	// Check if Exists Compare Unique and Non-Generated Primary Keys
					                             	var exists = existingObjects
					                             		.FirstOrDefault(entry => uniqueMember
					                             		                .Any(constraint => constraint
					                             		                     .All(bind => bind.ValueType == typeof(string)
					                             		                          ? bind.GetValue(entry).ToString().Equals(bind.GetValue(obj).ToString(), StringComparison.OrdinalIgnoreCase)
					                             		                          : bind.GetValue(entry) == bind.GetValue(obj)))
					                             		               );
					                             	
					                             	if (exists != null)
					                             	{
					                             		if (replace)
					                             		{
					                             			// Delete First
					                             			toDelete.Add(exists);
					                             			toAdd.Add(obj);
					                             		}
					                             		// Silently ignore duplicate inserts only...
					                             	}
					                             	else
					                             	{
					                             		toAdd.Add(obj);
					                             	}
					                             });
					// Delete First
					foreach (var obj in toDelete)
						obj.AllowDelete = true;
					
					GameServer.Database.DeleteObject(toDelete);
					
					// Then Insert
					var previousAllowAdd = toAdd.Select(obj => obj.AllowAdd).ToArray();
					foreach (var obj in toAdd)
						obj.AllowAdd = true;
					
					GameServer.Database.AddObject(toAdd);
					
					// Reset Allow Add Flag
					var current = 0;
					foreach (var obj in toAdd)
					{
						obj.AllowAdd = previousAllowAdd[current];
						current++;
					}
				}
				else
				{
					if (log.IsWarnEnabled)
						log.WarnFormat("XML Package {0} Found Empty, may be a parsing Error...", packageName);
					result = false;
				}
			}
			catch (Exception e)
			{
				if (log.IsErrorEnabled)
					log.ErrorFormat("Error While Loading XML Package {0} into Database (Mode:{1}) - {2}", packageName, replace ? "Replace" : "Insert", e);
				result = false;
			}
			
			return result;
		}
コード例 #27
0
        /// <summary>
        /// Saves Persisted DataObjects into Database
        /// </summary>
        /// <param name="dataObjects">DataObjects to Save</param>
        /// <param name="tableHandler">Table Handler for the DataObjects Collection</param>
        /// <returns>True if objects were saved successfully; false otherwise</returns>
        protected override IEnumerable <bool> SaveObjectImpl(DataTableHandler tableHandler, IEnumerable <DataObject> dataObjects)
        {
            var success = new List <bool>();

            if (!dataObjects.Any())
            {
                return(success);
            }

            try
            {
                // Columns Filtering out ReadOnly
                var columns = tableHandler.FieldElementBindings.Where(bind => bind.PrimaryKey == null && bind.ReadOnly == null)
                              .Select(bind => new { Binding = bind, ColumnName = string.Format("`{0}`", bind.ColumnName), ParamName = string.Format("@{0}", bind.ColumnName) }).ToArray();
                // Primary Key
                var primary = tableHandler.FieldElementBindings.Where(bind => bind.PrimaryKey != null)
                              .Select(bind => new { Binding = bind, ColumnName = string.Format("`{0}`", bind.ColumnName), ParamName = string.Format("@{0}", bind.ColumnName) }).ToArray();

                if (!primary.Any())
                {
                    throw new DatabaseException(string.Format("Table {0} has no primary key for saving...", tableHandler.TableName));
                }

                var command = string.Format("UPDATE `{0}` SET {1} WHERE {2}", tableHandler.TableName,
                                            string.Join(", ", columns.Select(col => string.Format("{0} = {1}", col.ColumnName, col.ParamName))),
                                            string.Join(" AND ", primary.Select(col => string.Format("{0} = {1}", col.ColumnName, col.ParamName))));

                var objs       = dataObjects.ToArray();
                var parameters = objs.Select(obj => columns.Concat(primary).Select(col => new QueryParameter(col.ParamName, col.Binding.GetValue(obj))));

                var affected        = ExecuteNonQueryImpl(command, parameters);
                var resultByObjects = affected.Select((result, index) => new { Result = result, DataObject = objs[index] });

                foreach (var result in resultByObjects)
                {
                    if (result.Result > 0)
                    {
                        result.DataObject.Dirty       = false;
                        result.DataObject.IsPersisted = true;
                        success.Add(true);
                    }
                    else
                    {
                        if (Log.IsErrorEnabled)
                        {
                            if (result.Result < 0)
                            {
                                Log.ErrorFormat("Error saving data object in table {0} Object = {1} --- constraint failed? {2}", tableHandler.TableName, result.DataObject, command);
                            }
                            else
                            {
                                Log.ErrorFormat("Error saving data object in table {0} Object = {1} --- keyvalue changed? {2}\n{3}", tableHandler.TableName, result.DataObject, command, Environment.StackTrace);
                            }
                        }
                        success.Add(false);
                    }
                }
            }
            catch (Exception e)
            {
                if (Log.IsErrorEnabled)
                {
                    Log.ErrorFormat("Error while saving data object in table: {0}\n{1}", tableHandler.TableName, e);
                }
            }

            return(success);
        }
コード例 #28
0
 /// <summary>
 /// Retrieve a Collection of DataObjects from database based on their primary key values
 /// </summary>
 /// <param name="tableHandler">Table Handler for the DataObjects to Retrieve</param>
 /// <param name="keys">Collection of Primary Key Values</param>
 /// <returns>Collection of DataObject with primary key matching values</returns>
 protected abstract IEnumerable <DataObject> FindObjectByKeyImpl(DataTableHandler tableHandler, IEnumerable <object> keys);
コード例 #29
0
 /// <summary>
 /// Check for Table Existence, Create or Alter accordingly
 /// </summary>
 /// <param name="table">Table Handler</param>
 public abstract void CheckOrCreateTableImpl(DataTableHandler table);
コード例 #30
0
		public void TestMultiIndexesDataObject()
		{
			var dth = new DataTableHandler(typeof(TestTableWithMultiIndexes));
			Assert.DoesNotThrow(() => Database.CheckOrCreateTableImpl(dth), "Registering Test Table with Overlapping Indexes should not Throw exceptions.");
		}