#region MIT license // // MIT license // // Copyright (c) 2007-2008 Jiri Moudry, Pascal Craponne // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // #endregion using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Text; using System.IO; using System.Reflection; using DbLinq.Util; using Mono.Options; namespace DbMetal { [DebuggerDisplay("Parameters from {Provider}, server={Server}")] public class Parameters { /// /// user name for database access /// public string User { get; set; } /// /// user password for database access /// public string Password { get; set; } /// /// server host name /// public string Server { get; set; } /// /// database name /// public string Database { get; set; } /// /// This connection string if present overrides User, Password, Server. /// Database is always used to generate the specific DataContext name /// public string Conn { get; set; } /// /// the namespace to put our classes into /// public string Namespace { get; set; } /// /// the language to generate classes for /// public string Language { get; set; } /// /// If present, write out C# code /// public string Code { get; set; } /// /// if present, write out DBML XML representing the DB /// public string Dbml { get; set; } /// /// when true, we will call Singularize()/Pluralize() functions. /// public bool Pluralize { get; set; } /// /// the culture used for word recognition and pluralization /// public string Culture { get; set; } /// /// load object renamings from an xml file /// public string Aliases { get; set; } /// /// this is the "input file" parameter /// public string SchemaXmlFile { get { return Extra.Count > 0 ? Extra[0] : null; } } public bool Schema { get; set; } /// /// base class from which all generated entities will inherit /// public string EntityBase { get; set; } /// /// interfaces to be implemented /// public string[] EntityInterfaces { get; set; } /// /// extra attributes to be implemented by class members /// public IList MemberAttributes { get; set; } /// /// generate Equals() and GetHashCode() /// public bool GenerateEqualsHash { get; set; } /// /// export stored procedures /// public bool Sprocs { get; set; } /// /// preserve case of database names /// public string Case { get; set; } /// /// force a Console.ReadKey at end of program. /// Useful when running from Studio, so the output window does not disappear /// picrap comment: you may use the tool to write output to Visual Studio output window instead of a console window /// public bool Readline { get; set; } /// /// specifies a provider (which here is a pair or ISchemaLoader and IDbConnection implementors) /// public string Provider { get; set; } /// /// for fine tuning, we allow to specifiy an ISchemaLoader /// public string DbLinqSchemaLoaderProvider { get; set; } /// /// for fine tuning, we allow to specifiy an IDbConnection /// public string DatabaseConnectionProvider { get; set; } /// /// the SQL dialect used by the database /// public string SqlDialectType { get; set; } /// /// the types to be generated /// public IList GenerateTypes { get; set; } /// /// if true, put a timestamp comment before the generated code /// public bool GenerateTimestamps { get; set; } /// /// show help /// public bool Help { get; set; } /// /// Show stack traces in error messages, etc., instead of just the message. /// public bool Debug { get; set; } /// /// non-option parameters /// public IList Extra = new List(); TextWriter log; public TextWriter Log { get { return log ?? Console.Out; } set { log = value; } } protected OptionSet Options; public Parameters() { Schema = true; Culture = "en"; GenerateTypes = new List(); MemberAttributes = new List(); GenerateTimestamps = true; EntityInterfaces = new []{ "INotifyPropertyChanging", "INotifyPropertyChanged" }; } public void Parse(IList args) { Options = new OptionSet() { // SQLMetal compatible { "c|conn=", "Database {CONNECTION STRING}. Cannot be used with /server, " +"/user or /password options.", conn => Conn = conn }, // SQLMetal compatible { "u|user=", "Login user {NAME}.", name => User = name }, // SQLMetal compatible { "p|password=", "Login {PASSWORD}.", password => Password = password }, // SQLMetal compatible { "s|server=", "Database server {NAME}.", name => Server = name }, // SQLMetal compatible { "d|database=", "Database catalog {NAME} on server.", name => Database = name }, { "provider=", "Specify {PROVIDER}. May be Ingres, MySql, Oracle, OracleODP, PostgreSql or Sqlite.", provider => Provider = provider }, { "with-schema-loader=", "ISchemaLoader implementation {TYPE}.", type => DbLinqSchemaLoaderProvider = type }, { "with-dbconnection=", "IDbConnection implementation {TYPE}.", type => DatabaseConnectionProvider = type }, { "with-sql-dialect=", "IVendor implementation {TYPE}.", type => SqlDialectType = type }, // SQLMetal compatible { "code=", "Output as source code to {FILE}. Cannot be used with /dbml option.", file => Code = file }, // SQLMetal compatible { "dbml=", "Output as dbml to {FILE}. Cannot be used with /map option.", file => Dbml = file }, // SQLMetal compatible { "language=", "Language {NAME} for source code: C#, C#2 or VB " +"(default: derived from extension on code file name).", name => Language = name }, { "aliases=", "Use mapping {FILE}.", file => Aliases = file }, { "schema", "Generate schema in code files (default: enabled).", v => Schema = v != null }, // SQLMetal compatible { "namespace=", "Namespace {NAME} of generated code (default: no namespace).", name => Namespace = name }, // SQLMetal compatible { "entitybase=", "Base {TYPE} of entity classes in the generated code " +"(default: entities have no base class).", type => EntityBase = type }, { "member-attribute=", "{ATTRIBUTE} for entity members in the generated code, " +"can be specified multiple times.", attribute => MemberAttributes.Add(attribute) }, { "generate-type=", "Generate only the {TYPE} selected, can be specified multiple times " +"and does not prevent references from being generated (default: " +"generate a DataContex subclass and all the entities in the schema).", type => GenerateTypes.Add(type) }, { "generate-equals-hash", "Generates overrides for Equals() and GetHashCode() methods.", v => GenerateEqualsHash = v != null }, // SQLMetal compatible { "sprocs", "Extract stored procedures.", v => Sprocs = v != null}, // SQLMetal compatible { "pluralize", "Automatically pluralize or singularize class and member names " +"using specified culture rules.", v => Pluralize = v != null}, { "culture=", "Specify {CULTURE} for word recognition and pluralization (default: \"en\").", culture => Culture = culture }, { "case=", "Transform names with the indicated {STYLE} " +"(default: net; may be: leave, pascal, camel, net).", style => Case = style }, { "generate-timestamps", "Generate timestampes in the generated code (default: enabled).", v => GenerateTimestamps = v != null }, { "readline", "Wait for a key to be pressed after processing.", v => Readline = v != null }, { "debug", "Enables additional information to help with debugging, " + "such as full stack traces in error messages.", v => Debug = v != null }, { "h|?|help", "Show this help", v => Help = v != null } }; Extra = Options.Parse(args); } #region Help public void WriteHelp() { WriteHeader(); // includes a WriteLine() WriteSyntax(); WriteLine(); WriteSummary(); WriteLine(); Options.WriteOptionDescriptions(Log); WriteLine(); WriteExamples(); } bool headerWritten; /// /// Writes the application header /// public void WriteHeader() { if (!headerWritten) { WriteHeaderContents(); WriteLine(); headerWritten = true; } } protected void WriteHeaderContents() { var version = ApplicationVersion; Write("DbLinq Database mapping generator 2008 version {0}.{1}", version.Major, version.Minor); Write("for Microsoft (R) .NET Framework version 3.5"); Write("Distributed under the MIT licence (http://linq.to/db/license)"); } /// /// Writes a small summary /// public void WriteSummary() { Write(" Generates code and mapping for DbLinq. SqlMetal can:"); Write(" - Generate source code and mapping attributes or a mapping file from a database."); Write(" - Generate an intermediate dbml file for customization from the database."); Write(" - Generate code and mapping attributes or mapping file from a dbml file."); } public void WriteSyntax() { var syntax = new StringBuilder(); syntax.AppendFormat("{0} [OPTIONS] []", ApplicationName); Write(syntax.ToString()); } /// /// Writes examples /// public void WriteExamples() { } /// /// Outputs a formatted string to the console. /// We're not using the ILogger here, since we want console output. /// /// /// public void Write(string format, params object[] args) { Output.WriteLine(Log, OutputLevel.Information, format, args); } /// /// Outputs an empty line /// public void WriteLine() { Output.WriteLine(Log, OutputLevel.Information, string.Empty); } /// /// Returns the application (assembly) name (without extension) /// protected static string ApplicationName { get { return Assembly.GetEntryAssembly().GetName().Name; } } /// /// Returns the application (assembly) version /// protected static Version ApplicationVersion { get { // Assembly.GetEntryAssembly() is null when loading from the // non-default AppDomain. var a = Assembly.GetEntryAssembly(); return a != null ? a.GetName().Version : new Version(); } } #endregion } }