context: // --------------------------------------------------------------------------------------------------------------------
  // <copyright file="database.cs" company="Allors bvba">
  //   Copyright 2002-2013 Allors bvba.
  // 
  // Dual Licensed under
  //   a) the Lesser General Public Licence v3 (LGPL)
  //   b) the Allors License
  // 
  // The LGPL License is included in the file lgpl.txt.
  // The Allors License is an addendum to your contract.
  // 
  // Allors Platform is distributed in the hope that it will be useful,
  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  // GNU General Public License for more details.
  // 
  // For more information visit http://www.allors.com/legal
  // </copyright>
  // --------------------------------------------------------------------------------------------------------------------
  
  namespace Allors.Adapters.Database.Sql
  {
      using System;
      using System.Collections.Generic;
      using System.Data;
      using System.Data.Common;
      using System.Linq;
      using System.Text;
      using System.Xml;
  
      using Allors.Adapters.Database.Caching;
  
      using global::Npgsql;
  
      using Meta;
  
      public abstract class Database : Population, IDatabase
      {
          public static readonly long[] EmptyObjectIds = { };
  
          private const string ConnectionStringsKey = "allors";
  
          private readonly string id;
  
          private readonly string connectionString;
          private readonly int commandTimeout;
          private readonly IsolationLevel isolationLevel;
  
          private readonly Dictionary<IObjectType, IRoleType[]> sortedUnitRolesByObjectType;
          private readonly ICache cache;
  
          protected Database(IServiceProvider serviceProvider, Configuration configuration)
              : base(configuration)
          {
              this.ServiceProvider = serviceProvider;
              this.Serializable = configuration.Serializable;
  
              this.connectionString = configuration.ConnectionString;
              this.commandTimeout = configuration.CommandTimeout;
              this.isolationLevel = configuration.IsolationLevel;
  
              var connectionStringBuilder = new NpgsqlConnectionStringBuilder(this.ConnectionString);
              var applicationName = connectionStringBuilder.ApplicationName?.Trim();
              if (!string.IsNullOrWhiteSpace(applicationName))
              {
                  this.id = applicationName;
              }
              else
              {
                  using (var connection = new NpgsqlConnection(this.ConnectionString))
                  {
                      connection.Open();
                      this.id = connection.Database?.ToLowerInvariant() ?? this.ConnectionString;
                  }
              }
  
              this.sortedUnitRolesByObjectType = new Dictionary<IObjectType, IRoleType[]>();
              
              this.cache = configuration.CacheFactory.CreateCache(this);
          }
  
          public event ObjectNotLoadedEventHandler ObjectNotLoaded;
  
          public event RelationNotLoadedEventHandler RelationNotLoaded;
  
          public Allors.IDatabase Serializable { get; }
  
          public IServiceProvider ServiceProvider { get; }
  
          public override bool IsDatabase
          {
              get
              {
                  return true;
              }
          }
  
          public override bool IsWorkspace
          {
              get
              {
                  return false;
              }
          }
  
          public override string Id
          {
              get { return this.id; }
          }
  
          public bool IsShared
          {
              get
              {
                  return true;
              }
          }
  
          public virtual string AscendingSortAppendix
          {
              get { return null; }
          }
  
          public virtual string DescendingSortAppendix
          {
              get { return null; }
          }
  
          public virtual string Except
          {
              get { return "EXCEPT"; }
          }
  
          public abstract Schema Schema { get; }
  
          public abstract CommandFactories CommandFactories { get; }
         
          public ICache Cache
          {
              get
              {
                  return this.cache;
              }
          }
  
          public string ConnectionString
          {
              get
              {
                  return this.connectionString;
              }
          }
  
          public int CommandTimeout
          {
              get
              {
                  return this.commandTimeout;
              }
          }
  
          public IsolationLevel IsolationLevel
          {
              get
              {
                  return this.isolationLevel;
              }
          }
  
          public override ISession CreateSession()
          {
              return this.CreateDatabaseSession();
          }
  
          public void Recover()
          {
              if (!ObjectFactory.MetaPopulation.IsValid)
              {
                  throw new ArgumentException("Domain is invalid");
              }
  
              var session = this.CreateManagementSession();
              try
              {
                  this.DropIndexes(session);
                  this.DropTriggers(session);
                  this.DropProcedures(session);
                  this.DropFunctions(session);
                  this.DropUserDefinedTypes(session);
  
                  this.CreateUserDefinedTypes(session);
                  this.CreateFunctions(session);
                  this.CreateProcedures(session);
                  this.CreateTriggers(session);
                  this.CreateIndexes(session);
  
                  session.Commit();
              }
              catch
              {
                  session.Rollback();
                  throw;
              }
              finally
              {
                  this.ResetSchema();
                  this.Cache.Invalidate();
              }
          }
  
          ISession Allors.IDatabase.CreateSession()
          {
              return this.CreateDatabaseSession();
          }
  
          public virtual ISession CreateDatabaseSession()
          {
              if (Schema.SchemaValidationErrors.HasErrors)
              {
  
gt:                 var errors = new StringBuilder();