using System; using System.Collections.Generic; using System.Data; using System.Linq; using System.Text; using TShockAPI.DB; namespace TShockAPI { public class DBTools { internal static IDbConnection database; /// /// Creates a Table, within the current open DB /// /// Name of the Table /// The list of columns that the Table will have /// Only try create Table if it does not exist public static void CreateTable(string name, List columns, bool IfNotExists =true) { //Build up Creation string :) StringBuilder sb = new StringBuilder(); sb.Append("CREATE TABLE "); if (IfNotExists) sb.Append("IF NOT EXISTS "); if (TShock.Config.StorageType.ToLower() == "sqlite") sb.Append("'" + name + "' ("); else if (TShock.Config.StorageType.ToLower() == "mysql") sb.Append(name + " ("); int count = 0; foreach (Column column in columns) { count++; if (column.Type.ToLower() == "int") { if (TShock.Config.StorageType.ToLower() == "sqlite") sb.Append(column.Name + " NUMERIC "); else if (TShock.Config.StorageType.ToLower() == "mysql") sb.Append(column.Name + " INT(255) "); } else if (column.Type.ToLower() == "string") { if (TShock.Config.StorageType.ToLower() == "sqlite") sb.Append(column.Name + " TEXT "); else if (TShock.Config.StorageType.ToLower() == "mysql") sb.Append(column.Name + " VARCHAR(255) "); } if (column.Unique) sb.Append("UNIQUE"); if (columns.Count == count) sb.Append(")"); else sb.Append(", "); } database.Query(sb.ToString()); } /// /// Inserts a list of values into a Table, if conditions are met /// /// Name of the Table /// Ignore insert if feild is unique and there is already a exact entry /// The list of values to enter into the table /// The list of where statements that must be met, can be an empty list public static int InsertTable(string tablename, bool Ignore, List Values, List WhereStatements) { StringBuilder sb = new StringBuilder(); sb.Append("INSERT "); if (Ignore) { if (TShock.Config.StorageType.ToLower() == "sqlite") sb.Append("OR IGNORE "); else if (TShock.Config.StorageType.ToLower() == "mysql") sb.Append("IGNORE "); } if (TShock.Config.StorageType.ToLower() == "sqlite") sb.Append("INTO '" + tablename + "' ("); else if (TShock.Config.StorageType.ToLower() == "mysql") sb.Append("INTO " + tablename + " "); using (var com = database.CreateCommand()) { //Values if (TShock.Config.StorageType.ToLower() == "sqlite") { int count = 0; foreach (ColumnData columnname in Values) { count++; if (Values.Count != count) sb.Append(columnname.Name + ", "); else sb.Append(columnname.Name + ") "); } sb.Append("VALUES ("); count = 0; foreach (ColumnData columnname in Values) { count++; if (Values.Count != count) { sb.Append("@" + columnname.Name.ToLower() + ", "); com.AddParameter("@" + columnname.Name.ToLower(), columnname.Value); } else { sb.Append("@" + columnname.Name.ToLower() + ") "); com.AddParameter("@" + columnname.Name.ToLower(), columnname.Value); } } } else if (TShock.Config.StorageType.ToLower() == "mysql") { sb.Append("SET "); int count = 0; foreach (ColumnData columnname in Values) { count++; if (Values.Count != count) { sb.Append("@" + columnname.Name.ToLower() + "=" + columnname.Value + ", "); com.AddParameter("@" + columnname.Name.ToLower(), columnname.Value); } else { sb.Append("@" + columnname.Name.ToLower() + "=" + columnname.Value + ") "); com.AddParameter("@" + columnname.Name.ToLower(), columnname.Value); } } } //Where Statement (if any) if (WhereStatements.Count > 0) { sb.Append("WHERE "); int count = 0; foreach (ColumnData columnname in WhereStatements) { count++; if (Values.Count != count) { sb.Append("@" + columnname.Name.ToLower() + "-where" + "=" + columnname.Value + " AND "); com.AddParameter("@" + columnname.Name.ToLower() + "-where", columnname.Value); } else { sb.Append("@" + columnname.Name.ToLower() + "-where" + "=" + columnname.Value + ";"); com.AddParameter("@" + columnname.Name.ToLower() + "-where", columnname.Value); } } } com.CommandText = sb.ToString(); using (var reader = com.ExecuteReader()) return reader.RecordsAffected; } } /// /// Returns a list of values from a given Table, where conditions are met /// /// Name of the Table /// The name of the column you are getting the values from /// The list of where statements that must be met, can be an empty list public static List ReadTable(string tablename, string getcolumn, List WhereStatements) { StringBuilder sb = new StringBuilder(); List ReturnedValues = new List(); sb.Append("SELECT * FROM " + tablename + " "); using (var com = database.CreateCommand()) { //Where Statement (if any) if (WhereStatements.Count > 0) { sb.Append("WHERE "); int count = 0; foreach (ColumnData columnname in WhereStatements) { count++; if (WhereStatements.Count != count) { sb.Append(columnname.Name + " =" + columnname.Value + " AND "); } else { sb.Append(columnname.Name + " =" + columnname.Value); } } } com.CommandText = sb.ToString(); using (var reader = com.ExecuteReader()) { while (reader.Read()) ReturnedValues.Add(reader.Get(getcolumn)); } } return ReturnedValues; } /// /// Sets values in a Table, where statements are met /// /// Name of the Table /// The column data you are setting /// The list of where statements that must be met, can be an empty list public static int SetTable(string tablename, ColumnData setcolumn, List WhereStatements) { StringBuilder sb = new StringBuilder(); sb.Append("UPDATE " + tablename + " SET " + setcolumn.Name + "=@setcolumn "); using (var com = database.CreateCommand()) { //Where Statement (if any) if (WhereStatements.Count > 0) { sb.Append("WHERE "); int count = 0; foreach (ColumnData columnname in WhereStatements) { count++; if (WhereStatements.Count != count) { sb.Append(columnname.Name + " =" + columnname.Value + " AND "); } else { sb.Append(columnname.Name + " =" + columnname.Value); } } } com.CommandText = sb.ToString(); com.AddParameter("@setcolumn", setcolumn.Value); using (var reader = com.ExecuteReader()) return reader.RecordsAffected; } } } public class Column { public string Name { get; set; } public string Type { get; set; } public bool Unique { get; set; } public string Parameters { get; set; } /// /// The class for creating a new column type /// /// Name of the column /// Whether there can be more than one exact value in the column /// The type of column, currently the api only supports "string" or "int" /// Extra SQL parameters given, can cause errors cross different SQL (SQLite and MySql) public Column(string name, bool unique, string type, string parameters = "") { Name = name; Type = type; Unique = unique; Parameters = parameters; } public Column() { Name = string.Empty; Type = string.Empty; Unique = false; Parameters = string.Empty; } } public class ColumnData { public string Name { get; set; } public object Value { get; set; } /// /// The class for testing, inserting or setting column data /// /// Column Name /// Column Value public ColumnData(string name, object value) { Name = name; Value = value; } public ColumnData() { Name = string.Empty; Value = string.Empty; } } }