Пример #1
0
        /// <summary>
        /// Update/Insert the given input object
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="input"></param>
        /// <returns></returns>
        public T UpsertRecord <T>(T input) where T : IStaticType, new()
        {
            var actualType = input.GetType();
            var entityName = actualType.Name;
            var type       = _dataType.FromType(actualType);

            if (type == null)
            {
                throw new ArgumentException("Given entityName does not exists.");
            }

            input.__updatedAt = DateTime.Now;

            if (input.Id == 0)
            {
                input.__createdAt = DateTime.Now;

                NancyBlackDatabase.ObjectCreating(this, entityName, input);

                _db.Insert(input, actualType);

                NancyBlackDatabase.ObjectCreated(this, entityName, input);
            }
            else
            {
                NancyBlackDatabase.ObjectUpdating(this, entityName, input);

                _db.Update(input, actualType);

                NancyBlackDatabase.ObjectUpdated(this, entityName, input);
            }

            return(input);
        }
Пример #2
0
        /// <summary>
        /// Delay Insert the specified item
        /// </summary>
        /// <param name="item"></param>
        public static void DelayedInsert(this NancyBlackDatabase db, dynamic item)
        {
            var     t = item.GetType();
            dynamic buffer;

            if (_buffers.TryGetValue(t, out buffer) == false)
            {
                buffer = DelayedInsertExt.CreateBuffer(db.DatabaseFileName, t);
                _buffers.AddOrUpdate(t, buffer, new Func <Type, object, object>((tin, o) => o));
            }

            buffer.Add(item);
        }
Пример #3
0
        /// <summary>
        /// Changes the delay time for
        /// </summary>
        /// <param name="t"></param>
        /// <param name="delay"></param>
        public static void SetFlushDelay(this NancyBlackDatabase db, Type t, TimeSpan delay)
        {
            dynamic buffer;

            if (_buffers.TryGetValue(t, out buffer))
            {
                buffer.FlushDelay = delay;
            }
            else
            {
                buffer = DelayedInsertExt.CreateBuffer(db.DatabaseFileName, t);
            }
        }
Пример #4
0
        /// <summary>
        /// Gets site database from given Context
        /// </summary>
        /// <param name="hostName"></param>
        /// <returns></returns>
        public static NancyBlackDatabase GetSiteDatabase(string rootPath, NancyContext context = null)
        {
            var path     = Path.Combine(rootPath, "Site");
            var fileName = Path.Combine(path, "data.sqlite");

            var db  = new SQLiteConnection(fileName, true);
            var ndb = new NancyBlackDatabase(db, context);

            ndb.DatabaseFileName  = fileName;
            ndb.DatabaseDirectory = path;

            return(ndb);
        }
Пример #5
0
        /// <summary>
        /// Deletes the record
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="input"></param>
        public void DeleteRecord <T>(T input) where T : IStaticType, new()
        {
            var actualType = input.GetType();
            var entityName = actualType.Name;

            var deleting = this.GetById <T>(input.Id); // get the object out before delete

            NancyBlackDatabase.ObjectDeleting(this, entityName, deleting);

            _db.Delete(deleting);

            NancyBlackDatabase.ObjectDeleted(this, entityName, deleting);
        }
Пример #6
0
        /// <summary>
        /// Update Record FAST, this will directly update the record to database
        /// </summary>
        /// <param name="entityName"></param>
        /// <param name="inputObject"></param>
        /// <returns></returns>
        public dynamic UpsertStaticRecord(string entityName, dynamic inputObject)
        {
            var type = _dataType.FromName(entityName);

            if (type == null)
            {
                throw new ArgumentException("Given entityName does not exists.");
            }

            var actualType = type.GetCompiledType();

            if (inputObject is JObject)
            {
                inputObject = ((JObject)inputObject).ToObject(actualType);
            }

            if (inputObject.Id == 0)
            {
                inputObject.__createdAt = DateTime.Now;
                inputObject.__updatedAt = DateTime.Now;

                NancyBlackDatabase.ObjectCreating(this, entityName, inputObject);

                _db.Insert((object)inputObject, actualType);

                NancyBlackDatabase.ObjectCreated(this, entityName, inputObject);
            }
            else
            {
                inputObject.__updatedAt = DateTime.Now;

                NancyBlackDatabase.ObjectUpdating(this, entityName, inputObject);

                _db.Update((object)inputObject, actualType);

                NancyBlackDatabase.ObjectUpdated(this, entityName, inputObject);
            }

            return(inputObject);
        }
Пример #7
0
        /// <summary>
        /// Generates the view.
        /// </summary>
        /// <param name="db">The database.</param>
        /// <param name="templatePath">The target template path.</param>
        /// <param name="table_name">The table_name.</param>
        /// <param name="replace">if set to <c>true</c>, view will be replaced.</param>
        /// <exception cref="System.InvalidOperationException">Entity: + table_name +  does not exists, Insert some sample data before running this page.</exception>
        protected void GenerateView(NancyBlackDatabase db,
                                    string templatePath,
                                    string table_name,
                                    string layout,
                                    bool replace    = false,
                                    string fileName = null)
        {
            if (fileName == null)
            {
                fileName = table_name;
            }

            var templateFile = Path.Combine(
                templatePath,
                fileName + ".cshtml");


            if (File.Exists(templateFile) && replace == false)
            {
                return;
            }

            var type = db.DataType.FromName(table_name);

            if (type == null)
            {
                throw new InvalidOperationException("Entity:" + table_name + " does not exists, Insert some sample data before running this page.");
            }

            var template = File.ReadAllText(Path.Combine(this.RootPath, "NancyBlack", "Modules", "DatabaseSystem", "Views", "_backendtemplate.cshtml"));
            var code     = Razor.Parse <ViewModel>(template, new ViewModel()
            {
                DataType = type,
                Layout   = layout
            }, null);

            Directory.CreateDirectory(templatePath);
            File.WriteAllText(templateFile, code);
        }
Пример #8
0
        /// <summary>
        /// Deletes the specified entity name.
        /// </summary>
        /// <param name="entityName">Name of the entity.</param>
        /// <param name="inputObject">The input object.</param>
        /// <exception cref="System.InvalidOperationException">
        /// Entity:  + entityName +  does not exists
        /// or
        /// Id of inputObject is not set or has default value
        /// </exception>
        public void DeleteRecord(string entityName, dynamic inputObject)
        {
            var type = _dataType.FromName(entityName);
            int?id   = inputObject.Id == null ? null : inputObject.Id;

            if (type == null)
            {
                throw new InvalidOperationException("Entity: " + entityName + " does not exists");
            }
            if (id == null || id == 0)
            {
                throw new InvalidOperationException("Id of inputObject is not set or has default value");
            }

            var deleting = this.GetById(entityName, id.Value); // get the object out before delete

            NancyBlackDatabase.ObjectDeleting(this, entityName, deleting);

            _db.Delete(deleting);

            NancyBlackDatabase.ObjectDeleted(this, entityName, deleting);
        }
Пример #9
0
        /// <summary>
        /// Performs the regular backup
        /// </summary>
        public void PerformBackup(dynamic backupOptions = null)
        {
            if (DateTime.Now.Subtract(_LastBackupCheck).TotalMinutes > 30)
            {
                _LastBackupCheck = DateTime.Now;
            }
            else
            {
                // No Need to do the backup now
                return;
            }

#if DEBUG
            Debugger.Break();
#endif
            Action cleanUp = null;

            var compression  = 1;
            var mode         = "hourly";
            var databaseFile = this.DatabaseFileName;

            string backupPath = Path.Combine(this.DatabaseDirectory, "Backups");

            if (backupOptions != null)
            {
                if (backupOptions.compression != null)
                {
                    compression = (int)backupOptions.compression;
                }

                if (backupOptions.uncpath != null)
                {
                    var existed = DriveInfo.GetDrives().ToDictionary(d => d.Name);
                    var chosen  = '\0';
                    for (char i = 'A'; i < 'Z'; i++)
                    {
                        if (existed.ContainsKey(i + @":\") == false)
                        {
                            chosen = i;
                            break;
                        }
                    }

                    if (chosen != '\0')
                    {
                        string command = string.Empty;

                        if (backupOptions.username != null && backupOptions.password != null)
                        {
                            command = string.Format("use {0}: {1} /u:{2} {3}",
                                                    chosen,
                                                    backupOptions.uncpath,
                                                    backupOptions.username,
                                                    backupOptions.password);
                        }
                        else
                        {
                            command = string.Format("use {0}: {1}",
                                                    chosen,
                                                    backupOptions.uncpath);
                        }

                        var process = Process.Start("net.exe", command);
                        process.WaitForExit();

                        if (process.ExitCode == 0)
                        {
                            cleanUp = () =>
                            {
                                string cmd = string.Format("use {0}: /delete",
                                                           chosen);

                                var p2 = Process.Start("net.exe", cmd);
                                p2.WaitForExit();
                            };

                            backupPath = chosen + ":\\";
                        }
                    }
                }

                if (backupOptions.sitename != null)
                {
                    backupPath = Path.Combine(backupPath, (string)backupOptions.sitename);
                }
            }

            try
            {
                if (mode == "hourly")
                {
                    backupPath = Path.Combine(backupPath, "DatabaseBackup-Hourly");
                    Directory.CreateDirectory(backupPath);

                    // create hourly backup
                    var backupFile = Path.Combine(backupPath, string.Format("hourlybackup-{0:HH}.sqlite.bz2", DateTime.Now));
                    if (File.Exists(backupFile) == false)
                    {
                        NancyBlackDatabase.BZip(databaseFile, backupFile);
                    }
                    else
                    {
                        // check modified date
                        if (File.GetLastWriteTime(backupFile).Date < DateTime.Now.Date)
                        {
                            // it was the yesterday's file, replace it
                            NancyBlackDatabase.BZip(databaseFile, backupFile);
                        }
                    }
                }

                if (mode == "daily")
                {
                    backupPath = Path.Combine(backupPath, "DatabaseBackup-Hourly");
                    Directory.CreateDirectory(backupPath);

                    var dailybackupFile = Path.Combine(backupPath, string.Format("dailybackup-{0:dd-MM-yyyy}.sqlite.bz2", DateTime.Now));
                    if (File.Exists(dailybackupFile) == false)
                    {
                        NancyBlackDatabase.BZip(databaseFile, dailybackupFile, 9); // max compression for daily backup
                    }

                    var backupFiles = Directory.GetFiles(backupPath, "dailybackup-*.sqlite.bz2");
                    var now         = DateTime.Now;
                    var maxDay      = 30;

                    if (backupOptions.dailyretention != null)
                    {
                        maxDay = (int)backupOptions.dailyretention;
                    }

                    foreach (var file in backupFiles)
                    {
                        if (now.Subtract(File.GetCreationTime(file)).TotalDays > maxDay)
                        {
                            try
                            {
                                File.Delete(file); // delete backup older than 30 days
                            }
                            catch (Exception)
                            {
                            }
                        }
                    }
                }
            }
            catch (Exception)
            {
                // retry backup again
                _LastBackupCheck = DateTime.MinValue;
            }
            finally
            {
                if (cleanUp != null)
                {
                    cleanUp();
                }
            }
        }
Пример #10
0
        /// <summary>
        /// Upserts the specified entity name.
        /// </summary>
        /// <param name="entityName">Name of the entity.</param>
        /// <param name="input">Data to be saved, can be anything including anonymous type. But Anonymous Type must include Id parameter</param>
        public JObject UpsertRecord(string entityName, object inputObject)
        {
            var type = _dataType.FromName(entityName);

            if (type is StaticDataType)
            {
                return(JObject.FromObject(this.UpsertStaticRecord(entityName, inputObject)));
            }

            JObject jObject = inputObject as JObject;

            if (jObject == null)
            {
                jObject = JObject.FromObject(inputObject);
            }

            List <JProperty> removed = new List <JProperty>();

            // converts complex properties to Json
            foreach (var prop in jObject.Properties().ToList()) // to-list to allow us to add property
            {
                if (prop.Value.Type == JTokenType.Array || prop.Value.Type == JTokenType.Object)
                {
                    // array or objects are converted to JSON when stored in table
                    jObject["js_" + prop.Name] = prop.Value.ToString(Formatting.None);

                    prop.Remove();
                    removed.Add(prop);
                }
            }

            type = _dataType.FromJObject(entityName, jObject);
            var actualType = type.GetCompiledType();

            jObject["__updatedAt"] = DateTime.Now;

            int id = 0;

            if (jObject.Property("id") != null) // try to get Id
            {
                id = (int)jObject["id"];

                jObject["Id"] = id;
                jObject.Remove("id");
            }

            if (jObject.Property("Id") != null)
            {
                id = (int)jObject["Id"];
            }

            if (id == 0)
            {
                jObject["__createdAt"] = DateTime.Now;

                // needs to convert to object to get Id later
                dynamic toInsert = jObject.ToObject(actualType);

                NancyBlackDatabase.ObjectCreating(this, entityName, toInsert);

                _db.Insert(toInsert, actualType);
                jObject["Id"] = toInsert.Id;

                NancyBlackDatabase.ObjectCreated(this, entityName, toInsert);
            }
            else
            {
                NancyBlackDatabase.ObjectUpdating(this, entityName, jObject);

                _db.Update(jObject.ToObject(actualType), actualType);

                NancyBlackDatabase.ObjectUpdated(this, entityName, jObject);
            }

            // remove "js_" properties
            foreach (var prop in jObject.Properties().ToList()) // to-list to allow us to add/remove property
            {
                if (prop.Name.StartsWith("js_"))
                {
                    prop.Remove();
                }
            }

            // add removed complex properties back
            foreach (var prop in removed)
            {
                jObject.Add(prop.Name, prop.Value);
            }

            return(jObject);
        }
Пример #11
0
        /// <summary>
        /// Performs the regular backup
        /// </summary>
        public void PerformBackup()
        {
            if (DateTime.Now.Subtract(_LastBackupCheck).TotalMinutes > 30)
            {
                _LastBackupCheck = DateTime.Now;
            }
            else
            {
                // No Need to do the backup now
                return;
            }

#if !DEBUG
            try
            {
                var path     = this.DatabaseDirectory;
                var fileName = this.DatabaseFileName;

                var backupPath = Path.Combine(path, "Backups");
                Directory.CreateDirectory(path);
                Directory.CreateDirectory(backupPath);

                // create hourly backup
                var backupFile = Path.Combine(backupPath, string.Format("hourlybackup-{0:HH}.sqlite.bz2", DateTime.Now));
                if (File.Exists(backupFile) == false)
                {
                    NancyBlackDatabase.BZip(fileName, backupFile);
                }
                else
                {
                    // check modified date
                    if (File.GetLastWriteTime(backupFile).Date < DateTime.Now.Date)
                    {
                        // it was the yesterday's file, replace it
                        NancyBlackDatabase.BZip(fileName, backupFile);
                    }
                }

                // create daily backup
                var dailybackupFile = Path.Combine(backupPath, string.Format("dailybackup-{0:dd-MM-yyyy}.sqlite.bz2", DateTime.Now));
                if (File.Exists(dailybackupFile) == false)
                {
                    NancyBlackDatabase.BZip(fileName, dailybackupFile, 9); // max compression for daily backup
                }

                var backupFiles = Directory.GetFiles(backupPath, "dailybackup-*.sqlite.bz2");
                var now         = DateTime.Now;
                foreach (var file in backupFiles)
                {
                    if (now.Subtract(File.GetCreationTime(file)).TotalDays > 30)
                    {
                        try
                        {
                            File.Delete(file); // delete backup older than 30 days
                        }
                        catch (Exception)
                        {
                        }
                    }
                }
            }
            catch (Exception)
            {
                // retry backup again
                _LastBackupCheck = DateTime.MinValue;
            }
#endif
        }