internal Row(Table t, BinaryReader din, int pos, Row before) { tTable = t; int index = tTable.IndexCount; Pos = pos; nFirstIndex = new Node(this, din, 0); Node n = nFirstIndex; for (int i = 1; i < index; i++) { n.nNext = new Node(this, din, i); n = n.nNext; } int l = tTable.InternalColumnCount; oData = Column.ReadData(din, l); int iCurrent = din.ReadInt32(); LogHelper.Publish(String.Format("Row read with {0} columns. Row read position from file: {1}. Current position: {2}.", oData.Length, iCurrent, Pos), LogEntryType.Debug); TracingHelper.Check(iCurrent == Pos, TracingHelper.INPUTSTREAM_ERROR); Insert(before); LastAccess = CurrentAccess++; }
/// <summary> /// Verify if the insert operation can be performed. /// </summary> /// <param name="row"></param> internal void CheckInsert(object[] row) { if (_type == ConstraintType.Main || _type == ConstraintType.Unique) { // inserts in the main table are never a problem // unique constraints are checked by the unique index return; } // must be called synchronized because of _mainData for (int i = 0; i < _len; i++) { object o = row[_refColumns[i]]; if (o == null) { // if one column is null then integrity is not checked return; } _mainData[_mainColumns[i]] = o; } // a record must exist in the main table TracingHelper.Check(_mainIndex.Find(_mainData) != null, TracingHelper.INTEGRITY_CONSTRAINT_VIOLATION); }
/// <summary> /// Verify if the delete operation can be performed. /// </summary> /// <param name="row"></param> internal void CheckDelete(object[] row) { if (_type == ConstraintType.ForeignKey || _type == ConstraintType.Unique) { // deleting references are never a problem // unique constraints are checked by the unique index return; } // must be called synchronized because of _refData for (int i = 0; i < _len; i++) { object o = row[_mainColumns[i]]; if (o == null) { // if one column is null then integrity is not checked return; } _refData[_refColumns[i]] = o; } // there must be no record in the 'slave' table TracingHelper.Check(_refIndex.Find(_refData) == null, TracingHelper.INTEGRITY_CONSTRAINT_VIOLATION); }
public static string InputStreamTostring(BinaryReader reader) { StringWriter write = new StringWriter(); int blocksize = 8 * 1024; // todo: is this a good value? char[] buffer = new char[blocksize]; try { while (true) { int l = reader.Read(buffer, 0, blocksize); if (l == -1) { break; } write.Write(buffer, 0, l); } write.Close(); reader.Close(); } catch (IOException e) { throw TracingHelper.Error(TracingHelper.INPUTSTREAM_ERROR, e.Message); } return(write.ToString()); }
/// <summary> /// Checks a database object for the specified right. /// </summary> /// <param name="dbobject">Database object checking.</param> /// <param name="right">Desired right.</param> internal void Check(string dbobject, AccessType right) { if (_administrator) { return; } AccessType n; n = (AccessType)_right[dbobject]; if ((n & right) != 0) { return; } if (_public != null) { n = (AccessType)(_public._right)[dbobject]; if ((n & right) != 0) { return; } } throw TracingHelper.Error(TracingHelper.ACCESS_IS_DENIED); }
/// <summary> /// Finalizes a nested transaction. /// </summary> /// <param name="rollback"></param> internal void EndNestedTransaction(bool rollback) { TracingHelper.Check(!_closed, TracingHelper.CONNECTION_IS_CLOSED); TracingHelper.Assert(_nestedTransaction, "EndNestedTransaction"); int i = _transaction.Count - 1; if (rollback) { while (i >= _nestedOldTransIndex) { Transaction t = (Transaction)_transaction[i]; t.Rollback(); i--; } } _nestedTransaction = false; _autoCommit = _nestedOldAutoCommit; if (_autoCommit == true) { _transaction.RemoveRange(_nestedOldTransIndex, (_transaction.Count - _nestedOldTransIndex)); } }
public bool CanRemove() { Node n = nFirstIndex; while (n != null) { if (TracingHelper.AssertEnabled) { TracingHelper.Assert(n.iBalance != -2); } if (TracingHelper.StopEnabled) { TracingHelper.Stop(); } if (n.iParent == 0 && n.nParent == null) { return(true); } n = n.nNext; } return(false); }
private int[] ProcessColumnList(Tokenizer tokenizer, Table table) { ArrayList v = new ArrayList(); tokenizer.GetThis("("); while (true) { v.Add(tokenizer.GetString()); string sToken = tokenizer.GetString(); if (sToken.Equals(")")) { break; } if (!sToken.Equals(",")) { throw TracingHelper.Error(TracingHelper.UnexpectedToken, sToken); } } int s = v.Count; int[] col = new int[s]; for (int i = 0; i < s; i++) { col[i] = table.GetColumnNumber((string)v[i]); } return(col); }
/// <summary> /// Check if the expression is resolved, recursively. /// </summary> public void CheckResolved() { TracingHelper.Check(_type != ExpressionType.DatabaseColumn || tFilter != null, TracingHelper.COLUMN_NOT_FOUND, sColumn); if (eArg != null) { eArg.CheckResolved(); } if (eArg2 != null) { eArg2.CheckResolved(); } if (sSelect != null) { sSelect.CheckResolved(); } if (fFunction != null) { fFunction.CheckResolved(); } }
private Node Search(object[] d) { Node x = _root; while (x != null) { if (TracingHelper.StopEnabled) { TracingHelper.Stop(); } int c = CompareRow(d, x.GetData()); if (c == 0) { return(x); } else if (c < 0) { x = x.GetLeft(); } else { x = x.GetRight(); } } return(null); }
/// <summary> /// Close the transaction log file. /// </summary> private void CloseScript() { if (TracingHelper.TraceEnabled) { TracingHelper.Write(); } try { if (wScript != null) { Stop(); wScript.Close(); wScript = null; _file = null; } } catch (Exception e) { LogHelper.Publish("Unexpected error on CloseScript.", e); TracingHelper.Error(TracingHelper.FILE_IO_ERROR, sFileScript); } }
/// <summary> /// GetRight method declaration. /// This GetRight method takes a string argument of the name of the access right. /// </summary> /// <param name="right">A string representation of the right.</param> /// <returns>A static int representing the string right passed in.</returns> public static AccessType GetRight(string right) { if (right.Equals("ALL")) { return(AccessType.All); } else if (right.Equals("SELECT")) { return(AccessType.Select); } else if (right.Equals("UPDATE")) { return(AccessType.Update); } else if (right.Equals("DELETE")) { return(AccessType.Delete); } else if (right.Equals("INSERT")) { return(AccessType.Insert); } throw TracingHelper.Error(TracingHelper.UnexpectedToken, right); }
/// <summary> /// Save database properties. /// </summary> private void SaveProperties() { lock ( SyncLock ) { //WATYF: //Added check for ".new" file, delete if exists. //Changed writer creation to include ".new" suffix on sFileProperties FileInfo fi = new FileInfo(sFileProperties + ".new"); if (fi.Exists) { fi.Delete(); } XmlTextWriter writer = new XmlTextWriter(sFileProperties + ".new", null); writer.Formatting = Formatting.Indented; writer.Indentation = 4; writer.WriteStartDocument(); writer.WriteComment("SharpHSQL Configuration"); writer.WriteProcessingInstruction("Instruction", "Configuration Record"); writer.WriteStartElement("Properties", ""); writer.WriteStartAttribute("LogFile", ""); writer.WriteString(sFileScript); writer.WriteEndAttribute(); writer.WriteStartAttribute("DataFile", ""); writer.WriteString(sFileCache); writer.WriteEndAttribute(); writer.WriteStartAttribute("Backup", ""); writer.WriteString(sFileBackup); writer.WriteEndAttribute(); writer.WriteStartAttribute("Version", ""); writer.WriteString(sVersion); writer.WriteEndAttribute(); writer.WriteStartAttribute("ReadOnly", ""); if (bReadOnly == true) { writer.WriteString("true"); } else { writer.WriteString("false"); } writer.WriteEndAttribute(); writer.WriteStartAttribute("Modified", ""); writer.WriteString(sModified); writer.WriteEndElement(); writer.WriteEndDocument(); writer.Flush(); writer.Close(); //WATYF: Added RenameNewToCurrent RenameNewToCurrent(sFileProperties); CloseProperties(); if (TracingHelper.TraceEnabled) { TracingHelper.Write(); } } }
/// <summary> /// Opens the transaction log for writing. /// </summary> private void OpenScript() { if (TracingHelper.TraceEnabled) { TracingHelper.Write(); } try { // opens the log file exclusively for writing _file = new FileStream(sFileScript, FileMode.Append, FileAccess.Write, FileShare.None); // todo: use a compressed stream wScript = new StreamWriter(_file, System.Text.Encoding.UTF8); #if !POCKETPC tRunner = new Thread(new ThreadStart(Run)); tRunner.IsBackground = true; tRunner.Start(); #endif } catch (Exception e) { LogHelper.Publish("Unexpected error on OpenScript.", e); TracingHelper.Error(TracingHelper.FILE_IO_ERROR, sFileScript); } }
/// <summary> /// Checks if the database is already open. /// </summary> /// <returns>True if the databse file is open.</returns> private bool IsAlreadyOpen() { if (TracingHelper.TraceEnabled) { TracingHelper.Write(); } FileStream fs = null; try { // try to open the log file exclusively for writing fs = new FileStream(sFileScript, FileMode.Append, FileAccess.Write, FileShare.None); } catch (Exception) { return(true); } finally { if (fs != null) { fs.Close(); fs = null; } } return(false); }
/// <summary> /// Load properties from file. /// </summary> private void LoadProperties() { try { XmlTextReader reader = new XmlTextReader(sFileProperties); //Read the tokens from the reader while (reader.Read()) { if (XmlNodeType.Element == reader.NodeType) { sFileScript = reader.GetAttribute("LogFile"); sFileCache = reader.GetAttribute("DataFile"); sFileBackup = reader.GetAttribute("Backup"); sModified = reader.GetAttribute("Modified"); sVersion = reader.GetAttribute("Version"); bReadOnly = reader.GetAttribute("ReadOnly").ToLower().Equals("true"); } } reader.Close(); } catch (Exception e) { Console.WriteLine("Property File Exeception:", e.ToString()); } if (TracingHelper.TraceEnabled) { TracingHelper.Write(); } }
private static int GetElapsed(string part, DateTime d1, DateTime d2) { TimeSpan elapsed = d1.Subtract(d2); switch (part) { case "year": return(new DateTime(elapsed.Ticks).Year); case "month": return(new DateTime(elapsed.Ticks).Month); case "day": return(new DateTime(elapsed.Ticks).Day); case "hour": return(new DateTime(elapsed.Ticks).Hour); case "minute": return(new DateTime(elapsed.Ticks).Minute); case "second": return(new DateTime(elapsed.Ticks).Second); case "ms": return(new DateTime(elapsed.Ticks).Millisecond); default: throw TracingHelper.Error(TracingHelper.ERROR_IN_FUNCTION); } }
/// <summary> /// Multiply two objects. /// </summary> /// <param name="one"></param> /// <param name="two"></param> /// <param name="type"></param> /// <returns></returns> internal static object Multiply(object one, object two, ColumnType type) { if (one == null || two == null) { return(null); } switch (type) { case ColumnType.Null: return(null); case ColumnType.Integer: int ai = (int)one; int bi = (int)two; return(ai * bi); case ColumnType.Float: case ColumnType.Real: float floata = (float)one; float floatb = (float)two; return(floata * floatb); case ColumnType.DbDouble: double ad = (double)one; double bd = (double)two; return(ad * bd); case ColumnType.Numeric: case ColumnType.DbDecimal: decimal abd = (decimal)one; decimal bbd = (decimal)two; return(abd * bbd); case ColumnType.TinyInt: byte ba = (byte)one; byte bb = (byte)two; return(ba * bb); case ColumnType.SmallInt: short shorta = (short)one; short shortb = (short)two; return(shorta * shortb); case ColumnType.BigInt: long longa = (long)one; long longb = (long)two; return(longa * longb); default: throw TracingHelper.Error(TracingHelper.FUNCTION_NOT_SUPPORTED, (int)type); } }
public void CreatePrimaryKey() { TracingHelper.Assert(iPrimaryKey == -1, "Table.createPrimaryKey"); AddColumn("SYSTEM_ID", ColumnType.Integer, true, true); CreatePrimaryKey(iColumnCount - 1); iVisibleColumns = iColumnCount - 1; }
/// <summary> /// Sets the auto commit mode for this channel. /// </summary> /// <param name="autoCommit"></param> public void SetAutoCommit(bool autoCommit) { TracingHelper.Check(!_closed, TracingHelper.CONNECTION_IS_CLOSED); Commit(); _autoCommit = autoCommit; }
private Result ProcessDrop(Tokenizer tokenizer, Channel channel) { channel.CheckReadWrite(); channel.CheckAdmin(); string sToken = tokenizer.GetString(); if (sToken.Equals("TABLE")) { sToken = tokenizer.GetString(); if (sToken.Equals("IF")) { sToken = tokenizer.GetString(); // EXISTS sToken = tokenizer.GetString(); // <table> DropTable(sToken, true); } else { DropTable(sToken, false); } channel.Commit(); } else if (sToken.Equals("USER")) { _access.DropUser(tokenizer.GetStringToken()); } else if (sToken.Equals("INDEX")) { sToken = tokenizer.GetString(); if (!tokenizer.WasLongName) { throw TracingHelper.Error(TracingHelper.UnexpectedToken, sToken); } string table = tokenizer.LongNameFirst; string index = tokenizer.LongNameLast; Table t = GetTable(table, channel); t.CheckDropIndex(index); Table tn = t.MoveDefinition(index); tn.MoveData(t); DropTable(table); LinkTable(tn); channel.Commit(); } else { throw TracingHelper.Error(TracingHelper.UnexpectedToken, sToken); } return(new Result()); }
public object[] GetData() { if (TracingHelper.AssertEnabled) { TracingHelper.Assert(iBalance != -2); } return(rData.GetData()); }
public void GetThis(string match) { GetToken(); if (!sToken.Equals(match)) { throw TracingHelper.Error(TracingHelper.UnexpectedToken, sToken); } }
/// <summary> /// CleanUp method declaration. /// This method cleans up the cache when it grows too large. It works by /// checking Rows in held in the Cache's iLastAccess member and removing /// Rows that haven't been accessed in the longest time. /// </summary> public void CleanUp() { if (_cacheSize < MAX_CACHE_SIZE) { return; } int count = 0, j = 0; while (j++ < LENGTH && _cacheSize + LENGTH > MAX_CACHE_SIZE && (count * 16) < LENGTH) { if (TracingHelper.StopEnabled) { TracingHelper.Stop(); } Row r = GetWorst(); if (r == null) { return; } if (r.Changed) { _rowWriter[count++] = r; } else { // here we can't remove roots if (!r.CanRemove()) { Remove(r); } } } if (count != 0) { SaveSorted(count); } for (int i = 0; i < count; i++) { // here we can't remove roots Row r = _rowWriter[i]; if (!r.CanRemove()) { Remove(r); } _rowWriter[i] = null; } }
private Result ProcessGrantOrRevoke(Tokenizer c, Channel channel, bool grant) { channel.CheckReadWrite(); channel.CheckAdmin(); AccessType right = AccessType.None; string sToken; do { string sRight = c.GetString(); right |= Access.GetRight(sRight); sToken = c.GetString(); } while (sToken.Equals(",")); if (!sToken.Equals("ON")) { throw TracingHelper.Error(TracingHelper.UnexpectedToken, sToken); } string table = c.GetString(); if (table.Equals("CLASS")) { // object is saved as 'CLASS "java.lang.Math"' // tables like 'CLASS "xy"' should not be created table += " \"" + c.GetString() + "\""; } else { GetTable(table, channel); // to make sure the table exists } c.GetThis("TO"); string user = c.GetStringToken(); // string command; if (grant) { _access.Grant(user, table, right); // command = "GRANT"; } else { _access.Revoke(user, table, right); // command = "REVOKE"; } return(new Result()); }
/// <summary> /// Close the transaction log. /// </summary> /// <param name="compact"></param> public void Close(bool compact) { lock ( SyncLock ) { if (TracingHelper.TraceEnabled) { TracingHelper.Write(); } if (bReadOnly) { return; } // no more scripting CloseScript(); // create '.script.new' (for this the cache may be still required) WriteScript(compact); // flush the cache (important: after writing the script) cCache.Flush(); // create '.backup.new' using the '.data' Backup(); // we have the new files sModified = "yes-new-files"; SaveProperties(); // old files can be removed and new files renamed RenameNewToCurrent(sFileScript); RenameNewToCurrent(sFileBackup); // now its done completely sModified = "no"; SaveProperties(); CloseProperties(); if (compact) { // stop the runner thread of this process (just for security) Stop(); // delete the .data so then a new file is created (new FileInfo(sFileCache)).Delete(); (new FileInfo(sFileBackup)).Delete(); // all files are closed now; simply open & close this database Database db = new Database(sName); db.Log.Close(false); } } }
public string GetName() { GetToken(); if (!WasName) { throw TracingHelper.Error(TracingHelper.UnexpectedToken, sToken); } return(sToken); }
public int GetColumnNumber(string c) { int i = SearchColumn(c); if (i == -1) { throw TracingHelper.Error(TracingHelper.COLUMN_NOT_FOUND, c); } return(i); }
public int GetBalance() { if (TracingHelper.AssertEnabled) { TracingHelper.Assert(iBalance != -2); // rData.iLastAccess=Row.iCurrentAccess++; } return(iBalance); }
/// <summary> /// Shutdown method declaration. /// The shutdown method closes the cache file. /// It does not flush pending writes. /// </summary> public void Shutdown() { try { _fileStream.Close(); } catch (Exception e) { throw TracingHelper.Error(TracingHelper.FILE_IO_ERROR, "error " + e + " in shutdown " + _name); } }