Skip to content

Commit

Permalink
Sets can no longer add new columns to the [cards] table. Values for n…
Browse files Browse the repository at this point in the history
…on-existing or not registered columns are simply dropped.

[cards] rebuild method now also supports adding columns and not just removing them.
Game installation makes use of that new ability to simplify adding games.
  • Loading branch information
David Schachtler authored and David Schachtler committed Apr 29, 2012
1 parent 2421e9c commit 7f0dbb7
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 75 deletions.
94 changes: 48 additions & 46 deletions octgnFX/Octgn.Data/DatabaseHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,54 +33,17 @@ public static bool ColumnExists(string tableName, string columnName, SQLiteConne
return (columnCache[tableName].Contains(columnName));
}

public static bool AddColumn(string tableName, string columnName, PropertyType type, SQLiteConnection connection)
{
bool ret = false;

using (SQLiteCommand com = connection.CreateCommand())
{
//YES I AM USING A STRINGBUILDER BECAUSE SQLITE WAS BEING A FUCKER. CHANGE IT IF YOU CAN MAKE IT WORK >_<
//BLOODY PARAMETERS FUCKING UP CONSTANTLY. SQLITE IS SHIT IN MY OPINION </endrage>
//TODO: Find out why ALTER commands do not always play nice with sqlitecommand parameters.
StringBuilder sb = new StringBuilder("ALTER TABLE @tablename ADD [@columnname] @type DEFAULT '@default'");
sb = sb.Replace("@tablename", tableName);
sb = sb.Replace("@columnname", columnName);
switch (type)
{
case PropertyType.String:
sb = sb.Replace("@type", "TEXT");
sb = sb.Replace("@default", "");
break;
case PropertyType.Integer:
sb = sb.Replace("@type", "INTEGER");
sb = sb.Replace("@default", "");
break;
case PropertyType.GUID:
sb = sb.Replace("@type", "TEXT");
sb = sb.Replace("@default", "00000000-0000-0000-0000-000000000000");
break;
default:
sb = sb.Replace("@type", "TEXT");
sb = sb.Replace("@default", "");
break;
}
com.CommandText = sb.ToString();
com.ExecuteNonQuery();
}

ret = ColumnExists(tableName, columnName, connection);
return (ret);
}

/// <summary>
/// Rebuilds the [cards] table to only include the columns specified in the [custom_properties] table.
/// </summary>
/// <param name="connection">The connection to use</param>
public static void RebuildCardsTable(SQLiteConnection connection)
{
#region Find out what properties are left
#region Find out what properties are registered
Dictionary<string, int> properties = new Dictionary<string, int>();
using (SQLiteCommand com = connection.CreateCommand())
{
// must be reverse order to maintain configuration in case of conflicting property definitions.
// i.e. [Power] INTEGER followed by [Power] TEXT
com.CommandText = @"SELECT * FROM [custom_properties] ORDER BY [real_id] DESC";
com.CommandText = @"SELECT * FROM [custom_properties]";
com.Prepare();
using (SQLiteDataReader reader = com.ExecuteReader())
{
Expand All @@ -90,7 +53,11 @@ public static void RebuildCardsTable(SQLiteConnection connection)
{
string propertyName = reader.GetString(columnOrdinalName);
int propertyType = reader.GetInt32(columnOrdinalType);
properties[propertyName] = propertyType;

if (!properties.ContainsKey(propertyName))
{
properties[propertyName] = propertyType;
}
}
}
}
Expand All @@ -110,7 +77,9 @@ [set_real_id] INTEGER REFERENCES [sets]([real_id]) ON DELETE CASCADE ON UPDATE C
[dependent] TEXT");

StringBuilder sqlCopy = new StringBuilder();
sqlCopy.Append("INSERT INTO [new_cards] SELECT [real_id], [id], [game_id], [set_real_id], [name], [image], [alternate], [dependent]");
StringBuilder sqlCopy2 = new StringBuilder();
sqlCopy.Append("INSERT INTO [new_cards] ([real_id], [id], [game_id], [set_real_id], [name], [image], [alternate], [dependent]");
sqlCopy2.Append(") SELECT [real_id], [id], [game_id], [set_real_id], [name], [image], [alternate], [dependent]");

foreach (String name in properties.Keys)
{
Expand All @@ -119,9 +88,15 @@ [set_real_id] INTEGER REFERENCES [sets]([real_id]) ON DELETE CASCADE ON UPDATE C
name,
properties[name] == 1 ? "INTEGER" : "TEXT",
""));
sqlCopy.Append(String.Format(", [{0}]", name));
if (ColumnExists("cards", name, connection))
{
// only copy columns that already exist
sqlCopy.Append(String.Format(", [{0}]", name));
sqlCopy2.Append(String.Format(", [{0}]", name));
}
}
sqlCreate.Append("\n);");
sqlCopy.Append(sqlCopy2.ToString());
sqlCopy.Append(" FROM [cards];");
#endregion

Expand All @@ -148,5 +123,32 @@ [set_real_id] INTEGER REFERENCES [sets]([real_id]) ON DELETE CASCADE ON UPDATE C
}
#endregion
}

/// <summary>
/// Returns a list of all column names registered with the specified game.
/// </summary>
/// <param name="game">The guid of the game</param>
/// <param name="connection">the connection to use</param>
/// <returns>A list of column names.</returns>
public static IList<String> GetCardProperties(Guid game, SQLiteConnection connection)
{
List<String> properties = new List<string>();

using (SQLiteCommand com = connection.CreateCommand())
{
com.CommandText = @"SELECT * FROM [custom_properties] WHERE game_id LIKE '@game_id'";
com.Parameters.AddWithValue("@game_id", game.ToString());
com.Prepare();
using (SQLiteDataReader reader = com.ExecuteReader())
{
while (reader.Read())
{
properties.Add(reader.GetString(reader.GetOrdinal("name")));
}
}
}

return properties;
}
}
}
48 changes: 24 additions & 24 deletions octgnFX/Octgn.Data/Game.cs
Original file line number Diff line number Diff line change
Expand Up @@ -437,33 +437,33 @@ private void InsertCard(CardModel card)
fields.Append("[id],[game_id],[set_real_id],[name],[image],[alternate],[dependent]");
values.Append("@id,@game_id,(SELECT real_id FROM sets WHERE id = @set_id LIMIT 1),@name,@image,@alternate,@dependent");

IList<string> columns = DatabaseHandler.GetCardProperties(this.Id, GamesRepository.DatabaseConnection);

foreach (KeyValuePair<string, object> pair in card.Properties)
{
fields.Append(string.Format(",[{0}]", pair.Key));
values.Append(string.Format(",@{0}", pair.Key.Replace(" ", "")));

string name = pair.Key;
PropertyType type = PropertyType.String;
object value = "";
if (pair.Value is string)
{
type = PropertyType.String;
value = (string)pair.Value;
}
else if (pair.Value is int)
{
type = PropertyType.Integer;
value = (int)pair.Value;
}
else
{
type = PropertyType.String;
value = (string)pair.Value;
}

if (!DatabaseHandler.ColumnExists("cards", name, GamesRepository.DatabaseConnection))
if (columns.Contains(pair.Key))
{
DatabaseHandler.AddColumn("cards", name, type, GamesRepository.DatabaseConnection);
fields.Append(string.Format(",[{0}]", pair.Key));
values.Append(string.Format(",@{0}", pair.Key.Replace(" ", "")));

string name = pair.Key;
PropertyType type = PropertyType.String;
object value = "";
if (pair.Value is string)
{
type = PropertyType.String;
value = (string)pair.Value;
}
else if (pair.Value is int)
{
type = PropertyType.Integer;
value = (int)pair.Value;
}
else
{
type = PropertyType.String;
value = (string)pair.Value;
}
}
}

Expand Down
7 changes: 2 additions & 5 deletions octgnFX/Octgn.Data/GamesRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -290,11 +290,6 @@ public void InstallGame(Game game, IEnumerable<PropertyDef> properties)
);";
foreach (PropertyDef pair in properties)
{
if (!DatabaseHandler.ColumnExists("cards", pair.Name, DatabaseConnection))
{
DatabaseHandler.AddColumn("cards", pair.Name, pair.Type, DatabaseConnection);
}

using (SQLiteCommand com = DatabaseConnection.CreateCommand())
{
com.CommandText = command;
Expand All @@ -319,6 +314,8 @@ public void InstallGame(Game game, IEnumerable<PropertyDef> properties)
com.ExecuteNonQuery();
}
}

DatabaseHandler.RebuildCardsTable(DatabaseConnection);
#endregion

trans.Commit();
Expand Down

0 comments on commit 7f0dbb7

Please sign in to comment.