public void TestTableWithBrokenPrimaryKey() { // Destroy previous table Database.ExecuteNonQuery(string.Format("DROP TABLE IF EXISTS `{0}`", AttributesUtils.GetTableName(typeof(TestTableWithBrokenPrimaryV1)))); // Create Table Database.RegisterDataObject(typeof(TestTableWithBrokenPrimaryV1)); // Break Primary Key Database.ExecuteNonQuery(string.Format("ALTER TABLE `{0}` DROP PRIMARY KEY", AttributesUtils.GetTableName(typeof(TestTableWithBrokenPrimaryV1)))); // Get a new Database Object to Trigger Migration var DatabaseV2 = GetDatabaseV2; // Trigger False Migration DatabaseV2.RegisterDataObject(typeof(TestTableWithBrokenPrimaryV2)); var adds = DatabaseV2.AddObject(new [] { new TestTableWithBrokenPrimaryV2 { PrimaryKey = 1 }, new TestTableWithBrokenPrimaryV2 { PrimaryKey = 1 }, }); Assert.IsFalse(adds, "Primary Key was not restored and duplicate key were inserted !"); }
public void TestTableMigrationToNonNullValue() { // Destroy previous table Database.ExecuteNonQuery(string.Format("DROP TABLE IF EXISTS `{0}`", AttributesUtils.GetTableName(typeof(TestTableMigrationNullToNonNull)))); // Get a new Database Object to Trigger Migration var DatabaseV2 = GetDatabaseV2; Database.RegisterDataObject(typeof(TestTableMigrationNullToNonNull)); Database.DeleteObject(Database.SelectAllObjects <TestTableMigrationNullToNonNull>()); Assert.IsEmpty(Database.SelectAllObjects <TestTableMigrationNullToNonNull>(), "Test Table TestTableMigrationNullToNonNull should be empty to begin this tests."); var objs = new [] { "TestObj1", null, "TestObj3" }.Select((ent, i) => new TestTableMigrationNullToNonNull { StringValue = ent }).ToArray(); Database.AddObject(objs); CollectionAssert.AreEquivalent(objs.Select(obj => obj.StringValue), Database.SelectAllObjects <TestTableMigrationNullToNonNull>().Select(obj => obj.StringValue), "Test Table TestTableMigrationNullToNonNull Entries should be available for this test to run."); // Trigger False Migration DatabaseV2.RegisterDataObject(typeof(TestTableMigrationNullFromNull)); var newObjs = DatabaseV2.SelectAllObjects <TestTableMigrationNullFromNull>().ToArray(); CollectionAssert.AreEquivalent(objs.Select(obj => obj.StringValue ?? string.Empty), newObjs.Select(obj => obj.StringValue), "Test Table Migration to TestTableMigrationNullFromNull should retrieve similar values that created ones..."); CollectionAssert.AreEqual(Enumerable.Repeat(0, 3), newObjs.Select(obj => obj.IntValue), "Test Table Migration to TestTableMigrationNullFromNull should retrieve all default int value to 0..."); }
public void TestTableMigrationChangingPrimaryKey() { // Destroy previous table Database.ExecuteNonQuery(string.Format("DROP TABLE IF EXISTS `{0}`", AttributesUtils.GetTableName(typeof(TestTableWithPrimaryChangingV1)))); // Get a new Database Object to Trigger Migration var DatabaseV2 = GetDatabaseV2; Database.RegisterDataObject(typeof(TestTableWithPrimaryChangingV1)); Database.DeleteObject(Database.SelectAllObjects <TestTableWithPrimaryChangingV1>()); Assert.IsEmpty(Database.SelectAllObjects <TestTableWithPrimaryChangingV1>(), "Test Table TestTableWithPrimaryChangingV1 should be empty to begin this tests."); var objs = new [] { "TestObj1", "TestObj2", "TestObj3" }.Select((ent, i) => new TestTableWithPrimaryChangingV1 { PrimaryKey = i, Value = ent }).ToArray(); Database.AddObject(objs); CollectionAssert.AreEquivalent(objs.Select(obj => obj.Value), Database.SelectAllObjects <TestTableWithPrimaryChangingV1>().Select(obj => obj.Value), "Test Table TestTableWithPrimaryChangingV1 Entries should be available for this test to run."); // Trigger False Migration DatabaseV2.RegisterDataObject(typeof(TestTableWithPrimaryChangingV2)); var newObjs = DatabaseV2.SelectAllObjects <TestTableWithPrimaryChangingV2>().ToArray(); CollectionAssert.AreEquivalent(objs.Select(obj => obj.Value), newObjs.Select(obj => obj.Value), "Test Table Migration to TestTableWithPrimaryChangingV2 should retrieve similar values that created ones..."); CollectionAssert.AreEquivalent(objs.Select(obj => obj.PrimaryKey), newObjs.Select(obj => obj.PrimaryKey), "Test Table Migration to TestTableWithPrimaryChangingV2 should retrieve similar values that created ones..."); }
/// <summary> /// Helper to Retrieve Table Handler from Object Type /// Return Real Table Handler for Modifications Queries /// </summary> /// <param name="objectType">Object Type</param> /// <returns>DataTableHandler for this Object Type or null.</returns> protected DataTableHandler GetTableHandler(Type objectType) { var tableName = AttributesUtils.GetTableName(objectType); DataTableHandler handler; return(TableDatasets.TryGetValue(tableName, out handler) ? handler : null); }
public void TestTableMigrationWithDifferentTypes() { // Destroy previous table Database.ExecuteNonQuery(string.Format("DROP TABLE IF EXISTS `{0}`", AttributesUtils.GetTableName(typeof(TestTableDifferentTypesV1)))); // Get a new Database Object to Trigger Migration var DatabaseV2 = GetDatabaseV2; Database.RegisterDataObject(typeof(TestTableDifferentTypesV1)); Database.DeleteObject(Database.SelectAllObjects <TestTableDifferentTypesV1>()); Assert.IsEmpty(Database.SelectAllObjects <TestTableDifferentTypesV1>(), "Test Table TestTableDifferentTypesV1 should be empty to begin this tests."); var datenow = DateTime.UtcNow; var now = new DateTime(datenow.Year, datenow.Month, datenow.Day, datenow.Hour, datenow.Minute, datenow.Second); var objs = new [] { "TestObj1", "TestObj2", "TestObj3" }.Select((ent, i) => new TestTableDifferentTypesV1 { StringValue = ent, IntValue = i, DateValue = now }).ToArray(); Database.AddObject(objs); CollectionAssert.AreEquivalent(objs.Select(obj => obj.StringValue), Database.SelectAllObjects <TestTableDifferentTypesV1>().Select(obj => obj.StringValue), "Test Table TestTableDifferentTypesV1 Entries should be available for this test to run."); // Trigger False Migration DatabaseV2.RegisterDataObject(typeof(TestTableDifferentTypesV2)); var newObjs = DatabaseV2.SelectAllObjects <TestTableDifferentTypesV2>().ToArray(); CollectionAssert.AreEquivalent(objs.Select(obj => obj.StringValue), newObjs.Select(obj => obj.StringValue), "Test Table Migration to TestTableDifferentTypesV2 should retrieve similar values that created ones..."); CollectionAssert.AreEquivalent(objs.Select(obj => obj.IntValue), newObjs.Select(obj => obj.IntValue), "Test Table Migration to TestTableDifferentTypesV2 should retrieve similar values that created ones..."); CollectionAssert.AreEquivalent(objs.Select(obj => obj.DateValue), newObjs.Select(obj => Convert.ToDateTime(obj.DateValue)), "Test Table Migration to TestTableDifferentTypesV2 should retrieve similar values that created ones..."); // Trigger another Migraiton DatabaseV2 = GetDatabaseV2; DatabaseV2.RegisterDataObject(typeof(TestTableDifferentTypesV1)); var newerObjs = DatabaseV2.SelectAllObjects <TestTableDifferentTypesV1>().ToArray(); CollectionAssert.AreEquivalent(objs.Select(obj => obj.StringValue), newerObjs.Select(obj => obj.StringValue), "Test Table Migration to TestTableDifferentTypesV1 should retrieve similar values that created ones..."); CollectionAssert.AreEquivalent(objs.Select(obj => obj.IntValue), newerObjs.Select(obj => obj.IntValue), "Test Table Migration to TestTableDifferentTypesV1 should retrieve similar values that created ones..."); CollectionAssert.AreEquivalent(objs.Select(obj => obj.DateValue), newerObjs.Select(obj => obj.DateValue), "Test Table Migration to TestTableDifferentTypesV1 should retrieve similar values that created ones..."); }
public void TestTableMigrationFromNoPrimaryKeyToAutoInc() { // Destroy previous table Database.ExecuteNonQuery(string.Format("DROP TABLE IF EXISTS `{0}`", AttributesUtils.GetTableName(typeof(TestTableWithNoPrimaryV1)))); // Get a new Database Object to Trigger Migration var DatabaseV2 = GetDatabaseV2; Database.RegisterDataObject(typeof(TestTableWithNoPrimaryV1)); Database.DeleteObject(Database.SelectAllObjects <TestTableWithNoPrimaryV1>()); Assert.IsEmpty(Database.SelectAllObjects <TestTableWithNoPrimaryV1>(), "Test Table TestTableWithNoPrimaryV1 should be empty to begin this tests."); var objs = new [] { "TestObj1", "TestObj2", "TestObj3" }.Select(ent => new TestTableWithNoPrimaryV1 { Value = ent }).ToArray(); Database.AddObject(objs); CollectionAssert.AreEquivalent(objs.Select(obj => obj.Value), Database.SelectAllObjects <TestTableWithNoPrimaryV1>().Select(obj => obj.Value), "Test Table TestTableWithNoPrimaryV1 Entries should be available for this test to run."); // Trigger False Migration DatabaseV2.RegisterDataObject(typeof(TestTableWithNoPrimaryV2)); var newObjs = DatabaseV2.SelectAllObjects <TestTableWithNoPrimaryV2>().ToArray(); CollectionAssert.AreEquivalent(objs.Select(obj => obj.Value), newObjs.Select(obj => obj.Value), "Test Table Migration to TestTableWithNoPrimaryV2 should retrieve similar values that created ones..."); Assert.IsTrue(newObjs.All(obj => obj.PrimaryKey != 0), "Test Table Migration to TestTableWithNoPrimaryV2 should have created and populated Primary Key Auto Increment."); // Trigger Another Migration DatabaseV2 = GetDatabaseV2; DatabaseV2.RegisterDataObject(typeof(TestTableWithNoPrimaryV3)); var newerObjs = DatabaseV2.SelectAllObjects <TestTableWithNoPrimaryV3>().ToArray(); CollectionAssert.AreEquivalent(objs.Select(obj => obj.Value), newerObjs.Select(obj => obj.Value), "Test Table Migration to TestTableWithNoPrimaryV3 should retrieve similar values that created ones..."); Assert.IsTrue(newerObjs.All(obj => obj.PrimaryKey2 != 0), "Test Table Migration to TestTableWithNoPrimaryV3 should have created and populated Primary Key Auto Increment."); }
/// <summary> /// Register Data Object Type if not already Registered /// </summary> /// <param name="dataObjectType">DataObject Type</param> public override void RegisterDataObject(Type dataObjectType) { var tableName = AttributesUtils.GetTableOrViewName(dataObjectType); var isView = AttributesUtils.GetViewName(dataObjectType) != null; var viewAs = AttributesUtils.GetViewAs(dataObjectType); DataTableHandler existingHandler; if (TableDatasets.TryGetValue(tableName, out existingHandler)) { if (dataObjectType != existingHandler.ObjectType) { throw new DatabaseException(string.Format("Table Handler Duplicate for Type: {2}, Table Name '{0}' Already Registered with Type : {1}", tableName, existingHandler.ObjectType, dataObjectType)); } return; } var dataTableHandler = new DataTableHandler(dataObjectType); try { if (isView) { if (!string.IsNullOrEmpty(viewAs)) { ExecuteNonQueryImpl(string.Format("DROP VIEW IF EXISTS `{0}`", tableName)); ExecuteNonQueryImpl(string.Format("CREATE VIEW `{0}` AS {1}", tableName, string.Format(viewAs, string.Format("`{0}`", AttributesUtils.GetTableName(dataObjectType))))); } } else { CheckOrCreateTableImpl(dataTableHandler); } TableDatasets.Add(tableName, dataTableHandler); // Init PreCache if (dataTableHandler.UsesPreCaching) { var primary = dataTableHandler.PrimaryKeys.Single(); var objects = SelectObjectsImpl(dataTableHandler, "", new [] { new QueryParameter[] { } }, Transaction.IsolationLevel.DEFAULT).First(); foreach (var obj in objects) { dataTableHandler.SetPreCachedObject(primary.GetValue(obj), obj); } } } catch (Exception e) { if (Log.IsErrorEnabled) { Log.ErrorFormat("RegisterDataObject: Error While Registering Table \"{0}\"\n{1}", tableName, e); } } }
/// <summary> /// Check For UnloadXML Args /// </summary> /// <param name="client"></param> /// <param name="args"></param> public void OnCommand(GameClient client, string[] args) { if (args.Length < 2) { DisplaySyntax(client); return; } var types = LoaderUnloaderXML.GetAllDataTableTypes(); var argTable = args[1]; // Prepare Write Path var directory = Path.IsPathRooted(XML_UNLOAD_DB_DIRECTORY) ? XML_UNLOAD_DB_DIRECTORY : string.Format("{0}{1}scripts{1}{2}", GameServer.Instance.Configuration.RootDirectory, Path.DirectorySeparatorChar, XML_UNLOAD_DB_DIRECTORY); if (!Directory.Exists(directory)) { Directory.CreateDirectory(directory); } switch (argTable) { case "full": foreach (Type table in types) { var dir = directory; var workingType = table; System.Threading.Tasks.Task.Factory.StartNew(() => LoaderUnloaderXML.UnloadXMLTable(workingType, dir)); } break; default: var finddir = directory; var findType = types.FirstOrDefault(t => t.Name.Equals(argTable, StringComparison.OrdinalIgnoreCase) || AttributesUtils.GetTableName(t).Equals(argTable, StringComparison.OrdinalIgnoreCase)); if (findType == null) { DisplaySyntax(client); if (log.IsInfoEnabled) { log.InfoFormat("Could not find table to unload with search string : {0}", argTable); } return; } System.Threading.Tasks.Task.Factory.StartNew(() => LoaderUnloaderXML.UnloadXMLTable(findType, finddir)); break; } }
/// <summary> /// Unload a DataObject Type to XML File /// </summary> /// <param name="t"></param> public static void UnloadXMLTable(Type t, string directory) { if (t == null || !typeof(DataObject).IsAssignableFrom(t)) { if (log.IsInfoEnabled) { log.InfoFormat("Null Type or Incompatible Type in UnloadXMLTable Call: {0}", Environment.StackTrace); } } try { // Get all object "Method" Through Reflection var classMethod = GameServer.Database.GetType().GetMethod("SelectAllObjects", Type.EmptyTypes); var genericMethod = classMethod.MakeGenericMethod(t); // Get Table Name var attrib = t.GetCustomAttributes <DataTable>(false); if (attrib.Any()) { var tableName = AttributesUtils.GetTableName(t); var path = string.Format("{0}{1}{2}.xml", directory, Path.DirectorySeparatorChar, tableName); if (log.IsInfoEnabled) { log.InfoFormat("Unloading Table {0} - To file {1}", tableName, path); } var objects = (IEnumerable)genericMethod.Invoke(GameServer.Database, new object[] { }); try { // Try Sorting them ! var remarkables = DatabaseUtils.GetRemarkableMembers(t, true); if (remarkables.Length > 0) { var firstOrder = objects.Cast <DataObject>().OrderBy(o => remarkables.First().GetValue(o)); foreach (var remarkable in remarkables.Skip(1)) { var followingOrder = firstOrder.ThenBy(o => remarkable.GetValue(o)); firstOrder = followingOrder; } // Dynamic cast var castMethods = typeof(Enumerable).GetMethod("Cast"); var castGeneric = castMethods.MakeGenericMethod(t); var toArrayMethod = typeof(Enumerable).GetMethod("ToArray"); var toArrayGeneric = toArrayMethod.MakeGenericMethod(t); objects = (IEnumerable)toArrayGeneric.Invoke(null, new object[] { castGeneric.Invoke(null, new object[] { firstOrder }) }); } } catch (Exception oe) { if (log.IsWarnEnabled) { log.WarnFormat("Error while sorting Table {0} for XML Unload, Probably Unsorted... - {1}", tableName, oe); } } // Delete Older Files if (File.Exists(path)) { File.Delete(path); } // Write XML DataTable var serializer = GetXMLSerializer(t.MakeArrayType(), t); using (var writer = new StreamWriter(path)) { serializer.Serialize(writer, objects); } } } catch (Exception ex) { if (log.IsWarnEnabled) { log.WarnFormat("Could Not Unload Table {0}: {1}", t, ex); } } }