#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
}
}