public void CreateVersion(string applicationName, int version)
        {
            if (!Auth.AllowCreateVersion(applicationName))
            {
                throw new SettingsAuthorizationException(AuthorizationScope.Version, AuthorizationLevel.Create, applicationName, Auth.CurrentIdentity.Id);
            }

            var application = GetApplicationsData(applicationName).SingleOrDefault();

            if (application == null)
            {
                throw new SettingsNotFoundException(Constants.ERROR_APPLICATION_UNKNOWN);
            }

            var data = GetVersionData(application).SingleOrDefault(v => v.Version == version);

            if (data != null)
            {
                throw new SettingsDuplicateException(Constants.ERROR_VERION_ALREADY_EXISTS);
            }

            data = new VersionData();
            data.ApplicationId = application.Id;
            data.Created = DateTime.UtcNow;
            data.Version = version;
            application.Versions.Add(data);
            Store.Save();
        }
        public ApplicationModel CreateApplication(string applicationName, string applicationDescription, string directoryName, string directoryDescription)
        {
            if (!Auth.AllowCreateApplication(applicationName))
            {
                throw new SettingsAuthorizationException(AuthorizationScope.Application, AuthorizationLevel.Create, applicationName, Auth.CurrentIdentity.Id);
            }

            if (string.IsNullOrWhiteSpace(applicationName))
            {
                throw new SettingsStoreException(Constants.ERROR_APPLICATION_NO_NAME);
            }

            var application = Store.Context.Applications.FirstOrDefault(app => app.Name == applicationName);

            if (application != null)
            {
                throw new SettingsStoreException(Constants.ERROR_APPLICATION_ALREADY_EXISTS);
            }

            if (!NameValidator.ValidateName(applicationName))
            {
                throw new SettingsNotFoundException(Constants.ERROR_APPLICATION_NAME_INVALID);
            }

            application = new ApplicationData();
            DirectoryData cust_directory = null;
            DirectoryData def_directory = null;

            using (TransactionScope scope = new TransactionScope())
            {
                application.Name = applicationName;

                if (string.IsNullOrWhiteSpace(applicationDescription))
                {
                    applicationDescription = Constants.DEAULT_APPLICATION_DESCRIPTION;
                }

                //Create application
                application.Description = applicationDescription.Trim().Replace("  ", " ");
                application.Created = DateTime.UtcNow;

                Store.Context.Applications.Add(application);
                Store.Context.SaveChanges();

                //Create version 1
                VersionData version = new VersionData { Version = 1, Created = DateTime.UtcNow, ApplicationId = application.Id };
                Store.Context.Versions.Add(version);
                Store.Context.SaveChanges();

                //Create application default directory
                def_directory = new DirectoryData();
                def_directory.Name = Constants.DEAULT_DIRECTORY_NAME;
                def_directory.Description = Constants.DEAULT_DIRECTORY_DESCRIPTION;
                def_directory.ApplicationId = application.Id;
                def_directory.Created = DateTime.UtcNow;
                Store.Context.Directories.Add(def_directory);

                //Create custom first directory, if provided.
                if (!string.IsNullOrWhiteSpace(directoryName))
                {
                    cust_directory = new DirectoryData();
                    cust_directory.Name = directoryName.Trim();
                    if (directoryDescription != null)
                        cust_directory.Description = directoryDescription.Trim();
                    cust_directory.ApplicationId = application.Id;
                    cust_directory.Created = DateTime.UtcNow;
                    Store.Context.Directories.Add(cust_directory);
                }

                Store.Context.SaveChanges();

                //Create default api key for applicaiton, a trigger maintains access for the master apikey to the application directories.
                ApiKeyData apiKey = new ApiKeyData { ApiKey = ApiKeyGenerator.Create(), Name = application.Name, Application = application, Active = true, AdminKey = true, Created = DateTime.UtcNow };

                Store.Context.ApiKeys.Add(apiKey);
                Store.Context.SaveChanges();

                //Set access right to default directory.
                DirectoryAccessData access = new DirectoryAccessData();
                access.AllowWrite = true;
                access.AllowDelete = true;
                access.AllowCreate = true;
                access.ApiKey = apiKey;
                access.Directory = def_directory;
                Store.Context.Access.Add(access);

                //Set access right to custom directory.
                if (cust_directory != null)
                {
                    access = new DirectoryAccessData();
                    access.AllowWrite = true;
                    access.AllowDelete = true;
                    access.AllowCreate = true;
                    access.ApiKey = apiKey;
                    access.Directory = cust_directory;
                    Store.Context.Access.Add(access);
                }

                Store.Save();
                scope.Complete();
            }

            Auth.Invalidate();

            Store.Context.Entry<ApplicationData>(application).Reload();

            //reload the enities the reflect the master key access created by the trigger.
            if (cust_directory != null)
                Store.Context.Entry<DirectoryData>(cust_directory).Collection("Access").Load();

            if (def_directory != null)
                Store.Context.Entry<DirectoryData>(def_directory).Collection("Access").Load();

            return GetApplication(applicationName);
        }
        public void CopyApplication(string applicationName, string newApplicationName, string newApplicationDescription, int version)
        {
            if (!Auth.AllowCreateApplication(applicationName))
            {
                throw new SettingsAuthorizationException(AuthorizationScope.Application, AuthorizationLevel.Create, applicationName, Auth.CurrentIdentity.Id);
            }

            if (string.IsNullOrWhiteSpace(applicationName))
            {
                throw new SettingsStoreException(Constants.ERROR_APPLICATION_NO_NAME);
            }

            var application = GetApplicationsData(applicationName).SingleOrDefault();

            if (application == null)
            {
                throw new SettingsNotFoundException(Constants.ERROR_APPLICATION_UNKNOWN);
            }

            using (TransactionScope scope = new TransactionScope())
            {
                CreateApplication(newApplicationName, newApplicationDescription);

                var newApplication = GetApplicationsData(newApplicationName).Single();

                List<DirectoryData> newDirectories = new List<DirectoryData>();
                List<VersionData> copyVersions = new List<VersionData>();
                List<SettingData> newSettings = new List<SettingData>();

                foreach (var item in application.Directories)
                {
                    DirectoryData data = new DirectoryData
                    {
                        ApplicationId = newApplication.Id,
                        Name = item.Name,
                        Description = item.Description
                    };

                    newApplication.Directories.Add(data);
                    newDirectories.Add(data);
                }
                if (version == 0)
                {
                    copyVersions.AddRange((from v in application.Versions
                                           orderby v.Version descending
                                           select v));
                }
                else
                {
                    copyVersions.Add((from v in application.Versions
                                      orderby v.Version ascending
                                      select v).First());
                }

                foreach (var item in copyVersions)
                {
                    VersionData newVersion = new VersionData();
                    newVersion.Version = item.Version;
                    newVersion.ApplicationId = newApplication.Id;
                    newVersion.Created = DateTime.UtcNow;

                    Store.Save();

                    foreach (var setting in item.Settings)
                    {
                        SettingData newSetting = SettingData.Copy(setting);
                        setting.VersionId = newVersion.Id;
                        setting.DirectoryId = newDirectories.Single(d => d.Name == setting.Directory.Name).Id;
                        newSettings.Add(newSetting);
                    }
                }

                Store.Context.Settings.AddRange(newSettings);
                Store.Save();
                scope.Complete();
            }
        }
        public void CopyVersion(string applicationName, int newVersionNumber, int copyFromVersionNumber)
        {
            if (!Auth.AllowCreateVersion(applicationName))
            {
                throw new SettingsAuthorizationException(AuthorizationScope.Version, AuthorizationLevel.Create, applicationName, Auth.CurrentIdentity.Id);
            }

            var application = GetApplicationsData(applicationName).SingleOrDefault();

            if (application == null)
            {
                throw new SettingsNotFoundException(Constants.ERROR_APPLICATION_UNKNOWN);
            }

            var copyVersion = GetVersionData(application).SingleOrDefault(v => v.Version == copyFromVersionNumber);
            var newVersion = GetVersionData(application).SingleOrDefault(v => v.Version == newVersionNumber);

            if (newVersion != null)
            {
                throw new SettingsDuplicateException(Constants.ERROR_VERION_ALREADY_EXISTS);
            }

            if (copyVersion == null)
            {
                throw new SettingsNotFoundException(Constants.ERROR_VERION_UNKNOWN);
            }

            using (TransactionScope scope = TransactionScopeFactory.CreateReaduncommited())
            {
                newVersion = new VersionData();
                newVersion.ApplicationId = application.Id;
                newVersion.Created = DateTime.UtcNow;
                newVersion.Version = newVersionNumber;
                application.Versions.Add(newVersion);
                Store.Save();

                foreach (var item in copyVersion.Settings)
                {
                    SettingData setting = SettingData.Copy(item);
                    setting.VersionId = newVersion.Id;
                    Store.Context.Settings.Add(setting);
                }

                Store.Save();
                scope.Complete();
            }
        }