[PATCH] Cleanup of the DbMetal command line

49 views
Skip to first unread message

Emanuele Aina

unread,
Nov 16, 2009, 3:57:43 PM11/16/09
to DbLinq
A quite big cleanup of DbMetal command-line interface:

* renamed -dbLinqSchemaLoaderProvider to -schema-loader
* renamed -databaseConnectionProvider to -dbconnection
* renamed -sqlDialectType to -vendor
* removed -renamesFile alias for -aliases
* renamed -entityBase to -entitybase
* changed the comma separated -entityAttributes to a repeatable
single-item -entity-attribute
* ditto for -memberAttributes and -member-attribute
* renamed -generateEqualsAndHash to -generate-equals-hash
* renamed -readlineAtExit to -readline
* retouched a bit some parameter descriptions

Gzipped patch attached.

---
.../CodeTextGenerator/CodeGenerator.Class.cs | 8 ++--
.../CodeTextGenerator/CodeGenerator.cs | 8 ++--
src/DbMetal/Generator/Implementation/Processor.cs | 2 +-
src/DbMetal/Parameters.cs | 58 ++++++++++----------
4 files changed, 39 insertions(+), 37 deletions(-)

diff --git a/src/DbMetal/Generator/Implementation/CodeTextGenerator/CodeGenerator.Class.cs b/src/DbMetal/Generator/Implementation/CodeTextGenerator/CodeGenerator.Class.cs
index f09a35c..a0b41ee 100644
--- a/src/DbMetal/Generator/Implementation/CodeTextGenerator/CodeGenerator.Class.cs
+++ b/src/DbMetal/Generator/Implementation/CodeTextGenerator/CodeGenerator.Class.cs
@@ -77,7 +77,7 @@ namespace DbMetal.Generator.Implementation.CodeTextGenerator
var tableAttribute = NewAttributeDefinition<TableAttribute>();
tableAttribute["Name"] = table.Name;
//using (WriteAttributes(writer, context.Parameters.EntityExposedAttributes))
- using (WriteAttributes(writer, GetAttributeNames(context, context.Parameters.EntityExposedAttributes)))
+ using (WriteAttributes(writer, GetAttributeNames(context, context.Parameters.EntityAttributes)))
using (writer.WriteAttribute(tableAttribute))
using (writer.WriteClass(specifications,
table.Type.Name, entityBase, context.Parameters.EntityInterfaces))
@@ -86,7 +86,7 @@ namespace DbMetal.Generator.Implementation.CodeTextGenerator
WriteCustomTypes(writer, table, schema, context);
WriteClassExtensibilityDeclarations(writer, table, context);
WriteClassProperties(writer, table, context);
- if (context.Parameters.GenerateEqualsAndHash)
+ if (context.Parameters.GenerateEqualsHash)
WriteClassEqualsAndHash(writer, table, context);
WriteClassChildren(writer, table, schema, context);
WriteClassParents(writer, table, schema, context);
@@ -269,7 +269,7 @@ namespace DbMetal.Generator.Implementation.CodeTextGenerator
/// <param name="context"></param>
/// <param name="attributes"></param>
/// <returns></returns>
- protected virtual string[] GetAttributeNames(GenerationContext context, string[] attributes)
+ protected virtual string[] GetAttributeNames(GenerationContext context, IEnumerable<string> attributes)
{
return (from a in attributes select GetName(a)).ToArray();
}
@@ -325,7 +325,7 @@ namespace DbMetal.Generator.Implementation.CodeTextGenerator
specifications |= GetSpecificationDefinition(property.Modifier);

//using (WriteAttributes(writer, context.Parameters.MemberExposedAttributes))
- using (WriteAttributes(writer, GetAttributeNames(context, context.Parameters.MemberExposedAttributes)))
+ using (WriteAttributes(writer, GetAttributeNames(context, context.Parameters.MemberAttributes)))
using (writer.WriteAttribute(NewAttributeDefinition<DebuggerNonUserCodeAttribute>()))
using (writer.WriteAttribute(column))
using (writer.WriteProperty(specifications, property.Member, GetTypeOrExtendedType(writer, property)))
diff --git a/src/DbMetal/Generator/Implementation/CodeTextGenerator/CodeGenerator.cs b/src/DbMetal/Generator/Implementation/CodeTextGenerator/CodeGenerator.cs
index bc3a7e2..206c6fd 100644
--- a/src/DbMetal/Generator/Implementation/CodeTextGenerator/CodeGenerator.cs
+++ b/src/DbMetal/Generator/Implementation/CodeTextGenerator/CodeGenerator.cs
@@ -177,12 +177,12 @@ namespace DbMetal.Generator.Implementation.CodeTextGenerator
implementation.WriteHeader(writer, context);

// write namespaces for members attributes
- foreach (var memberExposedAttribute in context.Parameters.MemberExposedAttributes)
- WriteUsingNamespace(writer, GetNamespace(memberExposedAttribute));
+ foreach (var memberAttribute in context.Parameters.MemberAttributes)
+ WriteUsingNamespace(writer, GetNamespace(memberAttribute));

// write namespaces for clases attributes
- foreach (var entityExposedAttribute in context.Parameters.EntityExposedAttributes)
- WriteUsingNamespace(writer, GetNamespace(entityExposedAttribute));
+ foreach (var entityAttribute in context.Parameters.EntityAttributes)
+ WriteUsingNamespace(writer, GetNamespace(entityAttribute));

writer.WriteLine();
}
diff --git a/src/DbMetal/Generator/Implementation/Processor.cs b/src/DbMetal/Generator/Implementation/Processor.cs
index 5a93e50..2c1ad96 100644
--- a/src/DbMetal/Generator/Implementation/Processor.cs
+++ b/src/DbMetal/Generator/Implementation/Processor.cs
@@ -98,7 +98,7 @@ namespace DbMetal.Generator.Implementation

ProcessSchema(parameters);

- if (parameters.ReadLineAtExit)
+ if (parameters.Readline)
{
// '-readLineAtExit' flag: useful when running from Visual Studio
Console.ReadKey();
diff --git a/src/DbMetal/Parameters.cs b/src/DbMetal/Parameters.cs
index 1b4845e..458d6ac 100644
--- a/src/DbMetal/Parameters.cs
+++ b/src/DbMetal/Parameters.cs
@@ -135,20 +135,18 @@ namespace DbMetal
/// <summary>
/// Extra attributes to be implemented by class
/// </summary>
- public string EntityAttributes { get; set; }
- public string[] EntityExposedAttributes { get { return GetArray(EntityAttributes); } }
+ public IList<string> EntityAttributes { get; set; }

/// <summary>
/// Extra attributes to be implemented by class
/// </summary>
- public string MemberAttributes { get; set; }
- public string[] MemberExposedAttributes { get { return GetArray(MemberAttributes); } }
+ public IList<string> MemberAttributes { get; set; }

/// <summary>
/// base class from which all generated entities will inherit
/// SQLMetal compatible
/// </summary>
- public bool GenerateEqualsAndHash { get; set; }
+ public bool GenerateEqualsHash { get; set; }

/// <summary>
/// export stored procedures
@@ -182,7 +180,7 @@ namespace DbMetal
/// picrap comment: you may use the tool to write output to Visual Studio output window instead of a console window
/// DbLinq specific
/// </summary>
- public bool ReadLineAtExit { get; set; }
+ public bool Readline { get; set; }

/// <summary>
/// specifies a provider (which here is a pair or ISchemaLoader and IDbConnection implementors)
@@ -227,6 +225,8 @@ namespace DbMetal
Schema = true;
Culture = "en";
GenerateTypes = new List<string>();
+ EntityAttributes = new List<string>();
+ MemberAttributes = new List<string>();
GenerateTimestamps = true;
EntityInterfaces = new []{ "INotifyPropertyChanging", "INotifyPropertyChanged" };
}
@@ -266,52 +266,54 @@ namespace DbMetal
{ "provider=",
"Specify {PROVIDER}. May be Ingres, MySql, Oracle, OracleODP, PostgreSql or Sqlite.",
provider => Provider = provider },
- { "dbLinqSchemaLoaderProvider=",
- "Specify a custom ISchemaLoader implementation {TYPE}.",
+ { "schema-loader=",
+ "ISchemaLoader implementation {TYPE}.",
type => DbLinqSchemaLoaderProvider = type },
- { "databaseConnectionProvider=",
- "Specify a custom IDbConnection implementation {TYPE}.",
+ { "dbconnection=",
+ "IDbConnection implementation {TYPE}.",
type => DatabaseConnectionProvider = type },
- { "sqlDialectType=",
- "The IVendor implementation {TYPE}.",
+ { "vendor=",
+ "IVendor implementation {TYPE}.",
type => SqlDialectType = type },
{ "code=",
"Output as source code to {FILE}. Cannot be used with /dbml option.",
file => Code = file },
{ "dbml=",
- "Output as dbml to {FILE}. Cannot be used with /map option.",
+ "Output as dbml to {FILE}.",
file => Dbml = file },
{ "language=",
"Language {NAME} for source code: C#, C#2 or VB "
+"(default: derived from extension on code file name).",
name => Language = name },
- { "aliases|renamesFile=",
+ { "aliases=",
"Use mapping {FILE}.",
file => Aliases = file },
{ "schema",
- "Generate schema in code files (default='true').",
+ "Generate schema in code files (default: enabled).",
(bool v) => Schema = v },
{ "namespace=",
"Namespace {NAME} of generated code (default: no namespace).",
name => Namespace = name },
- { "entityBase=",
+ { "entitybase=",
"Base {TYPE} of entity classes in the generated code "
+"(default: entities have no base class).",
type => EntityBase = type },
- { "entityAttributes=",
- "Comma separated {ATTRIBUTE(S)} of entity classes in the generated code.",
- attributes => EntityAttributes = attributes },
- { "memberAttributes=",
- "Comma separated {ATTRIBUTE(S)} of entity members in the generated code.",
- attributes => MemberAttributes = attributes },
+ { "entity-attribute=",
+ "{ATTRIBUTE} for entity classes in the generated code, "
+ +"can be specified multiple times.",
+ attribute => EntityAttributes.Add(attribute) },
+ { "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) },
- { "generateEqualsAndHash",
+ { "generate-equals-hash",
"Generates overrides for Equals() and GetHashCode() methods.",
- (bool v) => GenerateEqualsAndHash = v },
+ (bool v) => GenerateEqualsHash = v },
{ "sprocs",
"Extract stored procedures.",
(bool v) => Sprocs = v },
@@ -320,18 +322,18 @@ namespace DbMetal
+"using specified culture rules.",
(bool v) => Pluralize = v },
{ "culture=",
- "Specify {CULTURE} for word recognition and pluralization (default=\"en\").",
+ "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. True by default.",
+ "Generate timestampes in the generated code (default: enabled).",
(bool v) => GenerateTimestamps = v },
- { "readlineAtExit",
+ { "readline",
"Wait for a key to be pressed after processing.",
- (bool v) => ReadLineAtExit = v },
+ (bool v) => Readline = v },
{ "h|?|help",
"Show this help",
(bool v) => Help = v }

--
Emanuele Aina
Studio Associato Di Nunzio e Di Gregorio
http://dndg.it/
Via Maria Vittoria, 2
10123 Torino - Italy
0002-Cleanup-of-the-DbMetal-command-line.patch.gz

Jonathan Pryor

unread,
Nov 16, 2009, 5:07:04 PM11/16/09
to dbl...@googlegroups.com
On Mon, 2009-11-16 at 21:57 +0100, Emanuele Aina wrote:
> diff --git a/src/DbMetal/Generator/Implementation/CodeTextGenerator/CodeGenerator.cs b/src/DbMetal/Generator/Implementation/CodeTextGenerator/CodeGenerator.cs
> index bc3a7e2..206c6fd 100644
> --- a/src/DbMetal/Generator/Implementation/CodeTextGenerator/CodeGenerator.cs
> +++ b/src/DbMetal/Generator/Implementation/CodeTextGenerator/CodeGenerator.cs
> @@ -177,12 +177,12 @@ namespace DbMetal.Generator.Implementation.CodeTextGenerator
> implementation.WriteHeader(writer, context);
>
> // write namespaces for members attributes
> - foreach (var memberExposedAttribute in context.Parameters.MemberExposedAttributes)
> - WriteUsingNamespace(writer, GetNamespace(memberExposedAttribute));
> + foreach (var memberAttribute in context.Parameters.MemberAttributes)
> + WriteUsingNamespace(writer, GetNamespace(memberAttribute));

Opinions will vary, but I don't find long-named variables which are in
scope for 1 line to be all that useful. 'a' would work just as well as
'memberAttribute', and (even better) would likely be more resilient to
change.

(You don't need to make this change, I'm just mini-ranting. ;-)

Which brings us to...the actual cleanup:

> diff --git a/src/DbMetal/Parameters.cs b/src/DbMetal/Parameters.cs
> index 1b4845e..458d6ac 100644
> --- a/src/DbMetal/Parameters.cs
> +++ b/src/DbMetal/Parameters.cs
> @@ -266,52 +266,54 @@ namespace DbMetal
> { "provider=",
> "Specify {PROVIDER}. May be Ingres, MySql, Oracle, OracleODP, PostgreSql or Sqlite.",
> provider => Provider = provider },
> - { "dbLinqSchemaLoaderProvider=",
> - "Specify a custom ISchemaLoader implementation {TYPE}.",
> + { "schema-loader=",
> + "ISchemaLoader implementation {TYPE}.",
> type => DbLinqSchemaLoaderProvider = type },

I think some form of convention for parameters which take type names as
values would be useful. I'd consider a 'type' suffix, but we now have
--generate-type, so that doesn't really work.

More importantly, there is another "compatibility" requirement: .NET
SQLMETAL.EXE. Using the same parameter names as .NET gives two things:

1. Makes it easier to use DbMetal (we use the same options!)
2. Makes Mono's sqlmetal easier for me (we use the same options!) ;-)

For DbLinq extensions, this isn't as important, but this does
potentially (unfortunately) impact some of your more recent work. For
example, SQLMETAL has a /entitybase option which, as per recent
discussion, is pointless (entities are partial classes, why would you
ever need this?!), but we need to keep it anyway (and I'm glad to see
that you did).

Returning to the original point ("some form of convention"), I think
that options taking type names as values should start with --with, thus
instead of --schema-loader, we should use --with-schema-loader.

> - { "databaseConnectionProvider=",
> - "Specify a custom IDbConnection implementation {TYPE}.",
> + { "dbconnection=",
> + "IDbConnection implementation {TYPE}.",

Similarly, this should probably be --with-connection or
--with-dbconnection.

> type => DatabaseConnectionProvider = type },
> - { "sqlDialectType=",
> - "The IVendor implementation {TYPE}.",
> + { "vendor=",
> + "IVendor implementation {TYPE}.",

1. As per above, a --with prefix.
2. I hate the 'vendor' terminology, as it doesn't really make sense to
me. There is lots of "cross-pollination" in supported SQL, e.g. SQLite
supports SQL Server-style [...] quoting, plus `...` and "..." (to quote
DB column and table names, etc.), and accepting SQL Server's '@'
parameter prefix. I suspect you can write a fairly decent amount of SQL
queries that's identical between SQLite and SQL Server.

For this reason, I don't like the idea of tying "flavor of SQL" to
"vendor" or manufacturer. I prefer the term "dialect" (and am
considering doing a s/DbLinq.Vendors/DbLinq.Dialects/ in some future
version if insanity takes me).

So I'd prefer --with-sql-dialect.

> type => SqlDialectType = type },
> { "code=",
> "Output as source code to {FILE}. Cannot be used with /dbml option.",
> file => Code = file },
> { "dbml=",
> - "Output as dbml to {FILE}. Cannot be used with /map option.",
> + "Output as dbml to {FILE}.",
> file => Dbml = file },

Have you removed the /map restriction?

> { "language=",
> "Language {NAME} for source code: C#, C#2 or VB "
> +"(default: derived from extension on code file name).",
> name => Language = name },
> - { "aliases|renamesFile=",
> + { "aliases=",

I wonder if this should instead be --map (or have --map as an alias) --
SQLMETAL provides a /map option, and iirc renamesFile was originally
used for /map, so reverting this to /map would likely be best.

> - { "entityBase=",
> + { "entitybase=",
> "Base {TYPE} of entity classes in the generated code "
> +"(default: entities have no base class).",
> type => EntityBase = type },
> - { "entityAttributes=",
> - "Comma separated {ATTRIBUTE(S)} of entity classes in the generated code.",
> - attributes => EntityAttributes = attributes },
> - { "memberAttributes=",
> - "Comma separated {ATTRIBUTE(S)} of entity members in the generated code.",
> - attributes => MemberAttributes = attributes },
> + { "entity-attribute=",
> + "{ATTRIBUTE} for entity classes in the generated code, "
> + +"can be specified multiple times.",
> + attribute => EntityAttributes.Add(attribute) },

But to follow up...is there really a need for --entity-attribute? You
can just place the attributes on a partial class declaration, AND
SQLMETAL doesn't provide this option (no compatibility requirement), so
I don't actually see a need for this anymore.

Thanks for looking into this!

- Jon


Emanuele Aina

unread,
Dec 6, 2009, 10:28:42 AM12/6/09
to dbl...@googlegroups.com
Jonathan Pryor controllò:

> > + foreach (var memberAttribute in context.Parameters.MemberAttributes)
> > + WriteUsingNamespace(writer, GetNamespace(memberAttribute));
>
> Opinions will vary, but I don't find long-named variables which are in
> scope for 1 line to be all that useful. 'a' would work just as well as
> 'memberAttribute', and (even better) would likely be more resilient to
> change.
>
> (You don't need to make this change, I'm just mini-ranting. ;-)

I agree, but I've left it as is or I'd have to change the other loops
near this for consistency.

> I think some form of convention for parameters which take type names as
> values would be useful. I'd consider a 'type' suffix, but we now have
> --generate-type, so that doesn't really work.
>
> More importantly, there is another "compatibility" requirement: .NET
> SQLMETAL.EXE. Using the same parameter names as .NET gives two things:
>
> 1. Makes it easier to use DbMetal (we use the same options!)
> 2. Makes Mono's sqlmetal easier for me (we use the same options!) ;-)
>
> For DbLinq extensions, this isn't as important, but this does
> potentially (unfortunately) impact some of your more recent work. For
> example, SQLMETAL has a /entitybase option which, as per recent
> discussion, is pointless (entities are partial classes, why would you
> ever need this?!), but we need to keep it anyway (and I'm glad to see
> that you did).
>
> Returning to the original point ("some form of convention"), I think
> that options taking type names as values should start with --with, thus
> instead of --schema-loader, we should use --with-schema-loader.

Done.

> > - { "databaseConnectionProvider=",
> > - "Specify a custom IDbConnection implementation {TYPE}.",
> > + { "dbconnection=",
> > + "IDbConnection implementation {TYPE}.",
>
> Similarly, this should probably be --with-connection or
> --with-dbconnection.

Done.

> > type => DatabaseConnectionProvider = type },
> > - { "sqlDialectType=",
> > - "The IVendor implementation {TYPE}.",
> > + { "vendor=",
> > + "IVendor implementation {TYPE}.",
>
> 1. As per above, a --with prefix.
> 2. I hate the 'vendor' terminology, as it doesn't really make sense to
> me. There is lots of "cross-pollination" in supported SQL, e.g. SQLite
> supports SQL Server-style [...] quoting, plus `...` and "..." (to quote
> DB column and table names, etc.), and accepting SQL Server's '@'
> parameter prefix. I suspect you can write a fairly decent amount of SQL
> queries that's identical between SQLite and SQL Server.
>
> For this reason, I don't like the idea of tying "flavor of SQL" to
> "vendor" or manufacturer. I prefer the term "dialect" (and am
> considering doing a s/DbLinq.Vendors/DbLinq.Dialects/ in some future
> version if insanity takes me).
>
> So I'd prefer --with-sql-dialect.

Done.

> > { "dbml=",
> > - "Output as dbml to {FILE}. Cannot be used with /map option.",
> > + "Output as dbml to {FILE}.",
> > file => Dbml = file },
>
> Have you removed the /map restriction?

No, but we do not have a /map option... :)

> > { "language=",
> > "Language {NAME} for source code: C#, C#2 or VB "
> > +"(default: derived from extension on code file name).",
> > name => Language = name },
> > - { "aliases|renamesFile=",
> > + { "aliases=",
>
> I wonder if this should instead be --map (or have --map as an alias) --
> SQLMETAL provides a /map option, and iirc renamesFile was originally
> used for /map, so reverting this to /map would likely be best.

It seems that -aliases is used to read the file with the mapping, while
the SQLMetal -map does the opposite, it writes an XML file..

> > + { "entity-attribute=",
> > + "{ATTRIBUTE} for entity classes in the generated code, "
> > + +"can be specified multiple times.",
> > + attribute => EntityAttributes.Add(attribute) },
>
> But to follow up...is there really a need for --entity-attribute? You
> can just place the attributes on a partial class declaration, AND
> SQLMETAL doesn't provide this option (no compatibility requirement), so
> I don't actually see a need for this anymore.

Removed.

> Thanks for looking into this!

Sorry for the delay.

I've also done some small adjustments to comments and unused code.

Reworked gzipped patch attached.
0001-Cleanup-of-the-DbMetal-command-line.patch.gz

Jonathan Pryor

unread,
Dec 8, 2009, 4:43:40 PM12/8/09
to dbl...@googlegroups.com
On Sun, 2009-12-06 at 16:28 +0100, Emanuele Aina wrote:
> diff --git a/src/DbMetal/Generator/Implementation/Processor.cs b/src/DbMetal/Generator/Implementation/Processor.cs
> index 5a93e50..2c1ad96 100644
> --- a/src/DbMetal/Generator/Implementation/Processor.cs
> +++ b/src/DbMetal/Generator/Implementation/Processor.cs
> @@ -98,7 +98,7 @@ namespace DbMetal.Generator.Implementation
>
> ProcessSchema(parameters);
>
> - if (parameters.ReadLineAtExit)
> + if (parameters.Readline)

This makes me ponder the wisdom of renaming these members, as the patch
has effectively two mostly unrelated changes: DbMetal option cleanup,
and renaming Parameters members. Does renaming ReadLineAtExit actually
buy anything? (Ditto for GenerateEqualsHash.)

Just pondering out loud here; don't change them, but it does increase
the patch size for no significant reason...

> diff --git a/src/DbMetal/Parameters.cs b/src/DbMetal/Parameters.cs
> index 9d6eb21..7aae58b 100644
> --- a/src/DbMetal/Parameters.cs
> +++ b/src/DbMetal/Parameters.cs
> @@ -227,111 +205,109 @@ namespace DbMetal
...
> { "schema",
> - "Generate schema in code files (default='true').",
> - v => Schema = v != null},
> + "Generate schema in code files (default: enabled).",
> + (bool v) => Schema = v },

Don't do this (see also the commit message for r1280).

At least until Mono.Options is fixed to treat boolean options in a more
consistent manner, you should always compare the value against null and
not use (bool v) (unless you actually want the user to write
'-schema=True' instead of '-schema').

> - { "generateEqualsAndHash",
> + { "generate-equals-hash",
> "Generates overrides for Equals() and GetHashCode() methods.",
> - v => GenerateEqualsAndHash = v != null},
> + (bool v) => GenerateEqualsHash = v },

Same issue: don't do this.

> { "generate-timestamps",
> - "Generate timestampes in the generated code. True by default.",
> - v => GenerateTimestamps = v != null },
> - { "readlineAtExit",
> + "Generate timestampes in the generated code (default: enabled).",
> + (bool v) => GenerateTimestamps = v },
> + { "readline",
> "Wait for a key to be pressed after processing.",
> - v => ReadLineAtExit = v != null },
> + (bool v) => Readline = v },

Same here.

Also, I would strongly suggest that you run the DbMetal unit tests, as
if you had done so you would have seen that the DbMetal_test_sqlite
tests would have failed (or should have, anyway) as they use some
DbMetal boolean command-line options which would fail when using (bool
v) parameters; see src/DbMetal/Test/CreateEntitiesFromSqliteDbTest.cs:

s.Run(new string[]{
"/code:Northwind.Sqlite.cs",
"/conn:Data Source=" + Path.Combine(testdir, "Northwind.db3"),
"/database:Northwind",
"--generate-timestamps-",
"/namespace:nwind",
"/pluralize",
"/provider:Sqlite",
});

I realize that not everyone will run the SQL Server tests, but I don't
see much reason not to run the SQLite tests... (Though, come to think
of it, I think those rely on System.Data.SQLite.dll, not
Mono.Data.Sqlite, meaning they won't run under Mono. I should fix
that...)

- Jon


Emanuele Aina

unread,
Jan 5, 2010, 3:08:15 PM1/5/10
to dbl...@googlegroups.com
Jonathan Pryor controllò:

> > - if (parameters.ReadLineAtExit)
> > + if (parameters.Readline)
>
> This makes me ponder the wisdom of renaming these members, as the patch
> has effectively two mostly unrelated changes: DbMetal option cleanup,
> and renaming Parameters members. Does renaming ReadLineAtExit actually
> buy anything? (Ditto for GenerateEqualsHash.)
>
> Just pondering out loud here; don't change them, but it does increase
> the patch size for no significant reason...

I did it for consistency, as they map the command line options.

Increasing the patch size instead of splitting the changes in two
patches seemed a good tradeoff, but it is very subjective.

> > { "schema",
> > - "Generate schema in code files (default='true').",
> > - v => Schema = v != null},
> > + "Generate schema in code files (default: enabled).",
> > + (bool v) => Schema = v },
>
> Don't do this (see also the commit message for r1280).
>
> At least until Mono.Options is fixed to treat boolean options in a more
> consistent manner, you should always compare the value against null and
> not use (bool v) (unless you actually want the user to write
> '-schema=True' instead of '-schema').

Oops, done. Unfortunately I tested only the boolean options which are
enabled by default... :/

> Also, I would strongly suggest that you run the DbMetal unit tests, as
> if you had done so you would have seen that the DbMetal_test_sqlite
> tests would have failed (or should have, anyway) as they use some
> DbMetal boolean command-line options which would fail when using (bool
> v) parameters; see src/DbMetal/Test/CreateEntitiesFromSqliteDbTest.cs:
>
> s.Run(new string[]{
> "/code:Northwind.Sqlite.cs",
> "/conn:Data Source=" + Path.Combine(testdir, "Northwind.db3"),
> "/database:Northwind",
> "--generate-timestamps-",
> "/namespace:nwind",
> "/pluralize",
> "/provider:Sqlite",
> });
>
> I realize that not everyone will run the SQL Server tests, but I don't
> see much reason not to run the SQLite tests... (Though, come to think
> of it, I think those rely on System.Data.SQLite.dll, not
> Mono.Data.Sqlite, meaning they won't run under Mono. I should fix
> that...)

Sorry for that and for the delay of the reply.

Reworked gzipped patch attached.

diff --git a/src/DbMetal/Generator/Implementation/CodeTextGenerator/CodeGenerator.Class.cs b/src/DbMetal/Generator/Implementation/CodeTextGenerator/CodeGenerator.Class.cs
index 345129a..ba954ac 100644
--- a/src/DbMetal/Generator/Implementation/CodeTextGenerator/CodeGenerator.Class.cs
+++ b/src/DbMetal/Generator/Implementation/CodeTextGenerator/CodeGenerator.Class.cs
@@ -76,8 +76,6 @@ namespace DbMetal.Generator.Implementation.CodeTextGenerator



var tableAttribute = NewAttributeDefinition<TableAttribute>();
tableAttribute["Name"] = table.Name;

- //using (WriteAttributes(writer, context.Parameters.EntityExposedAttributes))


- using (WriteAttributes(writer, GetAttributeNames(context, context.Parameters.EntityExposedAttributes)))

using (writer.WriteAttribute(tableAttribute))
using (writer.WriteClass(specifications,
table.Type.Name, entityBase, context.Parameters.EntityInterfaces))

@@ -86,7 +84,7 @@ namespace DbMetal.Generator.Implementation.CodeTextGenerator


WriteCustomTypes(writer, table, schema, context);
WriteClassExtensibilityDeclarations(writer, table, context);
WriteClassProperties(writer, table, context);
- if (context.Parameters.GenerateEqualsAndHash)
+ if (context.Parameters.GenerateEqualsHash)
WriteClassEqualsAndHash(writer, table, context);
WriteClassChildren(writer, table, schema, context);
WriteClassParents(writer, table, schema, context);

@@ -269,7 +267,7 @@ namespace DbMetal.Generator.Implementation.CodeTextGenerator


/// <param name="context"></param>
/// <param name="attributes"></param>
/// <returns></returns>
- protected virtual string[] GetAttributeNames(GenerationContext context, string[] attributes)
+ protected virtual string[] GetAttributeNames(GenerationContext context, IEnumerable<string> attributes)
{
return (from a in attributes select GetName(a)).ToArray();
}

@@ -325,7 +323,7 @@ namespace DbMetal.Generator.Implementation.CodeTextGenerator


specifications |= GetSpecificationDefinition(property.Modifier);

//using (WriteAttributes(writer, context.Parameters.MemberExposedAttributes))
- using (WriteAttributes(writer, GetAttributeNames(context, context.Parameters.MemberExposedAttributes)))
+ using (WriteAttributes(writer, GetAttributeNames(context, context.Parameters.MemberAttributes)))
using (writer.WriteAttribute(NewAttributeDefinition<DebuggerNonUserCodeAttribute>()))
using (writer.WriteAttribute(column))
using (writer.WriteProperty(specifications, property.Member, GetTypeOrExtendedType(writer, property)))

diff --git a/src/DbMetal/Generator/Implementation/CodeTextGenerator/CodeGenerator.cs b/src/DbMetal/Generator/Implementation/CodeTextGenerator/CodeGenerator.cs
index bc3a7e2..bf73e1a 100644
--- a/src/DbMetal/Generator/Implementation/CodeTextGenerator/CodeGenerator.cs
+++ b/src/DbMetal/Generator/Implementation/CodeTextGenerator/CodeGenerator.cs
@@ -177,12 +177,8 @@ namespace DbMetal.Generator.Implementation.CodeTextGenerator


implementation.WriteHeader(writer, context);

// write namespaces for members attributes
- foreach (var memberExposedAttribute in context.Parameters.MemberExposedAttributes)
- WriteUsingNamespace(writer, GetNamespace(memberExposedAttribute));

-
- // write namespaces for clases attributes


- foreach (var entityExposedAttribute in context.Parameters.EntityExposedAttributes)
- WriteUsingNamespace(writer, GetNamespace(entityExposedAttribute));

+ foreach (var memberAttribute in context.Parameters.MemberAttributes)
+ WriteUsingNamespace(writer, GetNamespace(memberAttribute));

writer.WriteLine();
}
diff --git a/src/DbMetal/Generator/Implementation/Processor.cs b/src/DbMetal/Generator/Implementation/Processor.cs
index 5a93e50..bc94475 100644
--- a/src/DbMetal/Generator/Implementation/Processor.cs
+++ b/src/DbMetal/Generator/Implementation/Processor.cs
@@ -72,37 +72,31 @@ namespace DbMetal.Generator.Implementation
{
var parameters = new Parameters { Log = Log };

- if (args.Length == 0)
- PrintUsage(parameters);
+ parameters.WriteHeader();

- else
+ try
{
- parameters.WriteHeader();
-
- try
- {
- parameters.Parse(args);
- }
- catch (Exception e)
- {
- Output.WriteErrorLine(Log, e.Message);
- PrintUsage(parameters);
- return;
- }
+ parameters.Parse(args);
+ }
+ catch (Exception e)
+ {
+ Output.WriteErrorLine(Log, e.Message);
+ PrintUsage(parameters);
+ return;
+ }

- if (parameters.Help)
- {
- PrintUsage(parameters);
- return;
- }
+ if (args.Length == 0 || parameters.Help)
+ {
+ PrintUsage(parameters);
+ return;
+ }

- ProcessSchema(parameters);
+ ProcessSchema(parameters);

- if (parameters.ReadLineAtExit)
- {
- // '-readLineAtExit' flag: useful when running from Visual Studio
- Console.ReadKey();
- }
+ if (parameters.Readline)
+ {
+ // '-readLineAtExit' flag: useful when running from Visual Studio
+ Console.ReadKey();
}
}

diff --git a/src/DbMetal/Parameters.cs b/src/DbMetal/Parameters.cs
index 9d6eb21..72d2f4a 100644
--- a/src/DbMetal/Parameters.cs
+++ b/src/DbMetal/Parameters.cs
@@ -41,70 +41,62 @@ namespace DbMetal
{
/// <summary>
/// user name for database access
- /// SQLMetal compatible
/// </summary>
public string User { get; set; }

/// <summary>
/// user password for database access
- /// SQLMetal compatible
/// </summary>
public string Password { get; set; }

/// <summary>
/// server host name
- /// SQLMetal compatible
/// </summary>
public string Server { get; set; }

/// <summary>
/// database name
- /// SQLMetal compatible
/// </summary>
public string Database { get; set; }

/// <summary>
/// This connection string if present overrides User, Password, Server.
/// Database is always used to generate the specific DataContext name
- /// SQLMetal compatible
/// </summary>
public string Conn { get; set; }

/// <summary>
/// the namespace to put our classes into
- /// SQLMetal compatible
/// </summary>
public string Namespace { get; set; }

/// <summary>
/// the language to generate classes for
- /// SQLMetal compatible
/// </summary>
public string Language { get; set; }

/// <summary>
/// If present, write out C# code
- /// SQLMetal compatible
/// </summary>
public string Code { get; set; }

/// <summary>
- /// If present, write out DBML XML representing the DB
- /// SQLMetal compatible
+ /// if present, write out DBML XML representing the DB
/// </summary>
public string Dbml { get; set; }

/// <summary>
/// when true, we will call Singularize()/Pluralize() functions.
- /// SQLMetal compatible
/// </summary>
public bool Pluralize { get; set; }

+ /// <summary>
+ /// the culture used for word recognition and pluralization
+ /// </summary>
public string Culture { get; set; }

/// <summary>
- /// Load object renamings from an xml file
- /// DbLinq specific
+ /// load object renamings from an xml file
/// </summary>
public string Aliases { get; set; }

@@ -123,93 +115,79 @@ namespace DbMetal

/// <summary>


/// base class from which all generated entities will inherit

- /// SQLMetal compatible
/// </summary>
public string EntityBase { get; set; }

/// <summary>
- /// Interfaces to be implemented
+ /// interfaces to be implemented
/// </summary>
public string[] EntityInterfaces { get; set; }

/// <summary>
- /// Extra attributes to be implemented by class
+ /// extra attributes to be implemented by class members


/// </summary>
- public string EntityAttributes { get; set; }
- public string[] EntityExposedAttributes { get { return GetArray(EntityAttributes); } }

+ public IList<string> MemberAttributes { get; set; }

/// <summary>

- /// Extra attributes to be implemented by class
+ /// generate Equals() and GetHashCode()


/// </summary>
- public string MemberAttributes { get; set; }
- public string[] MemberExposedAttributes { get { return GetArray(MemberAttributes); } }

-
- /// <summary>
- /// base class from which all generated entities will inherit
- /// SQLMetal compatible
- /// </summary>


- public bool GenerateEqualsAndHash { get; set; }
+ public bool GenerateEqualsHash { get; set; }

/// <summary>
/// export stored procedures

- /// SQLMetal compatible
/// </summary>
public bool Sprocs { get; set; }

/// <summary>
/// preserve case of database names
- /// DbLinq specific
/// </summary>
public string Case { get; set; }

- bool useDomainTypes = true;
-
- /// <summary>
- /// if true, and PostgreSql database contains DOMAINS (typedefs),
- /// we will generate code DbType='DerivedType'.
- /// if false, generate code DbType='BaseType'.
- /// DbLinq specific
- /// </summary>
- public bool UseDomainTypes
- {
- get { return useDomainTypes; }
- set { useDomainTypes = value; }
- }
-
/// <summary>
/// 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

- /// DbLinq specific


/// </summary>
- public bool ReadLineAtExit { get; set; }
+ public bool Readline { get; set; }

/// <summary>
/// specifies a provider (which here is a pair or ISchemaLoader and IDbConnection implementors)

- /// SQLMetal compatible
/// </summary>
public string Provider { get; set; }

/// <summary>
- /// For fine tuning, we allow to specifiy an ISchemaLoader
- /// DbLinq specific
+ /// for fine tuning, we allow to specifiy an ISchemaLoader
/// </summary>
public string DbLinqSchemaLoaderProvider { get; set; }

/// <summary>
- /// For fine tuning, we allow to specifiy an IDbConnection
- /// DbLinq specific
+ /// for fine tuning, we allow to specifiy an IDbConnection
/// </summary>
public string DatabaseConnectionProvider { get; set; }

+ /// <summary>
+ /// the SQL dialect used by the database
+ /// </summary>
public string SqlDialectType { get; set; }

+ /// <summary>
+ /// the types to be generated
+ /// </summary>
public IList<string> GenerateTypes { get; set; }

+ /// <summary>
+ /// if true, put a timestamp comment before the generated code
+ /// </summary>
public bool GenerateTimestamps { get; set; }

+ /// <summary>
+ /// show help
+ /// </summary>
public bool Help { get; set; }

+ /// <summary>
+ /// non-option parameters
+ /// </summary>
public IList<string> Extra = new List<string>();

TextWriter log;


@@ -227,111 +205,109 @@ namespace DbMetal

Schema = true;
Culture = "en";
GenerateTypes = new List<string>();

+ MemberAttributes = new List<string>();
GenerateTimestamps = true;
EntityInterfaces = new []{ "INotifyPropertyChanging", "INotifyPropertyChanged" };
}

- /// <summary>
- /// Converts a list separated by a comma to a string array
- /// </summary>
- /// <param name="list"></param>
- /// <returns></returns>
- public string[] GetArray(string list)
- {
- if (string.IsNullOrEmpty(list))
- return new string[0];
- return (from entityInterface in list.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
- select entityInterface.Trim()).ToArray();
- }
-
public void Parse(IList<string> 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 },

- { "dbLinqSchemaLoaderProvider=",
- "Specify a custom ISchemaLoader implementation {TYPE}.",
+ { "with-schema-loader=",


+ "ISchemaLoader implementation {TYPE}.",
type => DbLinqSchemaLoaderProvider = type },

- { "databaseConnectionProvider=",
- "Specify a custom IDbConnection implementation {TYPE}.",

+ { "with-dbconnection=",


+ "IDbConnection implementation {TYPE}.",

type => DatabaseConnectionProvider = type },
- { "sqlDialectType=",
- "The IVendor implementation {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|renamesFile=",
+ { "aliases=",

"Use mapping {FILE}.",
file => Aliases = file },


{ "schema",
- "Generate schema in code files (default='true').",
- v => Schema = v != null},
+ "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 },
- { "entityBase=",

+ // SQLMetal compatible


+ { "entitybase=",
"Base {TYPE} of entity classes in the generated code "
+"(default: entities have no base class).",
type => EntityBase = type },
- { "entityAttributes=",
- "Comma separated {ATTRIBUTE(S)} of entity classes in the generated code.",
- attributes => EntityAttributes = attributes },
- { "memberAttributes=",
- "Comma separated {ATTRIBUTE(S)} of entity members in the generated code.",
- attributes => MemberAttributes = attributes },

+ { "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) },

- { "generateEqualsAndHash",
+ { "generate-equals-hash",
"Generates overrides for Equals() and GetHashCode() methods.",
- v => GenerateEqualsAndHash = v != null},

+ 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\").",
+ "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. True by default.",

+ "Generate timestampes in the generated code (default: enabled).",
v => GenerateTimestamps = v != null },
- { "readlineAtExit",

+ { "readline",
"Wait for a key to be pressed after processing.",
- v => ReadLineAtExit = v != null },

+ v => Readline = v != null },


{ "h|?|help",
"Show this help",

v => Help = v != null }

0001-Cleanup-of-the-DbMetal-command-line.patch.gz

Jonathan Pryor

unread,
Jan 7, 2010, 5:14:36 PM1/7/10
to dbl...@googlegroups.com
Please commit.

- Jon

Emanuele Aina

unread,
Jan 8, 2010, 3:34:57 AM1/8/10
to dbl...@googlegroups.com
Jonathan Pryor avallò:

> Please commit.

Done: r1297

--
Emanuele Aina


Studio Associato Di Nunzio e Di Gregorio

stu...@dndg.it
http://dndg.it

Reply all
Reply to author
Forward
0 new messages