Esempio n. 1
0
        /// <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);
            }
        }
Esempio n. 2
0
        /// <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);
            }
        }
Esempio n. 3
0
        /// <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();
            }
        }
Esempio n. 4
0
        /// <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();
                }
            }
        }
Esempio n. 5
0
        /// <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);
        }
Esempio n. 6
0
        /// <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);
                }
            }
        }
Esempio n. 7
0
        /// <summary>
        /// Script database to file.
        /// </summary>
        /// <param name="full"></param>
        private void WriteScript(bool full)
        {
            if (TracingHelper.TraceEnabled)
            {
                TracingHelper.Write();
            }

            // create script in '.new' file
            (new FileInfo(sFileScript + ".new")).Delete();

            // script; but only positions of cached tables, not full
            ScriptToFile(dDatabase, sFileScript + ".new", full, cSystem);
        }
Esempio n. 8
0
        /// <summary>
        /// Restores a previous backup.
        /// </summary>
        private void RestoreBackup()
        {
            if (TracingHelper.TraceEnabled)
            {
                TracingHelper.Write("Not closed last time!");
            }

            if (!(new FileInfo(sFileBackup)).Exists)
            {
                // the backup don't exists because it was never made or is empty
                // the cache file must be deleted in this case
                (new FileInfo(sFileCache)).Delete();

                return;
            }

            try
            {
                DateTime     time  = DateTime.Now;
                BinaryReader f     = new BinaryReader(new FileStream(sFileBackup, FileMode.Open, FileAccess.Read));
                BinaryWriter cache = new BinaryWriter(new FileStream(sFileCache, FileMode.OpenOrCreate, FileAccess.Write));
                byte[]       b     = new byte[COPY_BLOCK_SIZE];

                while (true)
                {
                    int l = f.Read(b, 0, COPY_BLOCK_SIZE);

                    if (l == 0)
                    {
                        break;
                    }

                    cache.Write(b, 0, l);
                }

                cache.Close();
                f.Close();

                TimeSpan execution = DateTime.Now.Subtract(time);

                if (TracingHelper.TraceEnabled)
                {
                    TracingHelper.Write((Int64)execution.TotalMilliseconds);
                }
            }
            catch (Exception e)
            {
                LogHelper.Publish("Unexpected error on RestoreBackup.", e);
                throw TracingHelper.Error(TracingHelper.FILE_IO_ERROR, sFileBackup);
            }
        }
Esempio n. 9
0
        /// <summary>
        /// Performs a backup of the current database.
        /// </summary>
        private void Backup()
        {
            if (TracingHelper.TraceEnabled)
            {
                TracingHelper.Write();
            }

            // if there is no cache file then backup is not necessary
            if (!(new FileInfo(sFileCache)).Exists)
            {
                return;
            }

            try
            {
                DateTime time = DateTime.Now;

                // create a '.new' file; rename later
                BinaryWriter f   = new BinaryWriter(new FileStream(sFileBackup + ".new", FileMode.OpenOrCreate, FileAccess.Write));
                byte[]       b   = new byte[COPY_BLOCK_SIZE];
                BinaryReader fin = new BinaryReader(new FileStream(sFileCache, FileMode.Open, FileAccess.Read));

                while (true)
                {
                    int l = fin.Read(b, 0, COPY_BLOCK_SIZE);

                    if (l == 0)
                    {
                        break;
                    }

                    f.Write(b, 0, l);
                }

                f.Close();
                fin.Close();

                TimeSpan execution = DateTime.Now.Subtract(time);

                if (TracingHelper.TraceEnabled)
                {
                    TracingHelper.Write((Int64)execution.TotalMilliseconds);
                }
            }
            catch (Exception e)
            {
                LogHelper.Publish("Unexpected error on Backup.", e);
                throw TracingHelper.Error(TracingHelper.FILE_IO_ERROR, sFileBackup);
            }
        }
Esempio n. 10
0
 /// <summary>
 /// Close the database properties file.
 /// </summary>
 private void CloseProperties()
 {
     try
     {
         if (TracingHelper.TraceEnabled)
         {
             TracingHelper.Write();
         }
     }
     catch (Exception e)
     {
         throw TracingHelper.Error(TracingHelper.FILE_IO_ERROR, sFileProperties + " " + e);
     }
 }
Esempio n. 11
0
        /// <summary>
        /// Database class constructor.
        /// </summary>
        /// <param name="name">The database name to open or create.</param>
        public Database(string name)
        {
            if (TracingHelper.TraceEnabled)
            {
                TracingHelper.Write();
            }

            _name    = name;
            _table   = new ArrayList();
            _access  = new Access();
            _channel = new Hashtable();
            _alias   = new Hashtable();
            _referentialIntegrity = true;

            Library.Register(_alias);

            _databaseInfo = new DatabaseInformation(this, _table, _access);

            bool    newdatabase = false;
            Channel sys         = new Channel(this, new User(null, null, true, null),
                                              true, false, 0);

            RegisterChannel(sys);

            if (name.Equals("."))
            {
                newdatabase = true;
            }
            else
            {
                _log        = new Log(this, sys, name);
                newdatabase = _log.Open();
            }

            if (newdatabase)
            {
                Execute("CREATE USER SA PASSWORD \"\" ADMIN", sys);
            }

            //_access.grant("PUBLIC", "CLASS \"SharpHSQL.Library\"", Access.ALL);
        }
Esempio n. 12
0
        /// <summary>
        /// Creates a new properties files.
        /// </summary>
        private void Create()
        {
            if (TracingHelper.TraceEnabled)
            {
                TracingHelper.Write(sName);
            }

            XmlTextWriter writer = new XmlTextWriter(sFileProperties, 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", Assembly.GetExecutingAssembly().GetName().Version.ToString());
            writer.WriteString("1.0");
            writer.WriteEndAttribute();
            writer.WriteStartAttribute("ReadOnly", "");
            writer.WriteString("false");
            writer.WriteEndAttribute();
            writer.WriteStartAttribute("Modified", "");
            writer.WriteString("no");
            writer.WriteEndElement();
            writer.WriteEndDocument();
            writer.Flush();
            writer.Close();

            SaveProperties();
        }
Esempio n. 13
0
        /// <summary>
        /// Opens the transaction log and runs it.
        /// </summary>
        private void RunScript()
        {
            if (TracingHelper.TraceEnabled)
            {
                TracingHelper.Write();
            }

            if (!(new FileInfo(sFileScript)).Exists)
            {
                return;
            }

            bRestoring = true;

            dDatabase.IsReferentialIntegrity = false;

            ArrayList channel = new ArrayList();

            channel.Add(cSystem);

            Channel current = cSystem;
            int     size    = 1;

            try
            {
                DateTime     time = DateTime.Now;
                StreamReader r    = new StreamReader(sFileScript);

                while (true)
                {
                    string s = r.ReadLine();

                    if (s == null)
                    {
                        break;
                    }

                    if (s.StartsWith("/*C"))
                    {
                        int id = Int32.Parse(s.Substring(3, (s.IndexOf('*', 4) - 3)));

                        if (id > (channel.Count - 1))
                        {
                            current = new Channel(cSystem, id);
                            channel.Add(current);
                            dDatabase.RegisterChannel(current);
                        }
                        else
                        {
                            current = (Channel)channel[id];
                        }

                        s = s.Substring(s.IndexOf('/', 1) + 1);
                    }

                    if (!s.Equals(""))
                    {
                        dDatabase.Execute(s, current);
                    }

                    if (s.Equals("DISCONNECT"))
                    {
                        int id = current.Id;

                        current = new Channel(cSystem, id);

                        channel.RemoveAt(id);
                        channel.Insert(id, current);
                    }
                }

                r.Close();

                for (int i = 0; i < size; i++)
                {
                    current = (Channel)channel[i];

                    if (current != null)
                    {
                        current.Rollback();
                    }
                }

                TimeSpan execution = DateTime.Now.Subtract(time);

                if (TracingHelper.TraceEnabled)
                {
                    TracingHelper.Write((Int64)execution.TotalMilliseconds);
                }
            }
            catch (IOException e)
            {
                throw TracingHelper.Error(TracingHelper.FILE_IO_ERROR, sFileScript + " " + e);
            }

            dDatabase.IsReferentialIntegrity = true;

            bRestoring = false;
        }
Esempio n. 14
0
        /// <summary>
        /// Script the database objects to a file.
        /// </summary>
        /// <param name="db"></param>
        /// <param name="file"></param>
        /// <param name="full"></param>
        /// <param name="channel"></param>
        public static void ScriptToFile(Database db, string file, bool full, Channel channel)
        {
            if ((new FileInfo(file)).Exists)
            {
                // there must be no such file; overwriting not allowed for security
                throw TracingHelper.Error(TracingHelper.FILE_IO_ERROR, file);
            }

            try
            {
                DateTime time = DateTime.Now;

                // only ddl commands; needs not so much memory
                Result r;

                if (full)
                {
                    // no drop, no insert, and no positions for cached tables
                    r = db.GetScript(false, false, false, channel);
                }
                else
                {
                    // no drop, no insert, but positions for cached tables
                    r = db.GetScript(false, false, true, channel);
                }

                Record       n = r.Root;
                StreamWriter w = new StreamWriter(file);

                while (n != null)
                {
                    writeLine(w, (string)n.Data[0]);

                    n = n.Next;
                }

                // inserts are done separetely to save memory
                ArrayList tables = db.Tables;

                for (int i = 0; i < tables.Count; i++)
                {
                    Table t = (Table)tables[i];

                    // cached tables have the index roots set in the ddl script
                    if (full || !t.IsCached)
                    {
                        Index primary = t.PrimaryIndex;
                        Node  x       = primary.First();

                        while (x != null)
                        {
                            writeLine(w, t.GetInsertStatement(x.GetData()));

                            x = primary.Next(x);
                        }
                    }
                }

                w.Close();

                TimeSpan execution = DateTime.Now.Subtract(time);

                if (TracingHelper.TraceEnabled)
                {
                    TracingHelper.Write((Int64)execution.TotalMilliseconds);
                }
            }
            catch (IOException e)
            {
                TracingHelper.Error(TracingHelper.FILE_IO_ERROR, file + " " + e);
            }
        }
Esempio n. 15
0
        /// <summary>
        /// Opens the database files.
        /// </summary>
        /// <returns>True if operation is sucessful.</returns>
        public bool Open()
        {
            lock ( SyncLock )
            {
                bool newdata = false;

                if (TracingHelper.TraceEnabled)
                {
                    TracingHelper.Write();
                }

                if (!(new FileInfo(sFileProperties)).Exists)
                {
                    Create();
                    // this is a new database
                    newdata = true;
                }

                // todo: some parts are not necessary for read-only access
                LoadProperties();

                if (bReadOnly == true)
                {
                    dDatabase.SetReadOnly();

                    cCache = new Cache(sFileCache);

                    cCache.Open(true);
                    RunScript();

                    return(false);
                }

                bool needbackup = false;

                if (sModified.Equals("yes-new-files"))
                {
                    RenameNewToCurrent(sFileScript);
                    RenameNewToCurrent(sFileBackup);
                }
                else if (sModified.Equals("yes"))
                {
                    if (IsAlreadyOpen())
                    {
                        throw TracingHelper.Error(TracingHelper.DATABASE_ALREADY_IN_USE);
                    }

                    // recovering after a crash (or forgot to close correctly)
                    RestoreBackup();

                    needbackup = true;
                }

                sModified = "yes";
                SaveProperties();

                cCache = new Cache(sFileCache);

                cCache.Open(false);
                RunScript();

                if (needbackup)
                {
                    Close(false);
                    sModified = "yes";
                    SaveProperties();
                    cCache.Open(false);
                }

                OpenScript();

                // this is a existing database
                return(newdata);
            }
        }
Esempio n. 16
0
        /// <summary>
        /// Executes an SQL statement and return the results.
        /// </summary>
        /// <param name="statement">The SQL statement to execute.</param>
        /// <param name="channel">The channel to use.</param>
        /// <returns>The Result object.</returns>
        public Result Execute(string statement, Channel channel)
        {
            if (TracingHelper.TraceEnabled)
            {
                TracingHelper.Write(statement);
            }

            Tokenizer c            = new Tokenizer(statement);
            Parser    p            = new Parser(this, c, channel);
            Result    rResult      = new Result();
            string    newStatement = string.Empty;
            int       updateCount  = 0;

            try
            {
                if (_log != null && _log.cCache != null)
                {
                    _log.cCache.CleanUp();
                }

                if (TracingHelper.AssertEnabled)
                {
                    TracingHelper.Assert(!channel.IsNestedTransaction);
                }

                TracingHelper.Check(channel != null, TracingHelper.ACCESS_IS_DENIED);
                TracingHelper.Check(!_shutDown, TracingHelper.DATABASE_IS_SHUTDOWN);

                while (true)
                {
                    int    begin  = c.Position;
                    bool   script = false;
                    string sToken = c.GetString();

                    if (sToken.Equals(""))
                    {
                        break;
                    }

                    switch (sToken)
                    {
                    case "SELECT":
                        rResult = p.ProcessSelect();
                        break;

                    case "INSERT":
                        rResult = p.ProcessInsert();
                        break;

                    case "UPDATE":
                        rResult = p.ProcessUpdate();
                        break;

                    case "DELETE":
                        rResult = p.ProcessDelete();
                        break;

                    case "ALTER":
                        rResult = p.ProcessAlter();
                        break;

                    case "CREATE":
                        rResult = ProcessCreate(c, channel);
                        script  = true;
                        break;

                    case "DROP":
                        rResult = ProcessDrop(c, channel);
                        script  = true;
                        break;

                    case "GRANT":
                        rResult = ProcessGrantOrRevoke(c, channel, true);
                        script  = true;
                        break;

                    case "REVOKE":
                        rResult = ProcessGrantOrRevoke(c, channel, false);
                        script  = true;
                        break;

                    case "CONNECT":
                        rResult = ProcessConnect(c, channel);
                        break;

                    case "DISCONNECT":
                        rResult = ProcessDisconnect(c, channel);
                        break;

                    case "SET":
                        rResult = ProcessSet(c, channel);
                        script  = true;
                        break;

                    case "SCRIPT":
                        rResult = ProcessScript(c, channel);
                        break;

                    case "COMMIT":
                        rResult = ProcessCommit(c, channel);
                        script  = true;
                        break;

                    case "ROLLBACK":
                        rResult = ProcessRollback(c, channel);
                        script  = true;
                        break;

                    case "SHUTDOWN":
                        rResult = ProcessShutdown(c, channel);
                        break;

                    case "CHECKPOINT":
                        rResult = ProcessCheckpoint(channel);
                        break;

                    case "CALL":
                        rResult = p.ProcessCall();
                        break;

                    case "SHOW":
                        rResult = ProcessShow(c, channel);
                        break;

                    case "DECLARE":
                        rResult = p.ProcessDeclare();
                        script  = true;
                        break;

                    case ";":
                        continue;

                    default:
                        throw TracingHelper.Error(TracingHelper.UnexpectedToken, sToken);
                    }

                    if (rResult != null && rResult.UpdateCount > updateCount)
                    {
                        updateCount = rResult.UpdateCount;
                    }

                    if (script && _log != null)
                    {
                        int end = c.Position;

                        _log.Write(channel, c.GetPart(begin, end));
                    }
                }
            }
            catch (Exception e)
            {
                rResult = new Result(TracingHelper.GetMessage(e) + " in statement [" + statement + "]");
            }

            if (rResult != null && rResult.UpdateCount < updateCount)
            {
                rResult.SetUpdateCount(updateCount);
            }

            return(rResult);
        }