using System; using System.Collections.Generic; using System.Text; using System.Diagnostics; using MySql.Data.MySqlClient; namespace WmData { /// /// This class was designed to do the same as WmDataIdManager, only better. /// Created on 11th of july 2009 @ 11.28hrs /// public class WmDataIdManager { protected object lockObject; protected string idTableName = "wmdataidmanager"; protected WmDataBaseCredentials databaseCredentials; public WmDataIdManager(WmDataBaseCredentials databaseCredentials) { this.databaseCredentials = databaseCredentials; // check if the table is present, create it if nescesary if (!WmDataBaseCreator.isTableExistent(idTableName, databaseCredentials)) { // Id Table does not exist, create one createSqlIdTable(); } lockObject = new object(); } /// /// Creates and saves a new id for a new record in the table. /// public int getNewId(string tableName) { int returnId = -1; string selectMaxIdSql = "SELECT currentmaxid FROM " + databaseCredentials.Catalog + "." + idTableName + " WHERE tablename='" + tableName + "';"; object maxIdValue = null; using (TimedLock.Lock(lockObject)) { // We lock this section to prevent duplicate id's MySqlConnection connection = new MySqlConnection(databaseCredentials.getConnectionString()); MySqlCommand currentMaxIdCommand = new MySqlCommand(selectMaxIdSql, connection); try { connection.Open(); maxIdValue = currentMaxIdCommand.ExecuteScalar(); } catch (Exception error) { Trace.WriteLine("WmDirectDataIdManager: Exception while retrieving current maximum id for table " + tableName + " from the " + idTableName + ". " + error.Message); } MySqlCommand newIdCommand = new MySqlCommand(); newIdCommand.Parameters.Add("?tablename", MySqlDbType.VarChar); newIdCommand.Parameters.Add("?lastupdate", MySqlDbType.DateTime); newIdCommand.Parameters.Add("?currentmaxid", MySqlDbType.Int32); newIdCommand.Parameters["?tablename"].Value = tableName; newIdCommand.Parameters["?lastupdate"].Value = DateTime.Now; if (!(maxIdValue is Int32)) { // there is no record matching this tablename, therefore we'll have to lookup the current maximum id and cache it returnId = getCurrentMaximumId(tableName) + 1; // get the current maximum id from the 'real' table newIdCommand.CommandText = "INSERT INTO " + databaseCredentials.Catalog + "." + idTableName + " (" + idTableName + ".tablename, " + idTableName + ".lastupdate, " + idTableName + ".currentmaxid) VALUES (?tablename,?lastupdate,?currentmaxid)"; } else { // update the cached id value returnId = (int)maxIdValue + 1; newIdCommand.CommandText = "UPDATE " + databaseCredentials.Catalog + "." + idTableName + " SET " + idTableName + ".tablename=?tablename, " + idTableName + ".lastupdate=?lastupdate, " + idTableName + ".currentmaxid=?currentmaxid WHERE tablename=?tablename"; } newIdCommand.Parameters["?currentmaxid"].Value = returnId; newIdCommand.Connection = connection; try { newIdCommand.ExecuteNonQuery(); } catch (Exception error) { Trace.WriteLine("WmDirectDataIdManager: Exception while saving the new current maximum id for table " + tableName + ". " + error.Message); } finally { connection.Close(); } } return returnId; } /// /// Returns the current maximum id that is actually used in the table /// protected int getCurrentMaximumId(string tableName) { string selectMaxIdSql = "SELECT MAX(" + tableName + ".id) FROM " + databaseCredentials.Catalog + "." + tableName + ";"; object maxIdValue = null; MySqlConnection connection = new MySqlConnection(databaseCredentials.getConnectionString()); MySqlCommand command = new MySqlCommand(selectMaxIdSql, connection); try { connection.Open(); maxIdValue = command.ExecuteScalar(); } catch (Exception error) { Trace.WriteLine("WmDirectDataIdManager: Exception while retrieving current maximum id for table "+tableName+". " + error.Message); } finally { connection.Close(); } if (!(maxIdValue is Int32)) { // it might be that the table does not exists, check that: // then it is logical that we return 0, since the current max id is 0 return 0; } else { return (int)maxIdValue; } } /// /// Creates the table where Id's are cached. /// protected void createSqlIdTable() { MySqlConnection connection = new MySqlConnection(databaseCredentials.getConnectionString()); string createTableSql = "CREATE TABLE `" + databaseCredentials.Catalog + "`.`wmdataidmanager` ( " + "`tablename` VARCHAR(200) NOT NULL, " + "`lastupdate` DATETIME NOT NULL, " + "`currentmaxid` INTEGER NOT NULL DEFAULT 0, " + "PRIMARY KEY (`tablename`) " + ")ENGINE = InnoDB;"; MySqlCommand tableCommand = new MySqlCommand(createTableSql, connection); try { connection.Open(); tableCommand.ExecuteNonQuery(); } catch (Exception error) { throw new Exception("WmDirectDataIdManager: Could not create WmDataIdManager SQL Table. " + error.Message); } finally { connection.Close(); } } /// /// Will purge the id manager cache (and force new id's to be looked up based upon existing records) /// public void clearIdManagerCache() { MySqlConnection connection = new MySqlConnection(databaseCredentials.getConnectionString()); string createTableSql = "DELETE FROM `" + databaseCredentials.Catalog + "`.`wmdataidmanager`;"; MySqlCommand tableCommand = new MySqlCommand(createTableSql, connection); try { connection.Open(); tableCommand.ExecuteNonQuery(); } catch (Exception error) { throw new Exception("WmDataIdManager: Could not purge WmDataIdManager cache. " + error.Message); } finally { connection.Close(); } Trace.WriteLine("WmDataIdManager: Purged the id cache."); } } }