예제 #1
0
        public void TestAllAvailableTables()
        {
            foreach (Assembly assembly in new [] { typeof(GS.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", Array.Empty <Type>()).MakeGenericMethod(type);
                        object objs      = null;
                        Assert.DoesNotThrow(() => { objs = selectall.Invoke(Database, Array.Empty <object>()); }, "Registered tables should not Throw Exception on Select All... (Failed on Type {0})", type);
                        Assert.IsNotNull(objs);
                    }
                }
            }
        }
예제 #2
0
        /// <summary>
        /// Get Database Column Definition for ElementBinding
        /// </summary>
        /// <param name="bind">ElementBinding for Column Definition</param>
        /// <param name="table">DataTableHanlder for Special cases</param>
        /// <returns>Column Definitnion string.</returns>
        protected virtual string GetColumnDefinition(ElementBinding bind, DataTableHandler table)
        {
            string type       = GetDatabaseType(bind, table);
            string defaultDef = null;

            // Check for Default Value depending on Constraints and Type
            if (bind.PrimaryKey != null && bind.PrimaryKey.AutoIncrement)
            {
                defaultDef = "NOT NULL PRIMARY KEY AUTOINCREMENT";
            }
            else if (bind.DataElement != null && bind.DataElement.AllowDbNull)
            {
                defaultDef = "DEFAULT NULL";
            }
            else if (bind.ValueType == typeof(DateTime))
            {
                defaultDef = "NOT NULL DEFAULT '2000-01-01 00:00:00'";
            }
            else if (bind.ValueType == typeof(string))
            {
                defaultDef = "NOT NULL DEFAULT ''";
            }
            else
            {
                defaultDef = "NOT NULL DEFAULT 0";
            }

            // Force Case Insensitive Text Field to Match MySQL Behavior
            if (bind.ValueType == typeof(string))
            {
                defaultDef = string.Format("{0} {1}", defaultDef, "COLLATE NOCASE");
            }

            return(string.Format("`{0}` {1} {2}", bind.ColumnName, type, defaultDef));
        }
예제 #3
0
        static void RunOp()
        {
            PageCounter counter = new PageCounter();
            if (operationMode == 1)
            {
                DataTableHandler dteHandler = new DataTableHandler();
                DateTime Start = new DateTime(2015, 7, 01);
                DateTime End = new DateTime(2015, 7, 02);
                DataTable PDFs = SQLHandler.getListOfPDFs(Start, End);
                counter.CountPagesFromDB(PDFs);
                Console.WriteLine("Enter the path and name of the file");
                string fullPath = Console.ReadLine();
                dteHandler.loadExcel(PDFs, fullPath);

                Console.WriteLine("File Written");
            }
            else if (operationMode == 2)
            {
                Console.WriteLine("Enter the fullpath of a pdf file: ");
                string fullFilePath = Console.ReadLine();

                Console.WriteLine("Page count for file: " + counter.CountPages(fullFilePath));
                Console.ReadKey();
            }
        }
예제 #4
0
        /// <summary>
        /// Get Database Column Definition for ElementBinding
        /// </summary>
        /// <param name="bind">ElementBinding for Column Definition</param>
        /// <param name="table">DataTableHanlder for Special cases</param>
        /// <returns>Column Definitnion string.</returns>
        protected virtual string GetColumnDefinition(ElementBinding bind, DataTableHandler table)
        {
            string type       = GetDatabaseType(bind, table);
            string defaultDef = null;

            Type[] numberTypes =
            {
                typeof(int),    typeof(byte),  typeof(bool), typeof(long), typeof(short),
                typeof(ushort), typeof(ulong), typeof(uint), typeof(double)
            };

            // Check for Default Value depending on Constraints and Type
            if (bind.PrimaryKey != null && bind.PrimaryKey.AutoIncrement)
            {
                defaultDef = "NOT NULL AUTO_INCREMENT";
            }
            else if (bind.DataElement != null && bind.DataElement.AllowDbNull)
            {
                defaultDef = "DEFAULT NULL";
            }
            else if (bind.ValueType == typeof(DateTime))
            {
                defaultDef = "NOT NULL DEFAULT '2000-01-01 00:00:00'";
            }
            else if (numberTypes.Contains(bind.ValueType))
            {
                defaultDef = "NOT NULL DEFAULT 0";
            }
            else
            {
                defaultDef = "NOT NULL";
            }

            return(string.Format("`{0}` {1} {2}", bind.ColumnName, type, defaultDef));
        }
예제 #5
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");
 }
예제 #6
0
        /// <summary>
        /// Create a New Table from DataTableHandler Definition
        /// </summary>
        /// <param name="table">DataTableHandler Definition to Create in Database</param>
        protected void CreateTable(DataTableHandler table)
        {
            ExecuteNonQueryImpl(GetTableDefinition(table));

            foreach (var commands in GetIndexesDefinition(table))
            {
                ExecuteNonQueryImpl(commands);
            }
        }
예제 #7
0
        /// <summary>
        /// Check for Table Existence, Create or Alter accordingly
        /// </summary>
        /// <param name="table">Table Handler</param>
        public override void CheckOrCreateTableImpl(DataTableHandler table)
        {
            var currentTableColumns = new List <TableRowBindind>();

            try
            {
                ExecuteSelectImpl(
                    string.Format("PRAGMA TABLE_INFO(`{0}`)", table.TableName),
                    reader =>
                {
                    while (reader.Read())
                    {
                        var column    = reader.GetString(1);
                        var colType   = reader.GetString(2);
                        var allowNull = !reader.GetBoolean(3);
                        var primary   = reader.GetInt64(5) > 0;
                        currentTableColumns.Add(new TableRowBindind(column, colType, allowNull, primary));
                        if (log.IsDebugEnabled)
                        {
                            log.DebugFormat("CheckOrCreateTable: Found Column {0} in existing table {1}", column, table.TableName);
                        }
                    }
                    if (log.IsDebugEnabled)
                    {
                        log.DebugFormat("CheckOrCreateTable: {0} columns existing in table {1}", currentTableColumns.Count, table.TableName);
                    }
                }, IsolationLevel.DEFAULT);
            }
            catch (Exception e)
            {
                if (log.IsDebugEnabled)
                {
                    log.Debug("CheckOrCreateTable: ", e);
                }
            }

            // Create Table or Alter Table
            if (currentTableColumns.Any())
            {
                AlterTable(currentTableColumns, table);
            }
            else
            {
                if (log.IsWarnEnabled)
                {
                    log.WarnFormat("Table {0} doesn't exist, creating it...", table.TableName);
                }

                CreateTable(table);
            }
        }
예제 #8
0
        /// <summary>
        /// Check for Table Existence, Create or Alter accordingly
        /// </summary>
        /// <param name="table">Table Handler</param>
        public override void CheckOrCreateTableImpl(DataTableHandler table)
        {
            var currentTableColumns = new List <TableRowBindind>();

            try
            {
                ExecuteSelectImpl(string.Format("DESCRIBE `{0}`", table.TableName),
                                  new[] { Array.Empty <QueryParameter>() },
                                  reader =>
                {
                    while (reader.Read())
                    {
                        var column    = reader.GetString(0);
                        var colType   = reader.GetString(1);
                        var allowNull = reader.GetString(2).ToLower() == "yes";
                        var primary   = reader.GetString(3).ToLower() == "pri";
                        currentTableColumns.Add(new TableRowBindind(column, colType, allowNull, primary));
                        if (log.IsDebugEnabled)
                        {
                            log.DebugFormat("CheckOrCreateTable: Found Column {0} in existing table {1}", column, table.TableName);
                        }
                    }
                    if (log.IsDebugEnabled)
                    {
                        log.DebugFormat("CheckOrCreateTable: {0} columns existing in table {1}", currentTableColumns.Count, table.TableName);
                    }
                });
            }
            catch (Exception e)
            {
                if (log.IsDebugEnabled)
                {
                    log.Debug("CheckOrCreateTable: ", e);
                }
            }

            // Create Table or Alter Table
            if (currentTableColumns.Any())
            {
                AlterTable(currentTableColumns, table);
            }
            else
            {
                if (log.IsWarnEnabled)
                {
                    log.WarnFormat("Table {0} doesn't exist, creating it...", table.TableName);
                }

                CreateTable(table);
            }
        }
예제 #9
0
        /// <summary>
        /// Finds an object in the database by primary key.
        /// </summary>
        /// <param name="objectType">the type of object to retrieve</param>
        /// <param name="key">the value of the primary key to search for</param>
        /// <returns>a <see cref="DataObject" /> instance representing a row with the given primary key value; null if the key value does not exist</returns>
        protected override TObject FindObjectByKeyImpl <TObject>(object key)
        {
            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)
            {
                DataObject obj = dth.GetPreCachedObject(key);
                if (obj != null)
                {
                    return(obj as TObject);
                }
            }

            // 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 = SelectObjectsImpl <TObject>(whereClause, Transaction.IsolationLevel.DEFAULT);

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

            return(null);
        }
예제 #10
0
        /// <summary>
        /// Helper Method to build Table Indexes Definition String
        /// </summary>
        /// <param name="table"></param>
        /// <returns></returns>
        protected IEnumerable <string> GetIndexesDefinition(DataTableHandler table)
        {
            // Indexes and Constraints
            var uniqueFields = table.Table.Constraints.OfType <UniqueConstraint>().Where(cstrnt => !cstrnt.IsPrimaryKey)
                               .Select(cstrnt => string.Format("CREATE UNIQUE INDEX IF NOT EXISTS `{0}` ON `{2}` ({1})", cstrnt.ConstraintName,
                                                               string.Join(", ", cstrnt.Columns.Select(col => string.Format("`{0}`", col.ColumnName))),
                                                               table.TableName));

            var indexes = table.Table.ExtendedProperties["INDEXES"] as Dictionary <string, DataColumn[]>;

            var indexesFields = indexes == null ? new string[] { }
                                : indexes.Select(index => string.Format("CREATE INDEX IF NOT EXISTS `{0}` ON `{2}` ({1})", index.Key,
                                                                        string.Join(", ", index.Value.Select(col => string.Format("`{0}`", col.ColumnName))),
                                                                        table.TableName));

            return(uniqueFields.Concat(indexesFields));
        }
예제 #11
0
        /// <summary>
        /// Helper Method to build Table Definition String
        /// </summary>
        /// <param name="table"></param>
        /// <returns></returns>
        protected string GetTableDefinition(DataTableHandler table)
        {
            var columnDef = table.FieldElementBindings
                            .Select(bind => GetColumnDefinition(bind, table));

            var primaryFields = new string[] {};

            if (!table.FieldElementBindings.Any(bind => bind.PrimaryKey != null && bind.PrimaryKey.AutoIncrement))
            {
                primaryFields = new [] { string.Format("PRIMARY KEY ({0})",
                                                       string.Join(", ", table.Table.PrimaryKey.Select(pk => string.Format("`{0}`", pk.ColumnName)))) }
            }
            ;

            // Create Table First
            return(string.Format("CREATE TABLE IF NOT EXISTS `{0}` ({1})", table.TableName,
                                 string.Join(", \n", columnDef.Concat(primaryFields))));
        }
예제 #12
0
        public PsaMovesetHandler(PsaFile psaFile)
        {
            PsaFile             = psaFile;
            AttributesHandler   = new AttributesParser(PsaFile);
            DataTableHandler    = new DataTableHandler(PsaFile);
            ExternalDataHandler = new ExternalDataHandler(PsaFile);
            int    dataSectionLocation = DataTableHandler.GetDataTableEntryByName("data").Location;
            string movesetBaseName     = GetMovesetBaseName();

            int numberOfSpecialActions          = (PsaFile.DataSection[dataSectionLocation + 10] - PsaFile.DataSection[dataSectionLocation + 9]) / 4;
            int codeBlockDataStartLocation      = 2014 + numberOfSpecialActions * 2;
            PsaCommandHandler psaCommandHandler = new PsaCommandHandler(psaFile, dataSectionLocation, codeBlockDataStartLocation);
            CodeBlocksHandler codeBlocksHandler = new CodeBlocksHandler(psaFile, dataSectionLocation, psaCommandHandler);

            ActionsHandler         = new ActionsHandler(PsaFile, dataSectionLocation, codeBlocksHandler, psaCommandHandler);
            SubActionsHandler      = new SubActionsHandler(PsaFile, dataSectionLocation, codeBlocksHandler, psaCommandHandler);
            SubRoutinesHandler     = new SubRoutinesHandler(PsaFile, dataSectionLocation, ActionsHandler, SubActionsHandler, psaCommandHandler);
            ActionOverridesHandler = new ActionOverridesHandler(PsaFile, dataSectionLocation, ActionsHandler, psaCommandHandler);
            ArticlesHandler        = new ArticlesHandler(PsaFile, dataSectionLocation, movesetBaseName, psaCommandHandler);
            CharacterParamsHandler = new CharacterParamsHandler(PsaFile, dataSectionLocation, movesetBaseName, psaCommandHandler);
            MiscHandler            = new MiscHandler(PsaFile, dataSectionLocation, movesetBaseName, numberOfSpecialActions);
        }
예제 #13
0
        /// <summary>
        /// Create a New Table from DataTableHandler Definition
        /// </summary>
        /// <param name="table">DataTableHandler Definition to Create in Database</param>
        protected void CreateTable(DataTableHandler table)
        {
            var columnDef = table.FieldElementBindings
                            .Select(bind => GetColumnDefinition(bind, table));

            var primaryFields = string.Format("PRIMARY KEY ({0})",
                                              string.Join(", ", table.Table.PrimaryKey.Select(pk => string.Format("`{0}`", pk.ColumnName))));

            var uniqueFields = table.Table.Constraints.OfType <UniqueConstraint>().Where(cstrnt => !cstrnt.IsPrimaryKey)
                               .Select(cstrnt => string.Format("UNIQUE KEY `{0}` ({1})", cstrnt.ConstraintName,
                                                               string.Join(", ", cstrnt.Columns.Select(col => string.Format("`{0}`", col.ColumnName)))));

            var indexes = table.Table.ExtendedProperties["INDEXES"] as Dictionary <string, DataColumn[]>;

            var indexesFields = indexes == null?Array.Empty <string>()
                                    : indexes.Select(index => string.Format("KEY `{0}` ({1})", index.Key,
                                                                            string.Join(", ", index.Value.Select(col => string.Format("`{0}`", col.ColumnName)))));

            var command = string.Format("CREATE TABLE IF NOT EXISTS `{0}` ({1})", table.TableName,
                                        string.Join(", \n", columnDef.Concat(new [] { primaryFields }).Concat(uniqueFields).Concat(indexesFields)));

            ExecuteNonQueryImpl(command);
        }
예제 #14
0
        /// <summary>
        /// 未发货订单
        /// </summary>
        /// <param name="context"></param>
        public void GetPendingList(HttpContext context)
        {
            var pageSize  = 5;
            var pageIndex = 1;

            if (!string.IsNullOrEmpty(context.Request["limit"]))
            {
                pageSize = int.Parse(context.Request["limit"]);
            }
            if (!string.IsNullOrEmpty(context.Request["offset"]))
            {
                pageIndex = int.Parse(context.Request["offset"]);
            }
            object RowCount = null;
            var    user     = (context.Session["USER_SESSION"] as UserBase);

            if (user.UA01024 != 42 && user.UA01024 != 43 && user.UA01024 != 44 && user.UA01024 != 47)
            {
                context.Response.Write("0");
                return;
            }
            string where = user.UA01024 == 43 ? "and OA01013 = '" + user.UA01001 + "'" : "and UA01013 = '" + user.UA01013 + "'";
            if (user.UA01013 == "全区域")
            {
                where = string.Empty;
            }
            DataTable dt   = new OrderBLL().GetPengdingList(pageIndex, pageSize, where, ref RowCount);
            var       list = new DataTableHandler().ToList <Pending>(dt);
            Hashtable tab  = new Hashtable();

            tab["total"] = RowCount;
            tab["rows"]  = list;
            var json = JsonConvert.SerializeObject(tab);

            context.Response.Write(json);
        }
예제 #15
0
        /// <summary>
        /// Check if Table Indexes Need Alteration
        /// </summary>
        /// <param name="table">DataTableHandler to Implement</param>
        protected void CheckTableIndexAlteration(DataTableHandler table)
        {
            // Query Existing Indexes
            var currentIndexes = new List <Tuple <string, string> >();

            try
            {
                ExecuteSelectImpl("SELECT name, sql FROM sqlite_master WHERE type == 'index' AND sql is not null AND tbl_name == @tableName",
                                  new QueryParameter("@tableName", table.TableName),
                                  reader =>
                {
                    while (reader.Read())
                    {
                        currentIndexes.Add(new Tuple <string, string>(reader.GetString(0), reader.GetString(1)));
                    }
                }, IsolationLevel.DEFAULT);
            }
            catch (Exception e)
            {
                if (log.IsDebugEnabled)
                {
                    log.Debug("CheckTableIndexAlteration: ", e);
                }

                throw;
            }

            var sortedIndexes = currentIndexes.Select(ind => {
                var unique  = ind.Item2.Trim().StartsWith("CREATE UNIQUE", StringComparison.OrdinalIgnoreCase);
                var columns = ind.Item2.Substring(ind.Item2.IndexOf('(')).Split(',').Select(sp => sp.Trim('`', '(', ')', ' '));
                return(new { KeyName = ind.Item1, Unique = unique, Columns = columns.ToArray() });
            }).ToArray();

            if (log.IsDebugEnabled)
            {
                log.DebugFormat("CheckTableIndexAlteration: {0} Indexes existing in table {1}", sortedIndexes.Length, table.TableName);
            }

            var tableIndexes = table.Table.ExtendedProperties["INDEXES"] as Dictionary <string, DataColumn[]>;

            var alterQueries = new List <string>();

            // Check for Index Removal
            foreach (var existing in sortedIndexes)
            {
                if (log.IsDebugEnabled)
                {
                    log.DebugFormat("CheckTableIndexAlteration: Found Index `{0}` (Unique:{1}) on ({2}) in existing table {3}", existing.KeyName, existing.Unique, string.Join(", ", existing.Columns), table.TableName);
                }

                DataColumn[] realindex;
                if (tableIndexes.TryGetValue(existing.KeyName, out realindex))
                {
                    // Check for index modifications
                    if (realindex.Length != existing.Columns.Length ||
                        !realindex.All(col => existing.Columns.Any(c => c.Equals(col.ColumnName, StringComparison.OrdinalIgnoreCase))))
                    {
                        alterQueries.Add(string.Format("DROP INDEX `{0}`", existing.KeyName));
                        alterQueries.Add(string.Format("CREATE INDEX IF NOT EXISTS `{0}` ON `{2}` ({1})", existing.KeyName, string.Join(", ", realindex.Select(col => string.Format("`{0}`", col))), table.TableName));
                    }
                }
                else
                {
                    // Check for Unique
                    var realunique = table.Table.Constraints.OfType <UniqueConstraint>().FirstOrDefault(cstrnt => !cstrnt.IsPrimaryKey && cstrnt.ConstraintName.Equals(existing.KeyName, StringComparison.OrdinalIgnoreCase));
                    if (realunique == null)
                    {
                        alterQueries.Add(string.Format("DROP INDEX `{0}`", existing.KeyName));
                    }
                    else if (realunique.Columns.Length != existing.Columns.Length ||
                             !realunique.Columns.All(col => existing.Columns.Any(c => c.Equals(col.ColumnName, StringComparison.OrdinalIgnoreCase))))
                    {
                        alterQueries.Add(string.Format("DROP INDEX `{0}`", existing.KeyName));
                        alterQueries.Add(string.Format("CREATE UNIQUE INDEX IF NOT EXISTS `{0}` ON `{2}` ({1})", existing.KeyName, string.Join(", ", realunique.Columns.Select(col => string.Format("`{0}`", col))), table.TableName));
                    }
                }
            }

            // Missing Indexes
            foreach (var missing in tableIndexes.Where(kv => sortedIndexes.All(c => !c.KeyName.Equals(kv.Key, StringComparison.OrdinalIgnoreCase))))
            {
                alterQueries.Add(string.Format("CREATE INDEX IF NOT EXISTS `{0}` ON `{2}` ({1})", missing.Key, string.Join(", ", missing.Value.Select(col => string.Format("`{0}`", col))), table.TableName));
            }

            foreach (var missing in table.Table.Constraints.OfType <UniqueConstraint>().Where(cstrnt => !cstrnt.IsPrimaryKey && sortedIndexes.All(c => !c.KeyName.Equals(cstrnt.ConstraintName, StringComparison.OrdinalIgnoreCase))))
            {
                alterQueries.Add(string.Format("CREATE UNIQUE INDEX IF NOT EXISTS `{0}` ON `{2}` ({1})", missing.ConstraintName, string.Join(", ", missing.Columns.Select(col => string.Format("`{0}`", col))), table.TableName));
            }

            if (!alterQueries.Any())
            {
                return;
            }

            if (log.IsDebugEnabled)
            {
                log.DebugFormat("Altering Table Indexes {0} this could take a few minutes...", table.TableName);
            }

            foreach (var query in alterQueries)
            {
                ExecuteNonQueryImpl(query);
            }
        }
예제 #16
0
        /// <summary>
        /// Check if this Table need Alteration
        /// </summary>
        /// <param name="currentColumns">Current Existing Columns</param>
        /// <param name="table">DataTableHandler to Implement</param>
        protected bool CheckTableAlteration(IEnumerable <TableRowBindind> currentColumns, DataTableHandler table)
        {
            // Check for Any differences in Columns
            if (table.FieldElementBindings
                .Any(bind => {
                var column = currentColumns.FirstOrDefault(col => col.ColumnName.Equals(bind.ColumnName, StringComparison.OrdinalIgnoreCase));

                if (column != null)
                {
                    // Check Null
                    if ((bind.DataElement != null && bind.DataElement.AllowDbNull) != column.AllowDbNull)
                    {
                        return(true);
                    }

                    // Check Type
                    if (!GetDatabaseType(bind, table).Equals(column.ColumnType, StringComparison.OrdinalIgnoreCase))
                    {
                        return(true);
                    }

                    // Field are identical
                    return(false);
                }
                // Field missing
                return(true);
            }))
            {
                return(true);
            }

            // Check for Any Difference in Primary Keys
            if (table.Table.PrimaryKey.Length != currentColumns.Count(col => col.Primary) ||
                table.Table.PrimaryKey.Any(pk => {
                var column = currentColumns.FirstOrDefault(col => col.ColumnName.Equals(pk.ColumnName, StringComparison.OrdinalIgnoreCase));

                if (column != null && column.Primary)
                {
                    return(false);
                }

                return(true);
            }))
            {
                return(true);
            }

            // No Alteration Needed
            return(false);
        }
예제 #17
0
		/// <summary>
		/// Check for Table Existence, Create or Alter accordingly
		/// </summary>
		/// <param name="table">Table Handler</param>
		public override void CheckOrCreateTableImpl(DataTableHandler table)
		{
			var currentTableColumns = new List<TableRowBindind>();
			try
			{
				ExecuteSelectImpl(string.Format("PRAGMA TABLE_INFO(`{0}`)", table.TableName),
				                  reader =>
				                  {
				                  	while (reader.Read())
				                  	{
				                  		var column = reader.GetString(1);
				                  		var colType = reader.GetString(2);
				                  		var allowNull = !reader.GetBoolean(3);
				                  		var primary = reader.GetInt64(5) > 0;
				                  		currentTableColumns.Add(new TableRowBindind(column, colType, allowNull, primary));
				                  		if (log.IsDebugEnabled)
				                  			log.DebugFormat("CheckOrCreateTable: Found Column {0} in existing table {1}", column, table.TableName);
				                  	}
				                  	if (log.IsDebugEnabled)
				                  		log.DebugFormat("CheckOrCreateTable: {0} columns existing in table {1}", currentTableColumns.Count, table.TableName);
				                  }, IsolationLevel.DEFAULT);
			}
			catch (Exception e)
			{
				if (log.IsDebugEnabled)
					log.Debug("CheckOrCreateTable: ", e);
			}
			
			// Create Table or Alter Table
			if (currentTableColumns.Any())
			{
				AlterTable(currentTableColumns, table);
			}
			else
			{
				if (log.IsWarnEnabled)
					log.WarnFormat("Table {0} doesn't exist, creating it...", table.TableName);

				CreateTable(table);
			}
		}
예제 #18
0
		/// <summary>
		/// Helper Method to build Table Definition String
		/// </summary>
		/// <param name="table"></param>
		/// <returns></returns>
		protected string GetTableDefinition(DataTableHandler table)
		{
			var columnDef = table.FieldElementBindings
				.Select(bind => GetColumnDefinition(bind, table));
			
			var primaryFields = new string[]{};
			if (!table.FieldElementBindings.Any(bind => bind.PrimaryKey != null && bind.PrimaryKey.AutoIncrement))
				primaryFields = new [] { string.Format("PRIMARY KEY ({0})",
				                              string.Join(", ", table.Table.PrimaryKey.Select(pk => string.Format("`{0}`", pk.ColumnName)))) };
			
			// Create Table First
			return string.Format("CREATE TABLE IF NOT EXISTS `{0}` ({1})", table.TableName,
			                            string.Join(", \n", columnDef.Concat(primaryFields)));
		}
예제 #19
0
		/// <summary>
		/// Helper Method to build Table Indexes Definition String
		/// </summary>
		/// <param name="table"></param>
		/// <returns></returns>
		protected IEnumerable<string> GetIndexesDefinition(DataTableHandler table)
		{
			// Indexes and Constraints
			var uniqueFields = table.Table.Constraints.OfType<UniqueConstraint>().Where(cstrnt => !cstrnt.IsPrimaryKey)
				.Select(cstrnt => string.Format("CREATE UNIQUE INDEX IF NOT EXISTS `{0}` ON `{2}` ({1})", cstrnt.ConstraintName,
				                                string.Join(", ", cstrnt.Columns.Select(col => string.Format("`{0}`", col.ColumnName))),
				                                table.TableName));
			
			var indexes = table.Table.ExtendedProperties["INDEXES"] as Dictionary<string, DataColumn[]>;
			
			var indexesFields = indexes == null ? new string[] { }
				: indexes.Select(index => string.Format("CREATE INDEX IF NOT EXISTS `{0}` ON `{2}` ({1})", index.Key,
			                                        string.Join(", ", index.Value.Select(col => string.Format("`{0}`", col.ColumnName))),
			                                        table.TableName));
			
			return uniqueFields.Concat(indexesFields);
		}
예제 #20
0
        /// <summary>
        /// Alter an Existing Table to Match DataTableHandler Definition
        /// </summary>
        /// <param name="currentColumns">Current Existing Columns</param>
        /// <param name="table">DataTableHandler to Implement</param>
        protected void AlterTable(IEnumerable <TableRowBindind> currentColumns, DataTableHandler table)
        {
            var columnDefs    = new List <string>();
            var alteredColumn = new List <string>();

            // Check for Missing Column or Wrong Type
            foreach (var binding in table.FieldElementBindings)
            {
                var column = currentColumns.FirstOrDefault(col => col.ColumnName.Equals(binding.ColumnName, StringComparison.OrdinalIgnoreCase));

                if (column != null)
                {
                    // Check Null && Type
                    if ((binding.DataElement != null && binding.DataElement.AllowDbNull) != column.AllowDbNull ||
                        !GetDatabaseType(binding, table).Equals(column.ColumnType, StringComparison.OrdinalIgnoreCase))
                    {
                        columnDefs.Add(string.Format("CHANGE `{1}` {0}", GetColumnDefinition(binding, table), binding.ColumnName));
                        alteredColumn.Add(binding.ColumnName);
                    }

                    continue;
                }

                columnDefs.Add(string.Format("ADD {0}", GetColumnDefinition(binding, table)));
            }

            // Check for Indexes
            var indexes = new List <Tuple <bool, string, string> >();

            try
            {
                ExecuteSelectImpl(string.Format("SHOW INDEX FROM `{0}`", table.TableName),
                                  reader =>
                {
                    while (reader.Read())
                    {
                        var unique    = reader.GetInt64(1) < 1;
                        var indexname = reader.GetString(2);
                        var column    = reader.GetString(4);
                        indexes.Add(new Tuple <bool, string, string>(unique, indexname, column));
                        if (log.IsDebugEnabled)
                        {
                            log.DebugFormat("AlterTable: Found Index `{0}` (Unique:{1}) on `{2}` in existing table {3}", indexname, unique, column, table.TableName);
                        }
                    }
                    if (log.IsDebugEnabled)
                    {
                        log.DebugFormat("AlterTable: {0} Indexes existing in table {1}", indexes.Count, table.TableName);
                    }
                }, IsolationLevel.DEFAULT);
            }
            catch (Exception e)
            {
                if (log.IsDebugEnabled)
                {
                    log.Debug("AlterTable: ", e);
                }
            }

            // Sort Indexes
            var existingIndexes = indexes.GroupBy(ind => new { KeyName = ind.Item2, Unique = ind.Item1 })
                                  .Select(grp => new { grp.Key.KeyName, grp.Key.Unique, Columns = grp.Select(i => i.Item3).ToArray() }).ToArray();

            var havePrimaryIndex     = existingIndexes.FirstOrDefault(ind => ind.KeyName.Equals("PRIMARY"));
            var currentPrimaryColumn = new string[] { };

            if (havePrimaryIndex != null)
            {
                currentPrimaryColumn = havePrimaryIndex.Columns;
            }

            // Check for Any Difference in Primary Keys
            if (table.Table.PrimaryKey.Length != currentPrimaryColumn.Length ||
                table.Table.PrimaryKey.Any(pk => {
                var column = currentPrimaryColumn.FirstOrDefault(col => col.Equals(pk.ColumnName, StringComparison.OrdinalIgnoreCase));

                return(column == null);
            }))
            {
                // Allow to edit Auto increment key if not previously modified
                foreach (var oldkeys in currentColumns.Where(col => col.Primary && !alteredColumn.Any(c => c.Equals(col.ColumnName, StringComparison.OrdinalIgnoreCase))))
                {
                    columnDefs.Add(string.Format("MODIFY `{0}` {1} {2}", oldkeys.ColumnName, oldkeys.ColumnType, oldkeys.AllowDbNull ? "DEFAULT NULL" : "NOT NULL"));
                }

                if (currentPrimaryColumn.Any())
                {
                    columnDefs.Add("DROP PRIMARY KEY");
                }

                columnDefs.Add(string.Format("ADD PRIMARY KEY ({0})", string.Join(", ", table.Table.PrimaryKey.Select(pk => string.Format("`{0}`", pk.ColumnName)))));
            }


            var tableIndexes = table.Table.ExtendedProperties["INDEXES"] as Dictionary <string, DataColumn[]>;

            // Check for Index Removal
            foreach (var existing in existingIndexes.Where(ind => !ind.KeyName.Equals("PRIMARY")))
            {
                DataColumn[] realindex;
                if (tableIndexes.TryGetValue(existing.KeyName, out realindex))
                {
                    // Check for index modifications
                    if (realindex.Length != existing.Columns.Length ||
                        !realindex.All(col => existing.Columns.Any(c => c.Equals(col.ColumnName, StringComparison.OrdinalIgnoreCase))))
                    {
                        columnDefs.Add(string.Format("DROP KEY `{0}`", existing.KeyName));
                        columnDefs.Add(string.Format("ADD KEY `{0}` ({1})", existing.KeyName, string.Join(", ", realindex.Select(col => string.Format("`{0}`", col)))));
                    }
                }
                else
                {
                    // Check for Unique
                    var realunique = table.Table.Constraints.OfType <UniqueConstraint>().FirstOrDefault(cstrnt => !cstrnt.IsPrimaryKey && cstrnt.ConstraintName.Equals(existing.KeyName, StringComparison.OrdinalIgnoreCase));
                    if (realunique == null)
                    {
                        columnDefs.Add(string.Format("DROP KEY `{0}`", existing.KeyName));
                    }
                    else if (realunique.Columns.Length != existing.Columns.Length ||
                             !realunique.Columns.All(col => existing.Columns.Any(c => c.Equals(col.ColumnName, StringComparison.OrdinalIgnoreCase))))
                    {
                        columnDefs.Add(string.Format("DROP KEY `{0}`", existing.KeyName));
                        columnDefs.Add(string.Format("ADD UNIQUE KEY `{0}` ({1})", existing.KeyName, string.Join(", ", realunique.Columns.Select(col => string.Format("`{0}`", col)))));
                    }
                }
            }

            // Missing Indexes
            foreach (var missing in tableIndexes.Where(kv => existingIndexes.All(c => !c.KeyName.Equals(kv.Key, StringComparison.OrdinalIgnoreCase))))
            {
                columnDefs.Add(string.Format("ADD KEY `{0}` ({1})", missing.Key, string.Join(", ", missing.Value.Select(col => string.Format("`{0}`", col)))));
            }

            foreach (var missing in table.Table.Constraints.OfType <UniqueConstraint>().Where(cstrnt => !cstrnt.IsPrimaryKey && existingIndexes.All(c => !c.KeyName.Equals(cstrnt.ConstraintName, StringComparison.OrdinalIgnoreCase))))
            {
                columnDefs.Add(string.Format("ADD UNIQUE KEY `{0}` ({1})", missing.ConstraintName, string.Join(", ", missing.Columns.Select(col => string.Format("`{0}`", col)))));
            }


            if (!columnDefs.Any())
            {
                return;
            }

            if (log.IsInfoEnabled)
            {
                log.InfoFormat("Altering Table {0} this could take a few minutes...", table.TableName);
            }

            ExecuteNonQueryImpl(string.Format("ALTER TABLE `{0}` {1}", table.TableName, string.Join(", \n", columnDefs)));
        }
예제 #21
0
		/// <summary>
		/// Alter an Existing Table to Match DataTableHandler Definition
		/// </summary>
		/// <param name="currentColumns">Current Existing Columns</param>
		/// <param name="table">DataTableHandler to Implement</param>
		protected void AlterTable(IEnumerable<TableRowBindind> currentColumns, DataTableHandler table)
		{
			var columnDefs = new List<string>();
			var alteredColumn = new List<string>();
			// Check for Missing Column or Wrong Type
			foreach (var binding in table.FieldElementBindings)
			{
				var column = currentColumns.FirstOrDefault(col => col.ColumnName.Equals(binding.ColumnName, StringComparison.OrdinalIgnoreCase));
				
				if (column != null)
				{

					// Check Null && Type
					if ((binding.DataElement != null && binding.DataElement.AllowDbNull) != column.AllowDbNull
					    || !GetDatabaseType(binding, table).Equals(column.ColumnType, StringComparison.OrdinalIgnoreCase))
					{
						columnDefs.Add(string.Format("CHANGE `{1}` {0}", GetColumnDefinition(binding, table), binding.ColumnName));
						alteredColumn.Add(binding.ColumnName);
					}

					continue;
				}
				
				columnDefs.Add(string.Format("ADD {0}", GetColumnDefinition(binding, table)));
			}

			// Check for Indexes
			var indexes = new List<Tuple<bool, string, string>>();
			try
			{
				ExecuteSelectImpl(string.Format("SHOW INDEX FROM `{0}`", table.TableName),
				                  reader =>
				                  {
				                  	while (reader.Read())
				                  	{
				                  		var unique = reader.GetInt64(1) < 1;
				                  		var indexname = reader.GetString(2);
				                  		var column = reader.GetString(4);
				                  		indexes.Add(new Tuple<bool, string, string>(unique, indexname, column));
				                  		if (log.IsDebugEnabled)
				                  			log.DebugFormat("AlterTable: Found Index `{0}` (Unique:{1}) on `{2}` in existing table {3}", indexname, unique, column, table.TableName);
				                  	}
				                  	if (log.IsDebugEnabled)
				                  		log.DebugFormat("AlterTable: {0} Indexes existing in table {1}", indexes.Count, table.TableName);
				                  }, IsolationLevel.DEFAULT);
			}
			catch (Exception e)
			{
				if (log.IsDebugEnabled)
					log.Debug("AlterTable: ", e);
			}
			
			// Sort Indexes
			var existingIndexes = indexes.GroupBy(ind => new { KeyName = ind.Item2, Unique = ind.Item1 })
				.Select(grp => new { grp.Key.KeyName, grp.Key.Unique, Columns = grp.Select(i => i.Item3).ToArray() }).ToArray();
			
			var havePrimaryIndex = existingIndexes.FirstOrDefault(ind => ind.KeyName.Equals("PRIMARY"));
			var currentPrimaryColumn = new string[] { };
			if (havePrimaryIndex != null)
				currentPrimaryColumn = havePrimaryIndex.Columns;
			
			// Check for Any Difference in Primary Keys
			if (table.Table.PrimaryKey.Length != currentPrimaryColumn.Length
			   || table.Table.PrimaryKey.Any(pk => {
			                                  	var column = currentPrimaryColumn.FirstOrDefault(col => col.Equals(pk.ColumnName, StringComparison.OrdinalIgnoreCase));
			                                  	
			                                  	return column == null;
			                                  }))
			{
				// Allow to edit Auto increment key if not previously modified
				foreach(var oldkeys in currentColumns.Where(col => col.Primary && !alteredColumn.Any(c => c.Equals(col.ColumnName, StringComparison.OrdinalIgnoreCase))))
					columnDefs.Add(string.Format("MODIFY `{0}` {1} {2}", oldkeys.ColumnName, oldkeys.ColumnType, oldkeys.AllowDbNull ? "DEFAULT NULL" : "NOT NULL"));
				
				if (currentPrimaryColumn.Any())
					columnDefs.Add("DROP PRIMARY KEY");
				
				columnDefs.Add(string.Format("ADD PRIMARY KEY ({0})", string.Join(", ", table.Table.PrimaryKey.Select(pk => string.Format("`{0}`", pk.ColumnName)))));
			}

			
			var tableIndexes = table.Table.ExtendedProperties["INDEXES"] as Dictionary<string, DataColumn[]>;
			
			// Check for Index Removal
			foreach (var existing in existingIndexes.Where(ind => !ind.KeyName.Equals("PRIMARY")))
			{
				DataColumn[] realindex;
				if(tableIndexes.TryGetValue(existing.KeyName, out realindex))
				{
					// Check for index modifications
					if (realindex.Length != existing.Columns.Length
					    || !realindex.All(col => existing.Columns.Any(c => c.Equals(col.ColumnName, StringComparison.OrdinalIgnoreCase))))
					{
						columnDefs.Add(string.Format("DROP KEY `{0}`", existing.KeyName));
						columnDefs.Add(string.Format("ADD KEY `{0}` ({1})", existing.KeyName, string.Join(", ", realindex.Select(col => string.Format("`{0}`", col)))));
					}
				}
				else
				{
					// Check for Unique
					var realunique = table.Table.Constraints.OfType<UniqueConstraint>().FirstOrDefault(cstrnt => !cstrnt.IsPrimaryKey && cstrnt.ConstraintName.Equals(existing.KeyName, StringComparison.OrdinalIgnoreCase));
					if (realunique == null)
						columnDefs.Add(string.Format("DROP KEY `{0}`", existing.KeyName));
					else if (realunique.Columns.Length != existing.Columns.Length
					         || !realunique.Columns.All(col => existing.Columns.Any(c => c.Equals(col.ColumnName, StringComparison.OrdinalIgnoreCase))))
					{
						columnDefs.Add(string.Format("DROP KEY `{0}`", existing.KeyName));
						columnDefs.Add(string.Format("ADD UNIQUE KEY `{0}` ({1})", existing.KeyName, string.Join(", ", realunique.Columns.Select(col => string.Format("`{0}`", col)))));
					}
				}
			}
			
			// Missing Indexes
			foreach (var missing in tableIndexes.Where(kv => existingIndexes.All(c => !c.KeyName.Equals(kv.Key, StringComparison.OrdinalIgnoreCase))))
				columnDefs.Add(string.Format("ADD KEY `{0}` ({1})", missing.Key, string.Join(", ", missing.Value.Select(col => string.Format("`{0}`", col)))));
			
			foreach (var missing in table.Table.Constraints.OfType<UniqueConstraint>().Where(cstrnt => !cstrnt.IsPrimaryKey && existingIndexes.All(c => !c.KeyName.Equals(cstrnt.ConstraintName, StringComparison.OrdinalIgnoreCase))))
				columnDefs.Add(string.Format("ADD UNIQUE KEY `{0}` ({1})", missing.ConstraintName, string.Join(", ", missing.Columns.Select(col => string.Format("`{0}`", col)))));
				
			
			if (!columnDefs.Any())
				return;
			
			if (log.IsInfoEnabled)
				log.InfoFormat("Altering Table {0} this could take a few minutes...", table.TableName);
			
			ExecuteNonQueryImpl(string.Format("ALTER TABLE `{0}` {1}", table.TableName, string.Join(", \n", columnDefs)));
		}
예제 #22
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);
        }
예제 #23
0
		/// <summary>
		/// Alter an Existing Table to Match DataTableHandler Definition
		/// </summary>
		/// <param name="currentColumns">Current Existing Columns</param>
		/// <param name="table">DataTableHandler to Implement</param>
		protected void AlterTable(IEnumerable<TableRowBindind> currentColumns, DataTableHandler table)
		{
			// If Column are not modified Alter Table is not needed...
			if  (!CheckTableAlteration(currentColumns, table))
			{
				// Table not Altered check for Indexes and return
				CheckTableIndexAlteration(table);
				return;
			}
			
			if (log.IsInfoEnabled)
				log.InfoFormat("Altering Table {0} this could take a few minutes...", table.TableName);
			
			var currentIndexes = new List<string>();
			try
			{
				ExecuteSelectImpl("SELECT name FROM sqlite_master WHERE type == 'index' AND sql is not null AND tbl_name == @tableName",
				                  new QueryParameter("@tableName", table.TableName),
				                  reader =>
				                  {
				                  	while (reader.Read())
				                  		currentIndexes.Add(reader.GetString(0));
				                  }, IsolationLevel.DEFAULT);
			}
			catch (Exception e)
			{
				if (log.IsDebugEnabled)
					log.Debug("AlterTableImpl: ", e);

				if (log.IsWarnEnabled)
					log.WarnFormat("AlterTableImpl: Error While Altering Table {0}, no modifications...", table.TableName);

				throw;
			}

			using (var conn = new SQLiteConnection(ConnectionString))
			{
				conn.Open();
				using(var tran = conn.BeginTransaction(System.Data.IsolationLevel.ReadCommitted))
				{
					try
					{
						// Delete Indexes
						foreach(var index in currentIndexes)
						{
							using (var command = new SQLiteCommand(string.Format("DROP INDEX `{0}`", index), conn))
							{
								command.Transaction = tran;
								command.ExecuteNonQuery();
							}
						}
						
						// Rename Table
						using (var command = new SQLiteCommand(string.Format("ALTER TABLE `{0}` RENAME TO `{0}_bkp`", table.TableName), conn))
						{
							command.Transaction = tran;
							command.ExecuteNonQuery();
						}
						
						// Create New Table
						using (var command = new SQLiteCommand(GetTableDefinition(table), conn))
						{
							command.Transaction = tran;
							command.ExecuteNonQuery();
						}
						
						// Create Indexes
						foreach (var index in GetIndexesDefinition(table))
						{
							using (var command = new SQLiteCommand(index, conn))
							{
								command.Transaction = tran;
								command.ExecuteNonQuery();
							}
						}
						
						// Copy Data
						var columns = table.FieldElementBindings.Where(bind => currentColumns.Any(col => col.ColumnName.Equals(bind.ColumnName, StringComparison.OrdinalIgnoreCase)))
							.Select(bind => string.Format("`{0}`", bind.ColumnName));
						using (var command = new SQLiteCommand(string.Format("INSERT INTO `{0}` ({1}) SELECT {1} FROM `{0}_bkp`", table.TableName, string.Join(", ", columns)), conn))
						{
							command.Transaction = tran;
							command.ExecuteNonQuery();
						}

						// Drop Renamed Table
						using (var command = new SQLiteCommand(string.Format("DROP TABLE `{0}_bkp`", table.TableName), conn))
						{
							command.Transaction = tran;
							command.ExecuteNonQuery();
						}
						
						tran.Commit();
						if (log.IsInfoEnabled)
							log.InfoFormat("AlterTableImpl: Table {0} Altered...", table.TableName);
					}
					catch (Exception e)
					{
						tran.Rollback();
						if (log.IsDebugEnabled)
							log.Debug("AlterTableImpl: ", e);
						
						if (log.IsWarnEnabled)
							log.WarnFormat("AlterTableImpl: Error While Altering Table {0}, rollback...\n{1}", table.TableName, e);
					}
					
				}
			}
		}
예제 #24
0
		/// <summary>
		/// Check if Table Indexes Need Alteration
		/// </summary>
		/// <param name="table">DataTableHandler to Implement</param>
		protected void CheckTableIndexAlteration(DataTableHandler table)
		{
			// Query Existing Indexes
			var currentIndexes = new List<Tuple<string, string>>();
			try
			{
				ExecuteSelectImpl("SELECT name, sql FROM sqlite_master WHERE type == 'index' AND sql is not null AND tbl_name == @tableName",
				                  new QueryParameter("@tableName", table.TableName),
				                  reader =>
				                  {
				                  	while (reader.Read())
				                  		currentIndexes.Add(new Tuple<string, string>(reader.GetString(0), reader.GetString(1)));
				                  }, IsolationLevel.DEFAULT);
			}
			catch (Exception e)
			{
				if (log.IsDebugEnabled)
					log.Debug("CheckTableIndexAlteration: ", e);
				
				throw;
			}
			
			var sortedIndexes = currentIndexes.Select(ind => {
			                                          	var unique = ind.Item2.Trim().StartsWith("CREATE UNIQUE", StringComparison.OrdinalIgnoreCase);
			                                          	var columns = ind.Item2.Substring(ind.Item2.IndexOf('(')).Split(',').Select(sp => sp.Trim('`', '(', ')', ' '));
			                                          	return new { KeyName = ind.Item1, Unique = unique, Columns = columns.ToArray() };
			                                          }).ToArray();
			if (log.IsDebugEnabled)
				log.DebugFormat("CheckTableIndexAlteration: {0} Indexes existing in table {1}", sortedIndexes.Length, table.TableName);

			var tableIndexes = table.Table.ExtendedProperties["INDEXES"] as Dictionary<string, DataColumn[]>;
			
			var alterQueries = new List<string>();
			
			// Check for Index Removal
			foreach (var existing in sortedIndexes)
			{
				if (log.IsDebugEnabled)
					log.DebugFormat("CheckTableIndexAlteration: Found Index `{0}` (Unique:{1}) on ({2}) in existing table {3}", existing.KeyName, existing.Unique, string.Join(", ", existing.Columns), table.TableName);
				
				DataColumn[] realindex;
				if(tableIndexes.TryGetValue(existing.KeyName, out realindex))
				{
					// Check for index modifications
					if (realindex.Length != existing.Columns.Length
					    || !realindex.All(col => existing.Columns.Any(c => c.Equals(col.ColumnName, StringComparison.OrdinalIgnoreCase))))
					{
						alterQueries.Add(string.Format("DROP INDEX `{0}`", existing.KeyName));
						alterQueries.Add(string.Format("CREATE INDEX IF NOT EXISTS `{0}` ON `{2}` ({1})", existing.KeyName, string.Join(", ", realindex.Select(col => string.Format("`{0}`", col))), table.TableName));
					}
				}
				else
				{
					// Check for Unique
					var realunique = table.Table.Constraints.OfType<UniqueConstraint>().FirstOrDefault(cstrnt => !cstrnt.IsPrimaryKey && cstrnt.ConstraintName.Equals(existing.KeyName, StringComparison.OrdinalIgnoreCase));
					if (realunique == null)
						alterQueries.Add(string.Format("DROP INDEX `{0}`", existing.KeyName));
					else if (realunique.Columns.Length != existing.Columns.Length
					         || !realunique.Columns.All(col => existing.Columns.Any(c => c.Equals(col.ColumnName, StringComparison.OrdinalIgnoreCase))))
					{
						alterQueries.Add(string.Format("DROP INDEX `{0}`", existing.KeyName));
						alterQueries.Add(string.Format("CREATE UNIQUE INDEX IF NOT EXISTS `{0}` ON `{2}` ({1})", existing.KeyName, string.Join(", ", realunique.Columns.Select(col => string.Format("`{0}`", col))), table.TableName));
					}
				}
			}
			
			// Missing Indexes
			foreach (var missing in tableIndexes.Where(kv => sortedIndexes.All(c => !c.KeyName.Equals(kv.Key, StringComparison.OrdinalIgnoreCase))))
				alterQueries.Add(string.Format("CREATE INDEX IF NOT EXISTS `{0}` ON `{2}` ({1})", missing.Key, string.Join(", ", missing.Value.Select(col => string.Format("`{0}`", col))), table.TableName));
			
			foreach (var missing in table.Table.Constraints.OfType<UniqueConstraint>().Where(cstrnt => !cstrnt.IsPrimaryKey && sortedIndexes.All(c => !c.KeyName.Equals(cstrnt.ConstraintName, StringComparison.OrdinalIgnoreCase))))
				alterQueries.Add(string.Format("CREATE UNIQUE INDEX IF NOT EXISTS `{0}` ON `{2}` ({1})", missing.ConstraintName, string.Join(", ", missing.Columns.Select(col => string.Format("`{0}`", col))), table.TableName));
			
			if (!alterQueries.Any())
				return;
			
			if (log.IsDebugEnabled)
				log.DebugFormat("Altering Table Indexes {0} this could take a few minutes...", table.TableName);
			
			foreach (var query in alterQueries)
				ExecuteNonQueryImpl(query);
		}
예제 #25
0
		/// <summary>
		/// Create a New Table from DataTableHandler Definition
		/// </summary>
		/// <param name="table">DataTableHandler Definition to Create in Database</param>
		protected void CreateTable(DataTableHandler table)
		{
			var columnDef = table.FieldElementBindings
				.Select(bind => GetColumnDefinition(bind, table));
			
			var primaryFields = string.Format("PRIMARY KEY ({0})",
			                                  string.Join(", ", table.Table.PrimaryKey.Select(pk => string.Format("`{0}`", pk.ColumnName))));
			
			var uniqueFields = table.Table.Constraints.OfType<UniqueConstraint>().Where(cstrnt => !cstrnt.IsPrimaryKey)
				.Select(cstrnt => string.Format("UNIQUE KEY `{0}` ({1})", cstrnt.ConstraintName,
				                                string.Join(", ", cstrnt.Columns.Select(col => string.Format("`{0}`", col.ColumnName)))));
			
			var indexes = table.Table.ExtendedProperties["INDEXES"] as Dictionary<string, DataColumn[]>;
			
			var indexesFields = indexes == null ? new string[] { }
				: indexes.Select(index => string.Format("KEY `{0}` ({1})", index.Key,
			                                        string.Join(", ", index.Value.Select(col => string.Format("`{0}`", col.ColumnName)))));
			
			var command = string.Format("CREATE TABLE IF NOT EXISTS `{0}` ({1})", table.TableName,
			                            string.Join(", \n", columnDef.Concat(new [] { primaryFields }).Concat(uniqueFields).Concat(indexesFields)));
			
			ExecuteNonQueryImpl(command);
		}
예제 #26
0
        /// <summary>
        /// Alter an Existing Table to Match DataTableHandler Definition
        /// </summary>
        /// <param name="currentColumns">Current Existing Columns</param>
        /// <param name="table">DataTableHandler to Implement</param>
        protected void AlterTable(IEnumerable <TableRowBindind> currentColumns, DataTableHandler table)
        {
            var columnDefs    = new List <string>();
            var alteredColumn = new List <string>();

            // Check for Missing Column or Wrong Type
            foreach (var binding in table.FieldElementBindings)
            {
                var column = currentColumns.FirstOrDefault(col => col.ColumnName.Equals(binding.ColumnName, StringComparison.OrdinalIgnoreCase));

                if (column != null)
                {
                    // Check Null && Type
                    if ((binding.DataElement != null && binding.DataElement.AllowDbNull) != column.AllowDbNull ||
                        !GetDatabaseType(binding, table).Equals(column.ColumnType, StringComparison.OrdinalIgnoreCase))
                    {
                        columnDefs.Add(string.Format("CHANGE `{1}` {0}", GetColumnDefinition(binding, table), binding.ColumnName));
                        alteredColumn.Add(binding.ColumnName);
                    }

                    continue;
                }

                columnDefs.Add(string.Format("ADD {0}", GetColumnDefinition(binding, table)));
            }

            // Check for Indexes
            var indexes = new List <Tuple <bool, string, string> >();

            try
            {
                ExecuteSelectImpl(string.Format("SHOW INDEX FROM `{0}`", table.TableName),
                                  new[] { Array.Empty <QueryParameter>() },
                                  reader =>
                {
                    while (reader.Read())
                    {
                        var unique    = reader.GetInt64(1) < 1;
                        var indexname = reader.GetString(2);
                        var column    = reader.GetString(4);
                        indexes.Add(new Tuple <bool, string, string>(unique, indexname, column));
                        if (log.IsDebugEnabled)
                        {
                            log.DebugFormat("AlterTable: Found Index `{0}` (Unique:{1}) on `{2}` in existing table {3}", indexname, unique, column, table.TableName);
                        }
                    }
                    if (log.IsDebugEnabled)
                    {
                        log.DebugFormat("AlterTable: {0} Indexes existing in table {1}", indexes.Count, table.TableName);
                    }
                });
            }
            catch (Exception e)
            {
                if (log.IsDebugEnabled)
                {
                    log.Debug("AlterTable: ", e);
                }
            }

            // Sort Indexes
            var existingIndexes = indexes.GroupBy(ind => new { KeyName = ind.Item2, Unique = ind.Item1 })
                                  .Select(grp => new { grp.Key.KeyName, grp.Key.Unique, Columns = grp.Select(i => i.Item3).ToArray() }).ToArray();

            var havePrimaryIndex     = existingIndexes.FirstOrDefault(ind => ind.KeyName.Equals("PRIMARY"));
            var currentPrimaryColumn = Array.Empty <string>();

            if (havePrimaryIndex != null)
            {
                currentPrimaryColumn = havePrimaryIndex.Columns;
            }

            // Check for Any Difference in Primary Keys
            if (table.Table.PrimaryKey.Length != currentPrimaryColumn.Length ||
                table.Table.PrimaryKey.Any(pk => {
                var column = currentPrimaryColumn.FirstOrDefault(col => col.Equals(pk.ColumnName, StringComparison.OrdinalIgnoreCase));

                return(column == null);
            }))
            {
                // Allow to edit Auto increment key if not previously modified
                foreach (var oldkeys in currentColumns.Where(col => col.Primary && !alteredColumn.Any(c => c.Equals(col.ColumnName, StringComparison.OrdinalIgnoreCase))))
                {
                    columnDefs.Add(string.Format("MODIFY `{0}` {1} {2}", oldkeys.ColumnName, oldkeys.ColumnType, oldkeys.AllowDbNull ? "DEFAULT NULL" : "NOT NULL"));
                }

                if (currentPrimaryColumn.Any())
                {
                    columnDefs.Add("DROP PRIMARY KEY");
                }

                columnDefs.Add(string.Format("ADD PRIMARY KEY ({0})", string.Join(", ", table.Table.PrimaryKey.Select(pk => string.Format("`{0}`", pk.ColumnName)))));
            }


            var tableIndexes = table.Table.ExtendedProperties["INDEXES"] as Dictionary <string, DataColumn[]>;

            // Check for Index Removal
            foreach (var existing in existingIndexes.Where(ind => !ind.KeyName.Equals("PRIMARY")))
            {
                DataColumn[] realindex;
                if (tableIndexes.TryGetValue(existing.KeyName, out realindex))
                {
                    // Check for index modifications
                    if (realindex.Length != existing.Columns.Length ||
                        !realindex.All(col => existing.Columns.Any(c => c.Equals(col.ColumnName, StringComparison.OrdinalIgnoreCase))))
                    {
                        columnDefs.Add(string.Format("DROP KEY `{0}`", existing.KeyName));
                        columnDefs.Add(string.Format("ADD KEY `{0}` ({1})", existing.KeyName, string.Join(", ", realindex.Select(col => string.Format("`{0}`", col)))));
                    }
                }
                else
                {
                    // Check for Unique
                    var realunique = table.Table.Constraints.OfType <UniqueConstraint>().FirstOrDefault(cstrnt => !cstrnt.IsPrimaryKey && cstrnt.ConstraintName.Equals(existing.KeyName, StringComparison.OrdinalIgnoreCase));
                    if (realunique == null)
                    {
                        columnDefs.Add(string.Format("DROP KEY `{0}`", existing.KeyName));
                    }
                    else if (realunique.Columns.Length != existing.Columns.Length ||
                             !realunique.Columns.All(col => existing.Columns.Any(c => c.Equals(col.ColumnName, StringComparison.OrdinalIgnoreCase))))
                    {
                        columnDefs.Add(string.Format("DROP KEY `{0}`", existing.KeyName));
                        columnDefs.Add(string.Format("ADD UNIQUE KEY `{0}` ({1})", existing.KeyName, string.Join(", ", realunique.Columns.Select(col => string.Format("`{0}`", col)))));
                    }
                }
            }

            // Missing Indexes
            foreach (var missing in tableIndexes.Where(kv => existingIndexes.All(c => !c.KeyName.Equals(kv.Key, StringComparison.OrdinalIgnoreCase))))
            {
                columnDefs.Add(string.Format("ADD KEY `{0}` ({1})", missing.Key, string.Join(", ", missing.Value.Select(col => string.Format("`{0}`", col)))));
            }

            foreach (var missing in table.Table.Constraints.OfType <UniqueConstraint>().Where(cstrnt => !cstrnt.IsPrimaryKey && existingIndexes.All(c => !c.KeyName.Equals(cstrnt.ConstraintName, StringComparison.OrdinalIgnoreCase))))
            {
                columnDefs.Add(string.Format("ADD UNIQUE KEY `{0}` ({1})", missing.ConstraintName, string.Join(", ", missing.Columns.Select(col => string.Format("`{0}`", col)))));
            }


            if (!columnDefs.Any())
            {
                return;
            }

            if (log.IsInfoEnabled)
            {
                log.InfoFormat("Altering Table {0} this could take a few minutes...", table.TableName);
            }


            using (var conn = new MySqlConnection(ConnectionString))
            {
                using (var cmd = conn.CreateCommand())
                {
                    conn.Open();

                    using (var tran = conn.BeginTransaction(System.Data.IsolationLevel.Serializable))
                    {
                        try
                        {
                            cmd.Transaction = tran;

                            // Update Null Values
                            var nullToNonNull = table.FieldElementBindings.Join(currentColumns, bind => bind.ColumnName, col => col.ColumnName, (bind, col) => new { bind, col }, StringComparer.OrdinalIgnoreCase)
                                                .Where(match => match.bind.DataElement != null && match.bind.DataElement.AllowDbNull == false && match.col.AllowDbNull == true)
                                                .Select(match => match.bind)
                                                .ToArray();

                            if (nullToNonNull.Any())
                            {
                                cmd.CommandText = string.Format("UPDATE `{0}` SET {1} WHERE {2}"
                                                                , table.TableName
                                                                , string.Join(", ", nullToNonNull.Select(bind => string.Format("`{0}` = IFNULL(`{0}`, {1})", bind.ColumnName, bind.ValueType == typeof(DateTime)
                                                                                                                               ? "'2000-01-01 00:00:00'"
                                                                                                                               : bind.ValueType == typeof(string)
                                                                                                                               ? "''"
                                                                                                                               : "0")))
                                                                , string.Join(" OR ", nullToNonNull.Select(bind => string.Format("`{0}` IS NULL", bind.ColumnName)))
                                                                );
                                cmd.ExecuteNonQuery();
                            }

                            // Alter Table
                            cmd.CommandText = string.Format("ALTER TABLE `{0}` {1}", table.TableName, string.Join(", \n", columnDefs));
                            cmd.ExecuteNonQuery();

                            tran.Commit();
                        }
                        catch (Exception e)
                        {
                            tran.Rollback();
                            if (log.IsDebugEnabled)
                            {
                                log.Debug("AlterTableImpl: ", e);
                            }

                            if (log.IsWarnEnabled)
                            {
                                log.WarnFormat("AlterTableImpl: Error While Altering Table {0}, rollback...\n{1}", table.TableName, e);
                            }

                            throw;
                        }
                    }
                }
            }
        }
예제 #27
0
		/// <summary>
		/// Convert a Table ElementBinding to Database Type string (Upper)
		/// </summary>
		/// <param name="bind">ElementBindind to Convert</param>
		/// <param name="table">DataTableHandler for Special cases</param>
		/// <returns>Database Type string ToUpper</returns>
		protected virtual string GetDatabaseType(ElementBinding bind, DataTableHandler table)
		{
			string type = null;
			// Check Value Type
			if (bind.ValueType == typeof(char))
			{
				type = "UNSIGNED SMALLINT(5)";
			}
			else if (bind.ValueType == typeof(sbyte))
			{
				// override to prevent byte conversion
				type = "SMALLINT(3)";
			}
			else if (bind.ValueType == typeof(short))
			{
				type = "SMALLINT(6)";
			}
			else if (bind.ValueType == typeof(int))
			{
				type = "INT(11)";
			}
			else if (bind.ValueType == typeof(long))
			{
				type = "BIGINT(20)";
			}
			else if (bind.ValueType == typeof(byte))
			{
				type = "UNSIGNED TINYINT(3)";
			}
			else if (bind.ValueType == typeof(ushort))
			{
				type = "UNSIGNED SMALLINT(5)";
			}
			else if (bind.ValueType == typeof(uint))
			{
				type = "UNSIGNED INT(10)";
			}
			else if (bind.ValueType == typeof(ulong))
			{
				type = "UNSIGNED BIGINT(20)";
			}
			else if (bind.ValueType == typeof(bool))			  
			{
				type = "TINYINT(1)";
			}
			else if (bind.ValueType == typeof(DateTime))
			{
				type = "DATETIME";
			}
			else if (bind.ValueType == typeof(float))
			{
				type = "FLOAT";
			}
			else if (bind.ValueType == typeof(double))
			{
				type = "DOUBLE";
			}
			else if (bind.ValueType == typeof(string))
			{
				if (bind.DataElement != null && bind.DataElement.Varchar > 0)
				{
					type = string.Format("VARCHAR({0})", bind.DataElement.Varchar);
				}
				else if (table.Table.PrimaryKey.Any(key => key.ColumnName.Equals(bind.ColumnName, StringComparison.OrdinalIgnoreCase))
				         || table.Table.Constraints.OfType<UniqueConstraint>().Any(cstrnt => cstrnt.Columns.Any(col => col.ColumnName.Equals(bind.ColumnName, StringComparison.OrdinalIgnoreCase)))
				         || (table.Table.ExtendedProperties["INDEXES"] != null && (table.Table.ExtendedProperties["INDEXES"] as Dictionary<string, DataColumn[]>)
				             .Any(kv => kv.Value.Any(col => col.ColumnName.Equals(bind.ColumnName, StringComparison.OrdinalIgnoreCase)))))
				{
					// If is in Primary Key Constraint or Unique Constraint or Index row, cast to Varchar.
					type = "VARCHAR(255)";
				}
				else
				{
					type = "TEXT";
				}
			}
			else
			{
				type = "BLOB";
			}
			
			if (bind.PrimaryKey != null && bind.PrimaryKey.AutoIncrement)
				type = "INTEGER";
			
			return type;
		}
예제 #28
0
        /// <summary>
        /// Alter an Existing Table to Match DataTableHandler Definition
        /// </summary>
        /// <param name="currentColumns">Current Existing Columns</param>
        /// <param name="table">DataTableHandler to Implement</param>
        protected void AlterTable(IEnumerable <TableRowBindind> currentColumns, DataTableHandler table)
        {
            // If Column are not modified Alter Table is not needed...
            if (!CheckTableAlteration(currentColumns, table))
            {
                // Table not Altered check for Indexes and return
                CheckTableIndexAlteration(table);
                return;
            }

            if (log.IsInfoEnabled)
            {
                log.InfoFormat("Altering Table {0} this could take a few minutes...", table.TableName);
            }

            var currentIndexes = new List <string>();

            try
            {
                ExecuteSelectImpl("SELECT name FROM sqlite_master WHERE type == 'index' AND sql is not null AND tbl_name == @tableName",
                                  new QueryParameter("@tableName", table.TableName),
                                  reader =>
                {
                    while (reader.Read())
                    {
                        currentIndexes.Add(reader.GetString(0));
                    }
                }, IsolationLevel.DEFAULT);
            }
            catch (Exception e)
            {
                if (log.IsDebugEnabled)
                {
                    log.Debug("AlterTableImpl: ", e);
                }

                if (log.IsWarnEnabled)
                {
                    log.WarnFormat("AlterTableImpl: Error While Altering Table {0}, no modifications...", table.TableName);
                }

                throw;
            }

            using (var conn = new SQLiteConnection(ConnectionString))
            {
                conn.Open();
                using (var tran = conn.BeginTransaction(System.Data.IsolationLevel.ReadCommitted))
                {
                    try
                    {
                        // Delete Indexes
                        foreach (var index in currentIndexes)
                        {
                            using (var command = new SQLiteCommand(string.Format("DROP INDEX `{0}`", index), conn))
                            {
                                command.Transaction = tran;
                                command.ExecuteNonQuery();
                            }
                        }

                        // Rename Table
                        using (var command = new SQLiteCommand(string.Format("ALTER TABLE `{0}` RENAME TO `{0}_bkp`", table.TableName), conn))
                        {
                            command.Transaction = tran;
                            command.ExecuteNonQuery();
                        }

                        // Create New Table
                        using (var command = new SQLiteCommand(GetTableDefinition(table), conn))
                        {
                            command.Transaction = tran;
                            command.ExecuteNonQuery();
                        }

                        // Create Indexes
                        foreach (var index in GetIndexesDefinition(table))
                        {
                            using (var command = new SQLiteCommand(index, conn))
                            {
                                command.Transaction = tran;
                                command.ExecuteNonQuery();
                            }
                        }

                        // Copy Data, Convert Null to Default when needed...
                        var matchingColumns = table.FieldElementBindings.Join(currentColumns, bind => bind.ColumnName, col => col.ColumnName, (bind, col) => new { bind, col }, StringComparer.OrdinalIgnoreCase);
                        var columns         = matchingColumns.Select(match => {
                            if (match.bind.DataElement != null && match.bind.DataElement.AllowDbNull == false && match.col.AllowDbNull == true)
                            {
                                if (match.bind.ValueType == typeof(DateTime))
                                {
                                    return new { Target = match.bind.ColumnName, Source = string.Format("IFNULL(`{0}`, {1})", match.bind.ColumnName, "'2000-01-01 00:00:00'") }
                                }
                                ;
                                if (match.bind.ValueType == typeof(string))
                                {
                                    return new { Target = match.bind.ColumnName, Source = string.Format("IFNULL(`{0}`, {1})", match.bind.ColumnName, "''") }
                                }
                                ;

                                return(new { Target = match.bind.ColumnName, Source = string.Format("IFNULL(`{0}`, {1})", match.bind.ColumnName, "0") });
                            }

                            return(new { Target = match.bind.ColumnName, Source = string.Format("`{0}`", match.bind.ColumnName) });
                        });

                        using (var command = new SQLiteCommand(string.Format("INSERT INTO `{0}` ({1}) SELECT {2} FROM `{0}_bkp`", table.TableName, string.Join(", ", columns.Select(c => c.Target)), string.Join(", ", columns.Select(c => c.Source))), conn))
                        {
                            if (log.IsDebugEnabled)
                            {
                                log.DebugFormat("AlterTableImpl, Insert/Select: {0}", command.CommandText);
                            }

                            command.Transaction = tran;
                            command.ExecuteNonQuery();
                        }

                        // Drop Renamed Table
                        using (var command = new SQLiteCommand(string.Format("DROP TABLE `{0}_bkp`", table.TableName), conn))
                        {
                            command.Transaction = tran;
                            command.ExecuteNonQuery();
                        }

                        tran.Commit();
                        if (log.IsInfoEnabled)
                        {
                            log.InfoFormat("AlterTableImpl: Table {0} Altered...", table.TableName);
                        }
                    }
                    catch (Exception e)
                    {
                        tran.Rollback();
                        if (log.IsDebugEnabled)
                        {
                            log.Debug("AlterTableImpl: ", e);
                        }

                        if (log.IsWarnEnabled)
                        {
                            log.WarnFormat("AlterTableImpl: Error While Altering Table {0}, rollback...\n{1}", table.TableName, e);
                        }

                        throw;
                    }
                }
            }
        }
예제 #29
0
		/// <summary>
		/// Check if this Table need Alteration
		/// </summary>
		/// <param name="currentColumns">Current Existing Columns</param>
		/// <param name="table">DataTableHandler to Implement</param>
		protected bool CheckTableAlteration(IEnumerable<TableRowBindind> currentColumns, DataTableHandler table)
		{
			// Check for Any differences in Columns
			if (table.FieldElementBindings
			    .Any(bind => {
			         	var column = currentColumns.FirstOrDefault(col => col.ColumnName.Equals(bind.ColumnName, StringComparison.OrdinalIgnoreCase));
			         	
			         	if (column != null)
			         	{
			         		// Check Null
			         		if ((bind.DataElement != null && bind.DataElement.AllowDbNull) != column.AllowDbNull)
			         			return true;
			         		
			         		// Check Type
			         		if (!GetDatabaseType(bind, table).Equals(column.ColumnType, StringComparison.OrdinalIgnoreCase))
			         			return true;
			         		
			         		// Field are identical
			         		return false;
			         	}
			         	// Field missing
			         	return true;
			         }))
				return true;
			
			// Check for Any Difference in Primary Keys
			if (table.Table.PrimaryKey.Length != currentColumns.Count(col => col.Primary)
				|| table.Table.PrimaryKey.Any(pk => {
			                                  	var column = currentColumns.FirstOrDefault(col => col.ColumnName.Equals(pk.ColumnName, StringComparison.OrdinalIgnoreCase));
			                                  	
			                                  	if (column != null && column.Primary)
			                                  		return false;
			                                  	
			                                  	return true;
			                                  }))
				return true;
			
			// No Alteration Needed
			return false;
		}
예제 #30
0
		/// <summary>
		/// Get Database Column Definition for ElementBinding
		/// </summary>
		/// <param name="bind">ElementBinding for Column Definition</param>
		/// <param name="table">DataTableHanlder for Special cases</param>
		/// <returns>Column Definitnion string.</returns>
		protected virtual string GetColumnDefinition(ElementBinding bind, DataTableHandler table)
		{
			string type = GetDatabaseType(bind, table);
			string defaultDef = null;
						
			// Check for Default Value depending on Constraints and Type
			if (bind.PrimaryKey != null && bind.PrimaryKey.AutoIncrement)
			{
				defaultDef = "NOT NULL PRIMARY KEY AUTOINCREMENT";
			}
			else if (bind.DataElement != null && bind.DataElement.AllowDbNull)
			{
				defaultDef = "DEFAULT NULL";
			}
			else if (bind.ValueType == typeof(DateTime))
			{
				defaultDef = "NOT NULL DEFAULT '2000-01-01 00:00:00'";
			}
			else
			{
				defaultDef = "NOT NULL";
			}
			
			// Force Case Insensitive Text Field to Match MySQL Behavior 
			if (bind.ValueType == typeof(string))
				defaultDef = string.Format("{0} {1}", defaultDef, "COLLATE NOCASE");
			
			return string.Format("`{0}` {1} {2}", bind.ColumnName, type, defaultDef);
		}
예제 #31
0
		/// <summary>
		/// Create a New Table from DataTableHandler Definition
		/// </summary>
		/// <param name="table">DataTableHandler Definition to Create in Database</param>
		protected void CreateTable(DataTableHandler table)
		{
			ExecuteNonQueryImpl(GetTableDefinition(table));
			
			foreach (var commands in GetIndexesDefinition(table))
				ExecuteNonQueryImpl(commands);
		}
예제 #32
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.");
        }
예제 #33
0
        /// <summary>
        /// Alter an Existing Table to Match DataTableHandler Definition
        /// </summary>
        /// <param name="currentColumns">Current Existing Columns</param>
        /// <param name="table">DataTableHandler to Implement</param>
        protected void AlterTable(IEnumerable <TableRowBindind> currentColumns, DataTableHandler table)
        {
            // If Column are not modified Alter Table is not needed...
            if (!CheckTableAlteration(currentColumns, table))
            {
                // Table not Altered check for Indexes and return
                CheckTableIndexAlteration(table);
                return;
            }

            if (log.IsInfoEnabled)
            {
                log.InfoFormat("Altering Table {0} this could take a few minutes...", table.TableName);
            }

            var currentIndexes = new List <string>();

            try
            {
                ExecuteSelectImpl("SELECT name FROM sqlite_master WHERE type == 'index' AND sql is not null AND tbl_name == @tableName",
                                  new QueryParameter("@tableName", table.TableName),
                                  reader =>
                {
                    while (reader.Read())
                    {
                        currentIndexes.Add(reader.GetString(0));
                    }
                }, IsolationLevel.DEFAULT);
            }
            catch (Exception e)
            {
                if (log.IsDebugEnabled)
                {
                    log.Debug("AlterTableImpl: ", e);
                }

                if (log.IsWarnEnabled)
                {
                    log.WarnFormat("AlterTableImpl: Error While Altering Table {0}, no modifications...", table.TableName);
                }

                throw;
            }

            using (var conn = new SQLiteConnection(ConnectionString))
            {
                conn.Open();
                using (var tran = conn.BeginTransaction(System.Data.IsolationLevel.ReadCommitted))
                {
                    try
                    {
                        // Delete Indexes
                        foreach (var index in currentIndexes)
                        {
                            using (var command = new SQLiteCommand(string.Format("DROP INDEX `{0}`", index), conn))
                            {
                                command.Transaction = tran;
                                command.ExecuteNonQuery();
                            }
                        }

                        // Rename Table
                        using (var command = new SQLiteCommand(string.Format("ALTER TABLE `{0}` RENAME TO `{0}_bkp`", table.TableName), conn))
                        {
                            command.Transaction = tran;
                            command.ExecuteNonQuery();
                        }

                        // Create New Table
                        using (var command = new SQLiteCommand(GetTableDefinition(table), conn))
                        {
                            command.Transaction = tran;
                            command.ExecuteNonQuery();
                        }

                        // Create Indexes
                        foreach (var index in GetIndexesDefinition(table))
                        {
                            using (var command = new SQLiteCommand(index, conn))
                            {
                                command.Transaction = tran;
                                command.ExecuteNonQuery();
                            }
                        }

                        // Copy Data
                        var columns = table.FieldElementBindings.Where(bind => currentColumns.Any(col => col.ColumnName.Equals(bind.ColumnName, StringComparison.OrdinalIgnoreCase)))
                                      .Select(bind => string.Format("`{0}`", bind.ColumnName));
                        using (var command = new SQLiteCommand(string.Format("INSERT INTO `{0}` ({1}) SELECT {1} FROM `{0}_bkp`", table.TableName, string.Join(", ", columns)), conn))
                        {
                            command.Transaction = tran;
                            command.ExecuteNonQuery();
                        }

                        // Drop Renamed Table
                        using (var command = new SQLiteCommand(string.Format("DROP TABLE `{0}_bkp`", table.TableName), conn))
                        {
                            command.Transaction = tran;
                            command.ExecuteNonQuery();
                        }

                        tran.Commit();
                        if (log.IsInfoEnabled)
                        {
                            log.InfoFormat("AlterTableImpl: Table {0} Altered...", table.TableName);
                        }
                    }
                    catch (Exception e)
                    {
                        tran.Rollback();
                        if (log.IsDebugEnabled)
                        {
                            log.Debug("AlterTableImpl: ", e);
                        }

                        if (log.IsWarnEnabled)
                        {
                            log.WarnFormat("AlterTableImpl: Error While Altering Table {0}, rollback...\n{1}", table.TableName, e);
                        }
                    }
                }
            }
        }
예제 #34
0
        /// <summary>
        /// Convert a Table ElementBinding to Database Type string (Upper)
        /// </summary>
        /// <param name="bind">ElementBindind to Convert</param>
        /// <param name="table">DataTableHandler for Special cases</param>
        /// <returns>Database Type string ToUpper</returns>
        protected virtual string GetDatabaseType(ElementBinding bind, DataTableHandler table)
        {
            string type = null;

            // Check Value Type
            if (bind.ValueType == typeof(char))
            {
                type = "SMALLINT(5) UNSIGNED";
            }
            else if (bind.ValueType == typeof(DateTime))
            {
                type = "DATETIME";
            }
            else if (bind.ValueType == typeof(sbyte))
            {
                type = "TINYINT(3)";
            }
            else if (bind.ValueType == typeof(short))
            {
                type = "SMALLINT(6)";
            }
            else if (bind.ValueType == typeof(int))
            {
                type = "INT(11)";
            }
            else if (bind.ValueType == typeof(long))
            {
                type = "BIGINT(20)";
            }
            else if (bind.ValueType == typeof(byte))
            {
                type = "TINYINT(3) UNSIGNED";
            }
            else if (bind.ValueType == typeof(ushort))
            {
                type = "SMALLINT(5) UNSIGNED";
            }
            else if (bind.ValueType == typeof(uint))
            {
                type = "INT(10) UNSIGNED";
            }
            else if (bind.ValueType == typeof(ulong))
            {
                type = "BIGINT(20) UNSIGNED";
            }
            else if (bind.ValueType == typeof(float))
            {
                // Float Value have less precision than C# Single.
                type = "DOUBLE";
            }
            else if (bind.ValueType == typeof(double))
            {
                type = "DOUBLE";
            }
            else if (bind.ValueType == typeof(bool))
            {
                type = "TINYINT(1)";
            }
            else if (bind.ValueType == typeof(string))
            {
                if (bind.DataElement != null && bind.DataElement.Varchar > 0)
                {
                    type = string.Format("VARCHAR({0})", bind.DataElement.Varchar);
                }
                else if (table.Table.PrimaryKey.Any(key => key.ColumnName.Equals(bind.ColumnName, StringComparison.OrdinalIgnoreCase)) ||
                         table.Table.Constraints.OfType <UniqueConstraint>().Any(cstrnt => cstrnt.Columns.Any(col => col.ColumnName.Equals(bind.ColumnName, StringComparison.OrdinalIgnoreCase))) ||
                         (table.Table.ExtendedProperties["INDEXES"] != null && (table.Table.ExtendedProperties["INDEXES"] as Dictionary <string, DataColumn[]>)
                          .Any(kv => kv.Value.Any(col => col.ColumnName.Equals(bind.ColumnName, StringComparison.OrdinalIgnoreCase)))))
                {
                    // If is in Primary Key Constraint or Unique Constraint or Index row, cast to Varchar.
                    type = "VARCHAR(255)";
                }
                else
                {
                    type = "TEXT";
                }
            }
            else
            {
                type = "BLOB";
            }

            if (bind.PrimaryKey != null && bind.PrimaryKey.AutoIncrement)
            {
                if (bind.ValueType == typeof(ulong) || bind.ValueType == typeof(long))
                {
                    type = "BIGINT(20)";
                }
                else
                {
                    type = "INT(11)";
                }
            }

            return(type);
        }
예제 #35
0
		/// <summary>
		/// Get Database Column Definition for ElementBinding
		/// </summary>
		/// <param name="bind">ElementBinding for Column Definition</param>
		/// <param name="table">DataTableHanlder for Special cases</param>
		/// <returns>Column Definitnion string.</returns>
		protected virtual string GetColumnDefinition(ElementBinding bind, DataTableHandler table)
		{
			string type = GetDatabaseType(bind, table);
			string defaultDef = null;
						
			// Check for Default Value depending on Constraints and Type
			if (bind.PrimaryKey != null && bind.PrimaryKey.AutoIncrement)
			{				
				defaultDef = "NOT NULL AUTO_INCREMENT";
			}
			else if (bind.DataElement != null && bind.DataElement.AllowDbNull)
			{
				defaultDef = "DEFAULT NULL";
			}
			else if (bind.ValueType == typeof(DateTime))
			{
				defaultDef = "NOT NULL DEFAULT '2000-01-01 00:00:00'";
			}
			else
			{
				defaultDef = "NOT NULL";
			}
			
			return string.Format("`{0}` {1} {2}", bind.ColumnName, type, defaultDef);
		}