Exemple #1
0
        private static SelectedConfigSections FillDefaults(ArgsParser parser, SyncConfigurationSection syncConfig)
        {
            SelectedConfigSections sections = new SelectedConfigSections();

            if (string.IsNullOrEmpty(parser.ScopeName) && syncConfig.SyncScopes.Count == 1)
            {
                sections.SelectedSyncScope = syncConfig.SyncScopes.Cast <SyncScopeConfigElement>().First();
                parser.ScopeName           = sections.SelectedSyncScope.Name;
            }
            else
            {
                sections.SelectedSyncScope = syncConfig.SyncScopes.Cast <SyncScopeConfigElement>().Single((e) => e.Name.Equals(parser.ScopeName, StringComparison.InvariantCultureIgnoreCase));
            }

            if (string.IsNullOrEmpty(parser.TargetDatabaseName) && syncConfig.Databases.Count == 1)
            {
                sections.SelectedTargetDatabase = syncConfig.Databases.Cast <TargetDatabaseConfigElement>().First();
                parser.TargetDatabaseName       = sections.SelectedTargetDatabase.Name;
            }
            else
            {
                sections.SelectedTargetDatabase = syncConfig.Databases.Cast <TargetDatabaseConfigElement>().Single((e) => e.Name.Equals(parser.TargetDatabaseName, StringComparison.InvariantCultureIgnoreCase));
            }

            return(sections);
        }
Exemple #2
0
        private static void ValidateCSDLMode(ArgsParser parser)
        {
            if (parser.OperationMode != OperationMode.Codegen)
            {
                throw new InvalidOperationException("Only /mode:codegen allowed when /url flag is used.");
            }

            if (parser.CodeGenMode == CodeGenTarget.Server)
            {
                throw new InvalidOperationException("/target:server is not a valid target when /url flag is used. Only isclient and client targets allowed.");
            }
        }
        private static void ValidateConfigFile(ArgsParser parser, SyncConfigurationSection syncConfig)
        {
            if (syncConfig == null)
            {
                throw new InvalidOperationException("Unable to parse config file.");
            }

            if (syncConfig.SyncScopes.Count == 0)
            {
                throw new InvalidOperationException("Config file should contain atleast one <SyncScope> definition.");
            }

            if (syncConfig.Databases.Count == 0)
            {
                throw new InvalidOperationException(
                          "Config file should contain atleast one <TargetDatabase> definition.");
            }

            if (syncConfig.SyncScopes.Count > 1 && string.IsNullOrEmpty(parser.ScopeName))
            {
                throw new InvalidOperationException(
                          "More than one <SyncScope> definitions found. Specify /scopename parameter.");
            }

            if (syncConfig.Databases.Count > 1 && string.IsNullOrEmpty(parser.TargetDatabaseName))
            {
                throw new InvalidOperationException(
                          "More than one <TargetDatabase> definitions found. Specify /database parameter.");
            }

            if (!string.IsNullOrEmpty(parser.ScopeName) &&
                syncConfig.SyncScopes.Cast <SyncScopeConfigElement>()
                .FirstOrDefault(e => e.Name.Equals(parser.ScopeName, StringComparison.InvariantCultureIgnoreCase)) ==
                null)
            {
                throw new ArgumentException("Scopename not found in SyncConfiguration/SyncScope definition.",
                                            parser.ScopeName);
            }

            if (!string.IsNullOrEmpty(parser.TargetDatabaseName) &&
                syncConfig.Databases.Cast <TargetDatabaseConfigElement>()
                .FirstOrDefault(
                    e => e.Name.Equals(parser.TargetDatabaseName, StringComparison.InvariantCultureIgnoreCase)) ==
                null)
            {
                throw new ArgumentException("TargetDatabase not found in SyncConfiguration/Databases definition.",
                                            parser.ScopeName);
            }
        }
Exemple #4
0
        /// <summary>
        /// Entry point
        /// </summary>
        /// <param name="args"></param>
        public static void Main(string[] args)
        {
            try
            {
                ArgsParser parser = null;

                try
                {
                    parser = ArgsParser.ParseArgs(args);
                }
                catch (Exception e)
                {
                    LogArgsError(e.Message);
                    return;
                }

                if (parser.HelpRequested)
                {
                    return;
                }
                if (!parser.ModeSpecified)
                {
                    LogArgsError("Required argument /mode is not specified.");
                    return;
                }

                if (parser.UseCSDLUrl)
                {
                    // This means user have specified a Config file. Read it and create the DbSyncDescription for it.
                    ProcessCSDLUri(parser);
                }
                else
                {
                    // This means user have specified a Config file. Read it and create the DbSyncDescription for it.
                    ProcessConfigFile(parser);
                }

                Log("{0} completed with no errors.", Constants.AssemblyName);
            }
            catch (Exception e)
            {
                Log(e.ToString());
                Log("{0} failed.", Constants.AssemblyName);
            }

            Console.ReadLine();
        }
Exemple #5
0
        private static void ProcessCSDLUri(ArgsParser parser)
        {
            Dictionary <string, Dictionary <string, string> > tablesToColumnMappingsInfo = new Dictionary <string, Dictionary <string, string> >();

            ValidateCSDLMode(parser);
            string serviceUri = null;
            DbSyncScopeDescription scopeDescription = CSDLParser.GetDescriptionFromUri(parser, parser.CSDLUrl, out serviceUri);

            Log("Generating files...");
            EntityGenerator generator = EntityGeneratorFactory.Create(parser.CodeGenMode, null /* null syncSchema - not needed for client code generation */);

            generator.GenerateEntities(parser.GeneratedFilePrefix,
                                       string.IsNullOrEmpty(parser.Namespace)
                ? string.IsNullOrEmpty(parser.GeneratedFilePrefix) ? scopeDescription.ScopeName : parser.GeneratedFilePrefix
                : parser.Namespace,
                                       scopeDescription, tablesToColumnMappingsInfo, parser.WorkingDirectory, parser.Language, serviceUri);
        }
Exemple #6
0
 private static void LogArgsError(string errorMessage)
 {
     Log(errorMessage);
     Log(ArgsParser.GetHelpString());
 }
        private static DbSyncScopeDescription ParseCSDLDocument(ArgsParser parser, string uriString, XDocument document)
        {
            DbSyncScopeDescription scopeDescription = null;
            Uri uri = new Uri(uriString);
            // Assumption is that for OData Sync metadata document, the URI is of format http://foo/snc.svc/scopename/$metadata.
            // In this case we are looking for the last but one segment.
            string scopeName = uri.Segments[uri.Segments.Length - 2];
            if (scopeName.EndsWith("/"))
            {
                scopeName = scopeName.Substring(0, scopeName.Length - 1);
            }

            if (parser.UseVerbose)
            {
                SyncSvcUtil.Log("Parsed ScopeName as {0}", scopeName);
            }

            // Its an CSDL document
            XElement dataServicesElem = document.Root.Element(Constants.SyncScopeDataServicesElement);
            if (dataServicesElem == null)
            {
                throw new CsdlException("No <DataServices> element found in the <edmx> document.");
            }
            XElement schemaElement = dataServicesElem.Element(Constants.SyncScopeSchemaElement);
            if (schemaElement == null)
            {
                throw new CsdlException("No <Schema> element found in the <DataServices> document.");
            }

            scopeDescription = new DbSyncScopeDescription(scopeName);
            // Loop over each <EntityType> element and add it as a DbSyncTableDescription
            foreach (XElement entity in schemaElement.Elements(Constants.SyncScopeEntityTypeElement))
            {
                XAttribute nameAttr = entity.Attribute(Constants.SyncScopeEntityTypeNameAttribute);
                if (nameAttr == null)
                {
                    throw new CsdlException("<EntityType> has no Name attribute. \n" + entity.ToString());
                }
                // Parse each entity and create a DbSyncTableDescription
                DbSyncTableDescription table = new DbSyncTableDescription(nameAttr.Value);

                // Look for <Key> element
                XElement keyElem = entity.Element(Constants.SyncScopeEntityTypeKeyElement);
                if (keyElem == null)
                {
                    throw new CsdlException("<EntityType> has no <Key> elements defined. \n" + entity.ToString());
                }

                List<string> keyNames = new List<string>();
                // Loop over each <PropertyRef> element and add it to the list for lookup
                foreach (XElement prop in keyElem.Elements(Constants.SyncScopeEntityTypeKeyRefElement))
                {
                    XAttribute keyName = prop.Attribute(Constants.SyncScopeEntityTypeNameAttribute);
                    if (keyName != null)
                    {
                        keyNames.Add(keyName.Value);
                    }
                }

                // Loop over each <Property> element and add it as a DbSyncColumnDescription
                foreach (XElement field in entity.Elements(Constants.SyncScopeEntityTypePropertyElement))
                {
                    // Read Property name
                    XAttribute fieldName = field.Attribute(Constants.SyncScopeEntityTypeNameAttribute);
                    if (fieldName == null)
                    {
                        throw new CsdlException("<Property> has no Name attribute. \n" + field.ToString());
                    }

                    // Read Property Edm type
                    XAttribute fieldType = field.Attribute(Constants.SyncScopeEntityTypeTypeAttribute);
                    if (fieldType == null)
                    {
                        throw new CsdlException("<Property> has no Type attribute. \n" + field.ToString());
                    }

                    // Read Property Nullable attribute
                    XAttribute fieldNullable = field.Attribute(Constants.SyncScopeEntityTypeNullableAttribute);

                    DbSyncColumnDescription column = new DbSyncColumnDescription(fieldName.Value, GetSqlTypeForEdm(fieldType.Value));
                    if (fieldNullable != null && bool.Parse(fieldNullable.Value))
                    {
                        column.IsNullable = true;
                    }
                    column.IsPrimaryKey = keyNames.Contains(fieldName.Value);
                    table.Columns.Add(column);
                }

                scopeDescription.Tables.Add(table);
            }
            return scopeDescription;
        }
Exemple #8
0
        public static DbSyncScopeDescription GetDescriptionFromUri(ArgsParser parser, string uriString,
                                                                   out string serviceUri)
        {
            // Issue the request.
            var request = new WebClient();

            SyncSvcUtil.Log("Trying to connect to Uri '{0}' to check for SyncScopeSchema document", uriString);

            var content = request.DownloadString(uriString);

            // Check to see if its a SyncScopes <services> document or an SyncScopeSchema <edmx> document.
            if (parser.UseVerbose)
            {
                SyncSvcUtil.Log(
                    "Download succeeded. Checking to see if its a SyncScope <Service> document or an SyncScopeSchema <edmx> document.");
                SyncSvcUtil.Log("Downloaded document content:\n {0}", content);
            }

            SyncSvcUtil.Log("Parsing downloaded document.", uriString);

            var document = XDocument.Parse(content);

            if (document == null)
            {
                throw new CsdlException("Downloaded content is not a valid XML document.");
            }

            if (document.Root.Name.Equals(Constants.SyncScopeServicesElement))
            {
                if (parser.UseVerbose)
                {
                    SyncSvcUtil.Log("Found a <service> document. Checking for SyncScopes workspace.");
                }
                var workspaceElement = document.Root.Element(Constants.SyncScopeWorkspaceElement);
                if (workspaceElement == null)
                {
                    throw new CsdlException("Remote SyncScope services document did not contain a <workspace> element.");
                }

                // Look for <collection> element
                var collectionElements =
                    workspaceElement.Elements(Constants.SyncScopeWorkspaceCollectionElement).ToArray();
                if (collectionElements.Length == 0)
                {
                    throw new CsdlException("Remote SyncScope services document did not contain a <collection> element.");
                }
                XAttribute hrefAttr;
                if (collectionElements.Length > 1)
                {
                    SyncSvcUtil.Log(
                        "Multiple SyncScopes were found in the <service> document. Please specify the correct Url.");
                    foreach (var elem in collectionElements)
                    {
                        hrefAttr = elem.Attribute(Constants.SyncScopeWorkspaceCollectionHrefAttribute);
                        SyncSvcUtil.Log("\t\t{0} - Uri: {1}{2}{0}/$metadata",
                                        hrefAttr.Value,
                                        parser.CSDLUrl,
                                        parser.CSDLUrl.EndsWith("/") ? string.Empty : "/");
                    }
                    throw new CsdlException("Multiple SyncScopes found.");
                }
                // We have exactly one SyncScope. Download the schema for that
                hrefAttr = collectionElements[0].Attribute(Constants.SyncScopeWorkspaceCollectionHrefAttribute);
                if (hrefAttr == null)
                {
                    throw new CsdlException("No Href attribute was found in the <collection> element.");
                }

                // Ensure the href param is not empty as this is the scopeName
                if (string.IsNullOrEmpty(hrefAttr.Value))
                {
                    throw new CsdlException(
                              string.Format("Href attribute in <collection> must have a non empty string.\n Content: {0}",
                                            collectionElements[0]));
                }

                // Look for and remove $syncScopes
                var origUrl = parser.CSDLUrl;
                if (origUrl.EndsWith("$syncscopes", StringComparison.InvariantCultureIgnoreCase))
                {
                    origUrl = origUrl.Substring(0, origUrl.LastIndexOf("/"));
                }

                uriString = string.Format("{0}{1}{2}/$metadata",
                                          origUrl,
                                          origUrl.EndsWith("/") ? string.Empty : "/",
                                          hrefAttr.Value);

                return(GetDescriptionFromUri(parser, uriString, out serviceUri));
            }
            if (document.Root.Name.Equals(Constants.SyncScopeEdmxElement))
            {
                // Set the service URI and remove $metadata token from it.
                //Remove the / at the end if present.
                serviceUri = (uriString.EndsWith("/")) ? uriString.Substring(0, uriString.Length - 1) : uriString;

                //The service will render the schema only if there is a $metadata at the end in the Uri.
                serviceUri = serviceUri.Substring(0, serviceUri.Length - "/$metadata".Length);

                //Remove the scope name
                serviceUri = serviceUri.Substring(0, serviceUri.LastIndexOf("/") + 1);

                return(ParseCSDLDocument(parser, uriString, document));
            }
            throw new CsdlException(
                      string.Format("Downloaded XML content is not a valid <service> document. \nDocument Content: {0}",
                                    content));
        }
Exemple #9
0
        private static void ValidateCSDLMode(ArgsParser parser)
        {
            if (parser.OperationMode != OperationMode.Codegen)
            {
                throw new InvalidOperationException("Only /mode:codegen allowed when /url flag is used.");
            }

            if (parser.CodeGenMode == CodeGenTarget.Server)
            {
                throw new InvalidOperationException("/target:server is not a valid target when /url flag is used. Only isclient and client targets allowed.");
            }
        }
Exemple #10
0
        private static void ValidateConfigFile(ArgsParser parser, SyncConfigurationSection syncConfig)
        {
            if (syncConfig == null)
            {
                throw new InvalidOperationException("Unable to parse config file.");
            }

            if (syncConfig.SyncScopes.Count == 0)
            {
                throw new InvalidOperationException("Config file should contain atleast one <SyncScope> definition.");
            }

            if (syncConfig.Databases.Count == 0)
            {
                throw new InvalidOperationException("Config file should contain atleast one <TargetDatabase> definition.");
            }

            if (syncConfig.SyncScopes.Count > 1 && string.IsNullOrEmpty(parser.ScopeName))
            {
                throw new InvalidOperationException("More than one <SyncScope> definitions found. Specify /scopename parameter.");
            }

            if (syncConfig.Databases.Count > 1 && string.IsNullOrEmpty(parser.TargetDatabaseName))
            {
                throw new InvalidOperationException("More than one <TargetDatabase> definitions found. Specify /database parameter.");
            }

            if (!string.IsNullOrEmpty(parser.ScopeName) &&
                syncConfig.SyncScopes.Cast<SyncScopeConfigElement>().FirstOrDefault((e) => e.Name.Equals(parser.ScopeName, StringComparison.InvariantCultureIgnoreCase)) == null)
            {
                throw new ArgumentException("Scopename not found in SyncConfiguration/SyncScope definition.", parser.ScopeName);
            }

            if (!string.IsNullOrEmpty(parser.TargetDatabaseName) &&
                syncConfig.Databases.Cast<TargetDatabaseConfigElement>().FirstOrDefault((e) => e.Name.Equals(parser.TargetDatabaseName, StringComparison.InvariantCultureIgnoreCase)) == null)
            {
                throw new ArgumentException("TargetDatabase not found in SyncConfiguration/Databases definition.", parser.ScopeName);
            }
        }
Exemple #11
0
        private static void ProcessConfigFile(ArgsParser parser)
        {
            DbSyncScopeDescription scopeDescription;
            Dictionary<string, Dictionary<string, string>> tablesToColumnMappingsInfo = new Dictionary<string, Dictionary<string, string>>();

            if (string.IsNullOrEmpty(parser.ConfigFile))
            {
                LogArgsError("Required argument /scopeconfig is not specified.");
                return;
            }
            if (!System.IO.File.Exists(parser.ConfigFile))
            {
                LogArgsError("Unable to find scopeconfig file '" + parser.ConfigFile + "'");
                return;
            }

            System.Configuration.Configuration config = ConfigurationManager.OpenMappedExeConfiguration(new ExeConfigurationFileMap() { ExeConfigFilename = parser.ConfigFile }, ConfigurationUserLevel.None);

            Log("Reading specified config file...");
            SyncConfigurationSection syncConfig = config.GetSection(Constants.SyncConfigurationSectionName) as SyncConfigurationSection;

            // ValidateConfigFile the config and the passed in input parameters
            ValidateConfigFile(parser, syncConfig);

            // Fill in the defaults value for the parser.
            SelectedConfigSections selectedConfig = FillDefaults(parser, syncConfig);


            Log("Generating DbSyncScopeDescription for scope {0}...", selectedConfig.SelectedSyncScope.Name);
            scopeDescription = GetDbSyncScopeDescription(selectedConfig);
            tablesToColumnMappingsInfo = BuildColumnMappingInfo(selectedConfig);
            switch (parser.OperationMode)
            {

                case OperationMode.Provision:
                    try
                    {


                        SqlSyncScopeProvisioning prov = new SqlSyncScopeProvisioning(new SqlConnection(selectedConfig.SelectedTargetDatabase.GetConnectionString()),
                                            scopeDescription, selectedConfig.SelectedSyncScope.IsTemplateScope ? SqlSyncScopeProvisioningType.Template : SqlSyncScopeProvisioningType.Scope);

                        // Note: Deprovisioning does not work because of a bug in the provider when you set the ObjectSchema property to “dbo”. 
                        // The workaround is to not set the property (it internally assumes dbo in this case) so that things work on deprovisioning.
                        if (!String.IsNullOrEmpty(selectedConfig.SelectedSyncScope.SchemaName))
                        {
                            prov.ObjectSchema = selectedConfig.SelectedSyncScope.SchemaName;
                        }

                        foreach (SyncTableConfigElement tableElement in selectedConfig.SelectedSyncScope.SyncTables)
                        {
                            // Check and set the SchemaName for individual table if specified
                            if (!string.IsNullOrEmpty(tableElement.SchemaName))
                            {
                                prov.Tables[tableElement.GlobalName].ObjectSchema = tableElement.SchemaName;
                            }

                            prov.Tables[tableElement.GlobalName].FilterClause = tableElement.FilterClause;
                            foreach (FilterColumnConfigElement filterCol in tableElement.FilterColumns)
                            {
                                prov.Tables[tableElement.GlobalName].FilterColumns.Add(scopeDescription.Tables[tableElement.GlobalName].Columns[filterCol.Name]);
                            }
                            foreach (FilterParameterConfigElement filterParam in tableElement.FilterParameters)
                            {
                                CheckFilterParamTypeAndSize(filterParam);
                                prov.Tables[tableElement.GlobalName].FilterParameters.Add(new SqlParameter(filterParam.Name, (SqlDbType)Enum.Parse(typeof(SqlDbType), filterParam.SqlType, true)));
                                prov.Tables[tableElement.GlobalName].FilterParameters[filterParam.Name].Size = filterParam.DataSize;
                            }
                        }

                        // enable bulk procedures.
                        prov.SetUseBulkProceduresDefault(selectedConfig.SelectedSyncScope.EnableBulkApplyProcedures);

                        // Create a new set of enumeration stored procs per scope. 
                        // Without this multiple scopes share the same stored procedure which is not desirable.
                        prov.SetCreateProceduresForAdditionalScopeDefault(DbSyncCreationOption.Create);

                        if (selectedConfig.SelectedSyncScope.IsTemplateScope)
                        {
                            if (!prov.TemplateExists(selectedConfig.SelectedSyncScope.Name))
                            {
                                Log("Provisioning Database {0} for template scope {1}...", selectedConfig.SelectedTargetDatabase.Name, selectedConfig.SelectedSyncScope.Name);
                                prov.Apply();
                            }
                            else
                            {
                                throw new InvalidOperationException(string.Format("Database {0} already contains a template scope {1}. Please deprovision the scope and retry.", selectedConfig.SelectedTargetDatabase.Name,
                                    selectedConfig.SelectedSyncScope.Name));
                            }
                        }
                        else
                        {
                            if (!prov.ScopeExists(selectedConfig.SelectedSyncScope.Name))
                            {
                                Log("Provisioning Database {0} for scope {1}...", selectedConfig.SelectedTargetDatabase.Name, selectedConfig.SelectedSyncScope.Name);
                                prov.Apply();
                            }
                            else
                            {
                                throw new InvalidOperationException(string.Format("Database {0} already contains a scope {1}. Please deprovision the scope and retry.", selectedConfig.SelectedTargetDatabase.Name,
                                    selectedConfig.SelectedSyncScope.Name));
                            }
                        }
                    }
                    catch (ConfigurationErrorsException)
                    {
                        throw;
                    }
                    catch (InvalidOperationException)
                    {
                        throw;
                    }
                    catch (Exception e)
                    {
                        throw new InvalidOperationException("Unexpected error when executing the Provisioning command. See inner exception for details.", e);
                    }
                    break;
                case OperationMode.Deprovision:
                    try
                    {
                        SqlSyncScopeDeprovisioning deprov = new SqlSyncScopeDeprovisioning(new SqlConnection(selectedConfig.SelectedTargetDatabase.GetConnectionString()));

                        // Set the ObjectSchema property.
                        if (!String.IsNullOrEmpty(selectedConfig.SelectedSyncScope.SchemaName))
                        {
                            deprov.ObjectSchema = selectedConfig.SelectedSyncScope.SchemaName;
                        }

                        Log("Deprovisioning Database {0} for scope {1}...", selectedConfig.SelectedTargetDatabase.Name, selectedConfig.SelectedSyncScope.Name);

                        if (selectedConfig.SelectedSyncScope.IsTemplateScope)
                        {
                            deprov.DeprovisionTemplate(selectedConfig.SelectedSyncScope.Name);
                        }
                        else
                        {
                            deprov.DeprovisionScope(selectedConfig.SelectedSyncScope.Name);

                        }
                    }
                    catch (Exception e)
                    {
                        throw new InvalidOperationException("Unexpected error when executing the Deprovisioning command. See inner exception for details.", e);
                    }

                    break;
                case OperationMode.Deprovisionstore:
                    try
                    {
                        SqlSyncScopeDeprovisioning deprov = new SqlSyncScopeDeprovisioning(new SqlConnection(selectedConfig.SelectedTargetDatabase.GetConnectionString()));

                        Log("Deprovisioning Store Database {0} ...", selectedConfig.SelectedTargetDatabase.Name);

                        deprov.DeprovisionStore();
                    }
                    catch (Exception e)
                    {
                        throw new InvalidOperationException("Unexpected error when executing the Deprovisioning command. See inner exception for details.", e);
                    }

                    break;
                case OperationMode.Codegen:
                    Log("Generating files...");
                    EntityGenerator generator = EntityGeneratorFactory.Create(parser.CodeGenMode, selectedConfig.SelectedSyncScope.SchemaName);
                    generator.GenerateEntities(parser.GeneratedFilePrefix,
                        string.IsNullOrEmpty(parser.Namespace)
                        ? string.IsNullOrEmpty(parser.GeneratedFilePrefix) ? scopeDescription.ScopeName : parser.GeneratedFilePrefix
                        : parser.Namespace,
                        scopeDescription, tablesToColumnMappingsInfo, parser.WorkingDirectory, parser.Language, null/*serviceUri*/);
                    break;
                default:
                    break;
            }
        }
Exemple #12
0
        public static ArgsParser ParseArgs(string[] args)
        {
            ArgsParser parser = new ArgsParser();

            foreach (string param in args)
            {
                string[] tokens = param.Split(new char[] { ':' }, 2, StringSplitOptions.RemoveEmptyEntries);

                if (tokens.Count() != 2 &&
                    !tokens[0].Equals("/?", StringComparison.InvariantCultureIgnoreCase) &&
                    !tokens[0].Equals("/verbose", StringComparison.InvariantCultureIgnoreCase))
                {
                    throw new ArgumentException("Invalid parameter passed", param);
                }
                string token1 = tokens.Count() == 2 ? tokens[1] : string.Empty;

                switch (tokens[0].ToLowerInvariant())
                {
                case "/mode":
                    parser._modeSpecified = true;
                    if (!EnumUtils.TryEnumParse <OperationMode>(token1, out parser._operationMode))
                    {
                        throw new ArgumentOutOfRangeException(param, string.Format("Invalid {0} option specified.", tokens[0]));
                    }
                    break;

                case "/target":
                    if (!EnumUtils.TryEnumParse <CodeGenTarget>(token1, out parser._codeGenMode))
                    {
                        throw new ArgumentOutOfRangeException(param, string.Format("Invalid {0} option specified.", tokens[0]));
                    }
                    break;

                case "/language":
                    if (!EnumUtils.TryEnumParse <CodeLanguage>(token1, out parser._language))
                    {
                        throw new ArgumentOutOfRangeException(param, string.Format("Invalid {0} option specified.", tokens[0]));
                    }
                    break;

                case "/scopeconfig":
                    if (parser._csdlUri != null)
                    {
                        throw new InvalidOperationException("Cannot specify both /scopeconfig and /url option.");
                    }
                    parser._configFile = token1;
                    break;

                case "/url":
                    if (parser._configFile != null)
                    {
                        throw new InvalidOperationException("Cannot specify both /scopeconfig and /url option.");
                    }
                    parser._csdlUri = token1;
                    if (!new Uri(parser._csdlUri).IsAbsoluteUri)
                    {
                        throw new ArgumentException(string.Format("Sync scope schema Uri cannot be relative."), param);
                    }
                    break;

                case "/scopename":
                    parser._scopeName = token1;
                    break;

                case "/database":
                    parser._targetDatabaseName = token1;
                    break;

                case "/outprefix":
                    parser._generateFilePrefix = token1;
                    break;

                case "/directory":
                    parser._workingDirectory = new DirectoryInfo(token1);
                    break;

                case "/namespace":
                    parser._namespace = token1;
                    break;

                case "/verbose":
                    parser._verboseEnabled = true;
                    break;

                case "/?":
                    parser._helpRequested = true;
                    Console.WriteLine(GetHelpString());
                    break;

                default:
                    throw new ArgumentOutOfRangeException(param);
                }
            }

            return(parser);
        }
Exemple #13
0
        private static void ProcessConfigFile(ArgsParser parser)
        {
            DbSyncScopeDescription scopeDescription;
            Dictionary <string, Dictionary <string, string> > tablesToColumnMappingsInfo = new Dictionary <string, Dictionary <string, string> >();

            if (string.IsNullOrEmpty(parser.ConfigFile))
            {
                LogArgsError("Required argument /scopeconfig is not specified.");
                return;
            }
            if (!System.IO.File.Exists(parser.ConfigFile))
            {
                LogArgsError("Unable to find scopeconfig file '" + parser.ConfigFile + "'");
                return;
            }

            System.Configuration.Configuration config = ConfigurationManager.OpenMappedExeConfiguration(new ExeConfigurationFileMap()
            {
                ExeConfigFilename = parser.ConfigFile
            }, ConfigurationUserLevel.None);

            Log("Reading specified config file...");
            SyncConfigurationSection syncConfig = config.GetSection(Constants.SyncConfigurationSectionName) as SyncConfigurationSection;

            // ValidateConfigFile the config and the passed in input parameters
            ValidateConfigFile(parser, syncConfig);

            // Fill in the defaults value for the parser.
            SelectedConfigSections selectedConfig = FillDefaults(parser, syncConfig);


            Log("Generating DbSyncScopeDescription for scope {0}...", selectedConfig.SelectedSyncScope.Name);
            scopeDescription           = GetDbSyncScopeDescription(selectedConfig);
            tablesToColumnMappingsInfo = BuildColumnMappingInfo(selectedConfig);
            switch (parser.OperationMode)
            {
            case OperationMode.Provision:
                Provision(selectedConfig, scopeDescription, false, parser.WorkingDirectory);
                break;

            case OperationMode.ProvisionScript:
                Provision(selectedConfig, scopeDescription, true, parser.WorkingDirectory);
                break;

            case OperationMode.Deprovision:
                Deprovision(selectedConfig, false, parser.WorkingDirectory);
                break;

            case OperationMode.DeprovisionScript:
                Deprovision(selectedConfig, true, parser.WorkingDirectory);
                break;

            case OperationMode.Deprovisionstore:
                DeprovisionStore(selectedConfig, false, parser.WorkingDirectory);
                break;

            case OperationMode.DeprovisionstoreScript:
                DeprovisionStore(selectedConfig, true, parser.WorkingDirectory);
                break;

            case OperationMode.Codegen:
                Log("Generating files...");
                EntityGenerator generator = EntityGeneratorFactory.Create(parser.CodeGenMode, selectedConfig.SelectedSyncScope.SchemaName);
                generator.GenerateEntities(parser.GeneratedFilePrefix,
                                           string.IsNullOrEmpty(parser.Namespace)
                        ? string.IsNullOrEmpty(parser.GeneratedFilePrefix) ? scopeDescription.ScopeName : parser.GeneratedFilePrefix
                        : parser.Namespace,
                                           scopeDescription, tablesToColumnMappingsInfo, parser.WorkingDirectory, parser.Language, null /*serviceUri*/);
                break;

            default:
                break;
            }
        }
        public static DbSyncScopeDescription GetDescriptionFromUri(ArgsParser parser, string uriString, out string serviceUri)
        {
            // Issue the request.
            WebClient request = new WebClient();
            SyncSvcUtil.Log("Trying to connect to Uri '{0}' to check for SyncScopeSchema document", uriString);

            string content = request.DownloadString(uriString);

            // Check to see if its a SyncScopes <services> document or an SyncScopeSchema <edmx> document.
            if (parser.UseVerbose)
            {
                SyncSvcUtil.Log("Download succeeded. Checking to see if its a SyncScope <Service> document or an SyncScopeSchema <edmx> document.");
                SyncSvcUtil.Log("Downloaded document content:\n {0}", content);
            }

            SyncSvcUtil.Log("Parsing downloaded document.", uriString);

            XDocument document = XDocument.Parse(content);
            if (document == null)
            {
                throw new CsdlException("Downloaded content is not a valid XML document.");
            }

            if (document.Root.Name.Equals(Constants.SyncScopeServicesElement))
            {
                if (parser.UseVerbose)
                {
                    SyncSvcUtil.Log("Found a <service> document. Checking for SyncScopes workspace.");
                }
                XElement workspaceElement = document.Root.Element(Constants.SyncScopeWorkspaceElement);
                if (workspaceElement == null)
                {
                    throw new CsdlException("Remote SyncScope services document did not contain a <workspace> element.");
                }

                // Look for <collection> element
                XElement[] collectionElements = workspaceElement.Elements(Constants.SyncScopeWorkspaceCollectionElement).ToArray();
                if (collectionElements.Length == 0)
                {
                    throw new CsdlException("Remote SyncScope services document did not contain a <collection> element.");
                }
                else if (collectionElements.Length > 1)
                {
                    SyncSvcUtil.Log("Multiple SyncScopes were found in the <service> document. Please specify the correct Url.");
                    foreach (XElement elem in collectionElements)
                    {
                        XAttribute hrefAttr = elem.Attribute(Constants.SyncScopeWorkspaceCollectionHrefAttribute);
                        SyncSvcUtil.Log("\t\t{0} - Uri: {1}{2}{0}/$metadata",
                        hrefAttr.Value,
                        parser.CSDLUrl,
                        parser.CSDLUrl.EndsWith("/") ? string.Empty : "/");
                    }
                    throw new CsdlException("Multiple SyncScopes found.");
                }
                else
                {
                    // We have exactly one SyncScope. Download the schema for that
                    XAttribute hrefAttr = collectionElements[0].Attribute(Constants.SyncScopeWorkspaceCollectionHrefAttribute);
                    if (hrefAttr == null)
                    {
                        throw new CsdlException("No Href attribute was found in the <collection> element.");
                    }

                    // Ensure the href param is not empty as this is the scopeName
                    if (string.IsNullOrEmpty(hrefAttr.Value))
                    {
                        throw new CsdlException(string.Format("Href attribute in <collection> must have a non empty string.\n Content: {0}", collectionElements[0].ToString()));
                    }

                    // Look for and remove $syncScopes
                    string origUrl = parser.CSDLUrl;
                    if (origUrl.EndsWith("$syncscopes", StringComparison.InvariantCultureIgnoreCase))
                    {
                        origUrl = origUrl.Substring(0, origUrl.LastIndexOf("/"));
                    }
                    
                    uriString = string.Format("{0}{1}{2}/$metadata",
                        origUrl,
                        origUrl.EndsWith("/") ? string.Empty : "/",
                        hrefAttr.Value);

                    return CSDLParser.GetDescriptionFromUri(parser, uriString, out serviceUri);
                }

            }
            else if (document.Root.Name.Equals(Constants.SyncScopeEdmxElement))
            {
                // Set the service URI and remove $metadata token from it.                
                //Remove the / at the end if present.
                serviceUri = (uriString.EndsWith("/")) ? uriString.Substring(0, uriString.Length - 1) : uriString;

                //The service will render the schema only if there is a $metadata at the end in the Uri.                
                serviceUri = serviceUri.Substring(0, serviceUri.Length - "/$metadata".Length);

                //Remove the scope name
                serviceUri = serviceUri.Substring(0, serviceUri.LastIndexOf("/") + 1);
               
                return ParseCSDLDocument(parser, uriString, document);
            }
            else
            {
                throw new CsdlException(string.Format("Downloaded XML content is not a valid <service> document. \nDocument Content: {0}", content));
            }
        }
Exemple #15
0
        private static SelectedConfigSections FillDefaults(ArgsParser parser, SyncConfigurationSection syncConfig)
        {
            SelectedConfigSections sections = new SelectedConfigSections();

            if (string.IsNullOrEmpty(parser.ScopeName) && syncConfig.SyncScopes.Count == 1)
            {
                sections.SelectedSyncScope = syncConfig.SyncScopes.Cast<SyncScopeConfigElement>().First();
                parser.ScopeName = sections.SelectedSyncScope.Name;
            }
            else
            {
                sections.SelectedSyncScope = syncConfig.SyncScopes.Cast<SyncScopeConfigElement>().Single((e) => e.Name.Equals(parser.ScopeName, StringComparison.InvariantCultureIgnoreCase));
            }

            if (string.IsNullOrEmpty(parser.TargetDatabaseName) && syncConfig.Databases.Count == 1)
            {
                sections.SelectedTargetDatabase = syncConfig.Databases.Cast<TargetDatabaseConfigElement>().First();
                parser.TargetDatabaseName = sections.SelectedTargetDatabase.Name;
            }
            else
            {
                sections.SelectedTargetDatabase = syncConfig.Databases.Cast<TargetDatabaseConfigElement>().Single((e) => e.Name.Equals(parser.TargetDatabaseName, StringComparison.InvariantCultureIgnoreCase));
            }
            
            return sections;
        }
Exemple #16
0
        private static DbSyncScopeDescription ParseCSDLDocument(ArgsParser parser, string uriString, XDocument document)
        {
            DbSyncScopeDescription scopeDescription = null;
            var uri = new Uri(uriString);
            // Assumption is that for OData Sync metadata document, the URI is of format http://foo/snc.svc/scopename/$metadata.
            // In this case we are looking for the last but one segment.
            var scopeName = uri.Segments[uri.Segments.Length - 2];

            if (scopeName.EndsWith("/"))
            {
                scopeName = scopeName.Substring(0, scopeName.Length - 1);
            }

            if (parser.UseVerbose)
            {
                SyncSvcUtil.Log("Parsed ScopeName as {0}", scopeName);
            }

            // Its an CSDL document
            var dataServicesElem = document.Root.Element(Constants.SyncScopeDataServicesElement);

            if (dataServicesElem == null)
            {
                throw new CsdlException("No <DataServices> element found in the <edmx> document.");
            }
            var schemaElement = dataServicesElem.Element(Constants.SyncScopeSchemaElement);

            if (schemaElement == null)
            {
                throw new CsdlException("No <Schema> element found in the <DataServices> document.");
            }

            scopeDescription = new DbSyncScopeDescription(scopeName);
            // Loop over each <EntityType> element and add it as a DbSyncTableDescription
            foreach (var entity in schemaElement.Elements(Constants.SyncScopeEntityTypeElement))
            {
                var nameAttr = entity.Attribute(Constants.SyncScopeEntityTypeNameAttribute);
                if (nameAttr == null)
                {
                    throw new CsdlException("<EntityType> has no Name attribute. \n" + entity);
                }
                // Parse each entity and create a DbSyncTableDescription
                var table = new DbSyncTableDescription(nameAttr.Value);

                // Look for <Key> element
                var keyElem = entity.Element(Constants.SyncScopeEntityTypeKeyElement);
                if (keyElem == null)
                {
                    throw new CsdlException("<EntityType> has no <Key> elements defined. \n" + entity);
                }

                var keyNames = new List <string>();
                // Loop over each <PropertyRef> element and add it to the list for lookup
                foreach (var prop in keyElem.Elements(Constants.SyncScopeEntityTypeKeyRefElement))
                {
                    var keyName = prop.Attribute(Constants.SyncScopeEntityTypeNameAttribute);
                    if (keyName != null)
                    {
                        keyNames.Add(keyName.Value);
                    }
                }

                // Loop over each <Property> element and add it as a DbSyncColumnDescription
                foreach (var field in entity.Elements(Constants.SyncScopeEntityTypePropertyElement))
                {
                    // Read Property name
                    var fieldName = field.Attribute(Constants.SyncScopeEntityTypeNameAttribute);
                    if (fieldName == null)
                    {
                        throw new CsdlException("<Property> has no Name attribute. \n" + field);
                    }

                    // Read Property Edm type
                    var fieldType = field.Attribute(Constants.SyncScopeEntityTypeTypeAttribute);
                    if (fieldType == null)
                    {
                        throw new CsdlException("<Property> has no Type attribute. \n" + field);
                    }

                    // Read Property Nullable attribute
                    var fieldNullable = field.Attribute(Constants.SyncScopeEntityTypeNullableAttribute);

                    var column = new DbSyncColumnDescription(fieldName.Value, GetSqlTypeForEdm(fieldType.Value));
                    if (fieldNullable != null && bool.Parse(fieldNullable.Value))
                    {
                        column.IsNullable = true;
                    }
                    column.IsPrimaryKey = keyNames.Contains(fieldName.Value);
                    table.Columns.Add(column);
                }

                scopeDescription.Tables.Add(table);
            }
            return(scopeDescription);
        }
Exemple #17
0
        private static void ProcessCSDLUri(ArgsParser parser)
        {
            Dictionary<string, Dictionary<string, string>> tablesToColumnMappingsInfo = new Dictionary<string, Dictionary<string, string>>();

            ValidateCSDLMode(parser);
            string serviceUri = null;
            DbSyncScopeDescription scopeDescription = CSDLParser.GetDescriptionFromUri(parser, parser.CSDLUrl, out serviceUri);

            Log("Generating files...");
            EntityGenerator generator = EntityGeneratorFactory.Create(parser.CodeGenMode, null /* null syncSchema - not needed for client code generation */);
            generator.GenerateEntities(parser.GeneratedFilePrefix,
                string.IsNullOrEmpty(parser.Namespace)
                ? string.IsNullOrEmpty(parser.GeneratedFilePrefix) ? scopeDescription.ScopeName : parser.GeneratedFilePrefix
                : parser.Namespace,
                scopeDescription, tablesToColumnMappingsInfo, parser.WorkingDirectory, parser.Language, serviceUri);
        }
        public static ArgsParser ParseArgs(string[] args)
        {
            ArgsParser parser = new ArgsParser();

            foreach (string param in args)
            {
                string[] tokens = param.Split(new char[] { ':' }, 2, StringSplitOptions.RemoveEmptyEntries);

                if (tokens.Count<string>() != 2  && 
                    !tokens[0].Equals("/?", StringComparison.InvariantCultureIgnoreCase) && 
                    !tokens[0].Equals("/verbose", StringComparison.InvariantCultureIgnoreCase))
                {
                    throw new ArgumentException("Invalid parameter passed", param);
                }

                switch (tokens[0].ToLowerInvariant())
                {
                    case "/mode":
                        parser._modeSpecified = true;
                        if (!EnumUtils.TryEnumParse<OperationMode>(tokens[1], out parser._operationMode))
                        {
                            throw new ArgumentOutOfRangeException(param, string.Format("Invalid {0} option specified.", tokens[0]));
                        }
                        break;
                    case "/target":
                        if (!EnumUtils.TryEnumParse<CodeGenTarget>(tokens[1], out parser._codeGenMode))
                        {
                            throw new ArgumentOutOfRangeException(param, string.Format("Invalid {0} option specified.", tokens[0]));
                        }
                        break;
                    case "/language":
                        if (!EnumUtils.TryEnumParse<CodeLanguage>(tokens[1], out parser._language))
                        {
                            throw new ArgumentOutOfRangeException(param, string.Format("Invalid {0} option specified.", tokens[0]));
                        }
                        break;
                    case "/scopeconfig":
                        if (parser._csdlUri != null)
                        {
                            throw new InvalidOperationException("Cannot specify both /scopeconfig and /url option.");
                        }
                        parser._configFile = tokens[1];
                        break;
                    case "/url":
                        if (parser._configFile != null)
                        {
                            throw new InvalidOperationException("Cannot specify both /scopeconfig and /url option.");
                        }
                        parser._csdlUri = tokens[1];
                        if (!new Uri(parser._csdlUri).IsAbsoluteUri)
                        {
                            throw new ArgumentException(string.Format("Sync scope schema Uri cannot be relative."), param);
                        }
                        break;
                    case "/scopename":
                        parser._scopeName = tokens[1];
                        break;
                    case "/database":
                        parser._targetDatabaseName = tokens[1];
                        break;
                    case "/outprefix":
                        parser._generateFilePrefix = tokens[1];
                        break;
                    case "/directory":
                        parser._workingDirectory = new DirectoryInfo(tokens[1]);
                        break;
                    case "/namespace":
                        parser._namespace = tokens[1];
                        break;
                    case "/verbose":
                        parser._verboseEnabled = true;
                        break;
                    case "/?":
                        parser._helpRequested = true;
                        Console.WriteLine(GetHelpString());
                        break;
                    default:
                        throw new ArgumentOutOfRangeException(param);
                }                
            }

            return parser;
        }
Exemple #19
0
        private static void ProcessConfigFile(ArgsParser parser)
        {
            DbSyncScopeDescription scopeDescription;
            Dictionary <string, Dictionary <string, string> > tablesToColumnMappingsInfo = new Dictionary <string, Dictionary <string, string> >();

            if (string.IsNullOrEmpty(parser.ConfigFile))
            {
                LogArgsError("Required argument /scopeconfig is not specified.");
                return;
            }
            if (!System.IO.File.Exists(parser.ConfigFile))
            {
                LogArgsError("Unable to find scopeconfig file '" + parser.ConfigFile + "'");
                return;
            }

            System.Configuration.Configuration config = ConfigurationManager.OpenMappedExeConfiguration(new ExeConfigurationFileMap()
            {
                ExeConfigFilename = parser.ConfigFile
            }, ConfigurationUserLevel.None);

            Log("Reading specified config file...");
            SyncConfigurationSection syncConfig = config.GetSection(Constants.SyncConfigurationSectionName) as SyncConfigurationSection;

            // ValidateConfigFile the config and the passed in input parameters
            ValidateConfigFile(parser, syncConfig);

            // Fill in the defaults value for the parser.
            SelectedConfigSections selectedConfig = FillDefaults(parser, syncConfig);


            Log("Generating DbSyncScopeDescription for scope {0}...", selectedConfig.SelectedSyncScope.Name);
            scopeDescription           = GetDbSyncScopeDescription(selectedConfig);
            tablesToColumnMappingsInfo = BuildColumnMappingInfo(selectedConfig);
            switch (parser.OperationMode)
            {
            case OperationMode.Provision:
                try
                {
                    SqlSyncScopeProvisioning prov = new SqlSyncScopeProvisioning(new SqlConnection(selectedConfig.SelectedTargetDatabase.GetConnectionString()),
                                                                                 scopeDescription, selectedConfig.SelectedSyncScope.IsTemplateScope ? SqlSyncScopeProvisioningType.Template : SqlSyncScopeProvisioningType.Scope);

                    // Note: Deprovisioning does not work because of a bug in the provider when you set the ObjectSchema property to “dbo”.
                    // The workaround is to not set the property (it internally assumes dbo in this case) so that things work on deprovisioning.
                    if (!String.IsNullOrEmpty(selectedConfig.SelectedSyncScope.SchemaName))
                    {
                        prov.ObjectSchema = selectedConfig.SelectedSyncScope.SchemaName;
                    }

                    foreach (SyncTableConfigElement tableElement in selectedConfig.SelectedSyncScope.SyncTables)
                    {
                        // Check and set the SchemaName for individual table if specified
                        if (!string.IsNullOrEmpty(tableElement.SchemaName))
                        {
                            prov.Tables[tableElement.GlobalName].ObjectSchema = tableElement.SchemaName;
                        }

                        prov.Tables[tableElement.GlobalName].FilterClause = tableElement.FilterClause;
                        foreach (FilterColumnConfigElement filterCol in tableElement.FilterColumns)
                        {
                            prov.Tables[tableElement.GlobalName].FilterColumns.Add(scopeDescription.Tables[tableElement.GlobalName].Columns[filterCol.Name]);
                        }
                        foreach (FilterParameterConfigElement filterParam in tableElement.FilterParameters)
                        {
                            CheckFilterParamTypeAndSize(filterParam);
                            prov.Tables[tableElement.GlobalName].FilterParameters.Add(new SqlParameter(filterParam.Name, (SqlDbType)Enum.Parse(typeof(SqlDbType), filterParam.SqlType, true)));
                            prov.Tables[tableElement.GlobalName].FilterParameters[filterParam.Name].Size = filterParam.DataSize;
                        }
                    }

                    // enable bulk procedures.
                    prov.SetUseBulkProceduresDefault(selectedConfig.SelectedSyncScope.EnableBulkApplyProcedures);

                    // Create a new set of enumeration stored procs per scope.
                    // Without this multiple scopes share the same stored procedure which is not desirable.
                    prov.SetCreateProceduresForAdditionalScopeDefault(DbSyncCreationOption.Create);

                    if (selectedConfig.SelectedSyncScope.IsTemplateScope)
                    {
                        if (!prov.TemplateExists(selectedConfig.SelectedSyncScope.Name))
                        {
                            Log("Provisioning Database {0} for template scope {1}...", selectedConfig.SelectedTargetDatabase.Name, selectedConfig.SelectedSyncScope.Name);
                            prov.Apply();
                        }
                        else
                        {
                            throw new InvalidOperationException(string.Format("Database {0} already contains a template scope {1}. Please deprovision the scope and retry.", selectedConfig.SelectedTargetDatabase.Name,
                                                                              selectedConfig.SelectedSyncScope.Name));
                        }
                    }
                    else
                    {
                        if (!prov.ScopeExists(selectedConfig.SelectedSyncScope.Name))
                        {
                            Log("Provisioning Database {0} for scope {1}...", selectedConfig.SelectedTargetDatabase.Name, selectedConfig.SelectedSyncScope.Name);
                            prov.Apply();
                        }
                        else
                        {
                            throw new InvalidOperationException(string.Format("Database {0} already contains a scope {1}. Please deprovision the scope and retry.", selectedConfig.SelectedTargetDatabase.Name,
                                                                              selectedConfig.SelectedSyncScope.Name));
                        }
                    }
                }
                catch (ConfigurationErrorsException)
                {
                    throw;
                }
                catch (InvalidOperationException)
                {
                    throw;
                }
                catch (Exception e)
                {
                    throw new InvalidOperationException("Unexpected error when executing the Provisioning command. See inner exception for details.", e);
                }
                break;

            case OperationMode.Deprovision:
                try
                {
                    SqlSyncScopeDeprovisioning deprov = new SqlSyncScopeDeprovisioning(new SqlConnection(selectedConfig.SelectedTargetDatabase.GetConnectionString()));

                    // Set the ObjectSchema property.
                    if (!String.IsNullOrEmpty(selectedConfig.SelectedSyncScope.SchemaName))
                    {
                        deprov.ObjectSchema = selectedConfig.SelectedSyncScope.SchemaName;
                    }

                    Log("Deprovisioning Database {0} for scope {1}...", selectedConfig.SelectedTargetDatabase.Name, selectedConfig.SelectedSyncScope.Name);

                    if (selectedConfig.SelectedSyncScope.IsTemplateScope)
                    {
                        deprov.DeprovisionTemplate(selectedConfig.SelectedSyncScope.Name);
                    }
                    else
                    {
                        deprov.DeprovisionScope(selectedConfig.SelectedSyncScope.Name);
                    }
                }
                catch (Exception e)
                {
                    throw new InvalidOperationException("Unexpected error when executing the Deprovisioning command. See inner exception for details.", e);
                }

                break;

            case OperationMode.Deprovisionstore:
                try
                {
                    SqlSyncScopeDeprovisioning deprov = new SqlSyncScopeDeprovisioning(new SqlConnection(selectedConfig.SelectedTargetDatabase.GetConnectionString()));

                    Log("Deprovisioning Store Database {0} ...", selectedConfig.SelectedTargetDatabase.Name);

                    deprov.DeprovisionStore();
                }
                catch (Exception e)
                {
                    throw new InvalidOperationException("Unexpected error when executing the Deprovisioning command. See inner exception for details.", e);
                }

                break;

            case OperationMode.Codegen:
                Log("Generating files...");
                EntityGenerator generator = EntityGeneratorFactory.Create(parser.CodeGenMode, selectedConfig.SelectedSyncScope.SchemaName);
                generator.GenerateEntities(parser.GeneratedFilePrefix,
                                           string.IsNullOrEmpty(parser.Namespace)
                        ? string.IsNullOrEmpty(parser.GeneratedFilePrefix) ? scopeDescription.ScopeName : parser.GeneratedFilePrefix
                        : parser.Namespace,
                                           scopeDescription, tablesToColumnMappingsInfo, parser.WorkingDirectory, parser.Language, null /*serviceUri*/);
                break;

            default:
                break;
            }
        }