示例#1
0
        /// <summary>
        /// Install the initial catalog
        /// </summary>
        public bool Install()
        {
            var search = ApplicationContext.Current?.ConfigurationManager.GetConnectionString("santeDbSearch");
            LockableSQLiteConnection db = null;

            // Database for the SQL Lite connection
            if (search != null)
            {
                db = SQLiteConnectionManager.Current.GetReadWriteConnection(search);
                using (db.Lock())
                    this.Install(db);
            }

            db = SQLiteConnectionManager.Current.GetReadWriteConnection(ApplicationContext.Current?.ConfigurationManager.GetConnectionString(ApplicationContext.Current?.Configuration.GetSection <DcDataConfigurationSection>().MainDataSourceConnectionStringName));
            using (db.Lock())
                return(this.Install(db));
        }
示例#2
0
        /// <summary>
        /// Get or create audit code
        /// </summary>
        private DbAuditCode GetOrCreateAuditCode(LockableSQLiteConnection context, AuditCode messageCode)
        {
            if (messageCode == null)
            {
                return(null);
            }
            var existing = context.Table <DbAuditCode>().Where(o => o.Code == messageCode.Code && o.CodeSystem == messageCode.CodeSystem).FirstOrDefault();

            if (existing == null)
            {
                byte[] codeId = Guid.NewGuid().ToByteArray();
                var    retVal = new DbAuditCode()
                {
                    Code = messageCode.Code, CodeSystem = messageCode.CodeSystem, Id = codeId
                };
                context.Insert(retVal);
                return(retVal);
            }
            else
            {
                return(existing);
            }
        }
示例#3
0
 /// <summary>
 /// Local data context
 /// </summary>
 public LocalDataContext(LockableSQLiteConnection connection)
 {
     this.Connection    = connection;
     this.m_cacheCommit = new Dictionary <Guid, IdentifiedData>();
 }
 /// <summary>
 /// Local data context
 /// </summary>
 public SQLiteDataContext(LockableSQLiteConnection connection, IPrincipal principal)
 {
     this.Principal     = principal;
     this.Connection    = connection;
     this.m_cacheCommit = new Dictionary <Guid, IdentifiedData>();
 }
示例#5
0
        /// <summary>
        /// Bundles are special, they may be written on the current connection
        /// or in memory
        /// </summary>
        public override Bundle Insert(Bundle data, TransactionMode mode, IPrincipal principal)
        {
            // first, are we just doing a normal insert?
            if (data.Item.Count <= 250)
            {
                return(base.Insert(data, mode, principal));
            }
            else
            { // It is cheaper to open a mem-db and let other threads access the main db for the time being
                base.FireInserting(new DataPersistingEventArgs <Bundle>(data, mode, principal));
                var cstr = ApplicationContext.Current.ConfigurationManager.GetConnectionString("santeDbData");
                // Memory connection
                using (var memConnection = new LockableSQLiteConnection(ApplicationContext.Current.GetService <ISQLitePlatform>(), new SanteDB.Core.Configuration.Data.ConnectionString()
                {
                    Value = "dbfile=:memory:"
                }, SQLiteOpenFlags.ReadWrite))
                {
                    try
                    {
                        ApplicationContext.Current.SetProgress(Strings.locale_prepareBundle, 0.5f);
                        // We want to apply the initial schema
                        new SanteDB.DisconnectedClient.SQLite.Configuration.Data.Migrations.InitialCatalog().Install(memConnection, true);


                        // Copy the name component and address component values
                        if (cstr.GetComponent("encrypt") != "true" || ApplicationContext.Current.GetCurrentContextSecurityKey() == null)
                        {
                            memConnection.Execute($"ATTACH DATABASE '{cstr.GetComponent("dbfile")}' AS file_db KEY ''");
                        }
                        else
                        {
                            memConnection.Execute($"ATTACH DATABASE '{cstr.GetComponent("dbfile")}' AS file_db KEY X'{BitConverter.ToString(ApplicationContext.Current.GetCurrentContextSecurityKey()).Replace("-", "")}'");
                        }

                        try
                        {
                            memConnection.BeginTransaction();

                            //// Names & Address
                            memConnection.Execute($"INSERT OR REPLACE INTO phonetic_value (uuid, value) SELECT uuid, value FROM file_db.phonetic_value");
                            memConnection.Execute($"INSERT OR REPLACE INTO entity_addr_val (uuid, value) SELECT uuid, value FROM file_db.entity_addr_val");

                            //foreach (var itm in memConnection.Query<String>("SELECT NAME FROM SQLITE_MASTER WHERE TYPE = 'index' AND SQL IS NOT NULL"))
                            //    memConnection.Execute(String.Format("DROP INDEX {0};", itm));
                            memConnection.Commit();
                        }
                        catch (Exception e)
                        {
                            memConnection.Rollback();
                            throw new DataException("Error inserting bundle", e);
                        }

                        memConnection.Execute("DETACH DATABASE file_db");

                        // We insert in the memcontext now
                        using (var memContext = new SQLiteDataContext(memConnection, principal))
                            this.InsertInternal(memContext, data);

                        var columnMapping = memConnection.TableMappings.Where(o => o.MappedType.Namespace.StartsWith("SanteDB")).ToList();

                        // Now we attach our local file based DB by requesting a lock so nobody else touches it!
                        using (var fileContext = this.CreateConnection(principal))
                            using (fileContext.LockConnection())
                            {
                                if (cstr.GetComponent("encrypt") != "true" || ApplicationContext.Current.GetCurrentContextSecurityKey() == null)
                                {
                                    memConnection.Execute($"ATTACH DATABASE '{cstr.GetComponent("dbfile")}' AS file_db KEY ''");
                                }
                                else
                                {
                                    memConnection.Execute($"ATTACH DATABASE '{cstr.GetComponent("dbfile")}' AS file_db KEY X'{BitConverter.ToString(ApplicationContext.Current.GetCurrentContextSecurityKey()).Replace("-", "")}'");
                                }

                                try
                                {
                                    memConnection.BeginTransaction();

                                    // Copy copy!!!
                                    int i = 0;
                                    foreach (var tbl in memConnection.Query <SysInfoStruct>("SELECT name FROM sqlite_master WHERE type='table'"))
                                    {
                                        memConnection.Execute($"INSERT OR REPLACE INTO file_db.{tbl.Name} SELECT * FROM {tbl.Name}");
                                        ApplicationContext.Current.SetProgress(Strings.locale_committing, (float)i++ / columnMapping.Count);
                                    }
                                    ApplicationContext.Current.SetProgress(Strings.locale_committing, 1.0f);

                                    memConnection.Commit();
                                }
                                catch
                                {
                                    memConnection.Rollback();
                                    throw;
                                }
                            }
                    }
                    catch (Exception e)
                    {
                        this.m_tracer.TraceWarning("Error inserting bundle using fast insert method - Will use slow method: {0}", e);
                        return(base.Insert(data, mode, principal)); // Attempt to do a slow insert
                        // TODO: Figure out why the copy command sometimes is missing UUIDs
                        //throw new LocalPersistenceException(Synchronization.Model.DataOperationType.Insert, data, e);
                    }
                }

                base.FireInserted(new DataPersistedEventArgs <Bundle>(data, mode, principal));
                return(data);
            }
        }