[PATCH] Add a /noDataContext to the DbMetal program

4 views
Skip to first unread message

Emanuele Aina

unread,
Oct 26, 2009, 10:24:54 AM10/26/09
to DbLinq
This patch that adds a /noDataContext option to the DbMetal program to
avoid the generation of the specialized DataContext subclass.

Here is the diff for comments, but I've also attached the gzipped patch:
hopefully it will apply cleanly on r1244.

---
.../CodeTextGenerator/CodeGenerator.cs | 4 +++-
src/DbMetal/Parameters.cs | 7 +++++++
2 files changed, 10 insertions(+), 1 deletions(-)

diff --git a/src/DbMetal/Generator/Implementation/CodeTextGenerator/CodeGenerator.cs b/src/DbMetal/Generator/Implementation/CodeTextGenerator/CodeGenerator.cs
index 77a6fee..041d238 100644
--- a/src/DbMetal/Generator/Implementation/CodeTextGenerator/CodeGenerator.cs
+++ b/src/DbMetal/Generator/Implementation/CodeTextGenerator/CodeGenerator.cs
@@ -95,7 +95,9 @@ namespace DbMetal.Generator.Implementation.CodeTextGenerator
{
using (WriteNamespace(codeWriter, contextNamespace))
{
- WriteDataContext(codeWriter, dbSchema, context);
+ if (!context.Parameters.NoDataContext) {
+ WriteDataContext(codeWriter, dbSchema, context);
+ }
WriteClasses(codeWriter, dbSchema, context);
}
}
diff --git a/src/DbMetal/Parameters.cs b/src/DbMetal/Parameters.cs
index 0391667..e38badc 100644
--- a/src/DbMetal/Parameters.cs
+++ b/src/DbMetal/Parameters.cs
@@ -215,6 +215,13 @@ namespace DbMetal
public bool ReadLineAtExit { get; set; }

/// <summary>
+ /// avoid generating the DataContext subclass with specialized table accessors
+ /// DbLinq specific
+ /// </summary>
+ [Option("Do not generate the specialized DataContext subclass.", Group = 4)]
+ public bool NoDataContext { get; set; }
+
+ /// <summary>
/// specifies a provider (which here is a pair or ISchemaLoader and IDbConnection implementors)
/// SQLMetal compatible
/// </summary>
--


--
Buongiorno.
Complimenti per l'ottima scelta.

0001-Add-a-noDataContext-to-the-DbMetal-program.patch.gz

Jonathan Pryor

unread,
Oct 26, 2009, 4:15:22 PM10/26/09
to dbl...@googlegroups.com
Silly question, but why wouldn't we want to generate the specialized
DataContext subclass?

Thanks,
- Jon

Federico Di Gregorio

unread,
Oct 26, 2009, 4:33:18 PM10/26/09
to dbl...@googlegroups.com
Il giorno lun, 26/10/2009 alle 16.15 -0400, Jonathan Pryor ha scritto:
> Silly question, but why wouldn't we want to generate the specialized
> DataContext subclass?

Hi,

I can explain that. We have a framework were we generate the code in
separate files and if every file contains a copy of the DataContext
subclass we end with multiple copies of the same code.

Now, why generate code in separate files? We have several reasons:

1) better output from SCM history and diffs
2) 1-to-1 mapping to other generated files (we also generate XML
forms, proxy code and so on)
3) even if we have only 1 PostgreSQL database we like to place the
generated classes in different namespaces because some tables are
generic and part of a framework while others are specific to the
application

We can just keep our own version of DbMetal but if the changes don't
break anything and are generic enough to be useful, why not upstream?

federico

--
Federico Di Gregorio http://people.initd.org/fog
Debian GNU/Linux Developer f...@debian.org
INIT.D Developer f...@initd.org
E tu usa il prefisso corretto Re: non R:, questa è una ML seria.
-- cosmos, su debian-italian

Jonathan Pryor

unread,
Oct 26, 2009, 9:02:22 PM10/26/09
to dbl...@googlegroups.com
On Mon, 2009-10-26 at 21:33 +0100, Federico Di Gregorio wrote:
> Il giorno lun, 26/10/2009 alle 16.15 -0400, Jonathan Pryor ha scritto:
> > Silly question, but why wouldn't we want to generate the specialized
> > DataContext subclass?
>
> I can explain that. We have a framework were we generate the code in
> separate files and if every file contains a copy of the DataContext
> subclass we end with multiple copies of the same code.

Ah.

Well then, unify the two patches. :-)

Specifically, the specialized database generation logic should also use
the EntityInterfaces type (which should likely be simplified to -type or
something). That way a single option controls what types are generated,
and by implication will control whether the specialized DataContext is
generated (or not, again, based on the type's name).

This would be straightforward and easily documentable (I hope).

- Jon


Emanuele Aina

unread,
Nov 14, 2009, 1:47:19 PM11/14/09
to dbl...@googlegroups.com
Jonathan Pryor precisò:

> Specifically, the specialized database generation logic should also use
> the EntityInterfaces type (which should likely be simplified to -type or
> something). That way a single option controls what types are generated,
> and by implication will control whether the specialized DataContext is
> generated (or not, again, based on the type's name).
>
> This would be straightforward and easily documentable (I hope).

I'll rework my patches such that instead of separated
--generate-datacontext and --entity options a single --type option will
do, but it's not clear to me how it should also replace
--entityInterfaces.

Also, we'd like that --type does not prevent references from being
generated, such that (for example) if Order refers to the Customer table
(which is not being generated in the current run) the reference
Order.Customer will be available nonetheless.

Otherwise we can investigate a more explicit approach with a
--separate-files (or whatever you prefer) option.

--
Emanuele Aina
Studio Associato Di Nunzio e Di Gregorio
http://dndg.it/
Via Maria Vittoria, 2
10123 Torino - Italy

Emanuele Aina

unread,
Nov 14, 2009, 2:12:21 PM11/14/09
to dbl...@googlegroups.com
> I'll rework my patches such that instead of separated
> --generate-datacontext and --entity options a single --type option will
> do, but it's not clear to me how it should also replace
> --entityInterfaces.

Here it is:

---
.../CodeTextGenerator/CodeGenerator.Class.cs | 8 +++++++-
.../CodeTextGenerator/CodeGenerator.cs | 13 ++++++++++---
src/DbMetal/Parameters.cs | 8 ++++++++
3 files changed, 25 insertions(+), 4 deletions(-)

diff --git a/src/DbMetal/Generator/Implementation/CodeTextGenerator/CodeGenerator.Class.cs b/src/DbMetal/Generator/Implementation/CodeTextGenerator/CodeGenerator.Class.cs
index 2afdb7a..9daf975 100644
--- a/src/DbMetal/Generator/Implementation/CodeTextGenerator/CodeGenerator.Class.cs
+++ b/src/DbMetal/Generator/Implementation/CodeTextGenerator/CodeGenerator.Class.cs
@@ -48,7 +48,13 @@ namespace DbMetal.Generator.Implementation.CodeTextGenerator
{
protected virtual void WriteClasses(CodeWriter writer, Database schema, GenerationContext context)
{
- foreach (var table in schema.Tables)
+ IEnumerable<Table> tables = schema.Tables;
+
+ var types = context.Parameters.Types;
+ if (types.Count > 0)
+ tables = tables.Where(t => types.Contains(t.Type.Name));
+
+ foreach (var table in tables)
WriteClass(writer, table, schema, context);
}

diff --git a/src/DbMetal/Generator/Implementation/CodeTextGenerator/CodeGenerator.cs b/src/DbMetal/Generator/Implementation/CodeTextGenerator/CodeGenerator.cs
index ed35680..3429406 100644
--- a/src/DbMetal/Generator/Implementation/CodeTextGenerator/CodeGenerator.cs
+++ b/src/DbMetal/Generator/Implementation/CodeTextGenerator/CodeGenerator.cs
@@ -93,18 +93,25 @@ namespace DbMetal.Generator.Implementation.CodeTextGenerator
if (string.IsNullOrEmpty(entityNamespace))
entityNamespace = dbSchema.EntityNamespace;

+ bool generateDataContext = true;
+ var types = context.Parameters.Types;
+ if (types.Count > 0)
+ generateDataContext = types.Contains(dbSchema.Class);
+
if (contextNamespace == entityNamespace)
{
using (WriteNamespace(codeWriter, contextNamespace))
{
- WriteDataContext(codeWriter, dbSchema, context);
+ if (generateDataContext)
+ WriteDataContext(codeWriter, dbSchema, context);
WriteClasses(codeWriter, dbSchema, context);
}
}
else
{
- using (WriteNamespace(codeWriter, contextNamespace))
- WriteDataContext(codeWriter, dbSchema, context);
+ if (generateDataContext)
+ using (WriteNamespace(codeWriter, contextNamespace))
+ WriteDataContext(codeWriter, dbSchema, context);
using (WriteNamespace(codeWriter, entityNamespace))
WriteClasses(codeWriter, dbSchema, context);
}
diff --git a/src/DbMetal/Parameters.cs b/src/DbMetal/Parameters.cs
index a5ede79..a74ecfd 100644
--- a/src/DbMetal/Parameters.cs
+++ b/src/DbMetal/Parameters.cs
@@ -204,6 +204,8 @@ namespace DbMetal
public string DatabaseConnectionProvider { get; set; }

public string SqlDialectType { get; set; }
+
+ public IList<string> Types { get; set; }

public bool GenerateTimestamps { get; set; }

@@ -225,6 +227,7 @@ namespace DbMetal
{
Schema = true;
Culture = "en";
+ Types = new List<string>();
GenerateTimestamps = true;
EntityInterfaces = "INotifyPropertyChanging,INotifyPropertyChanged";//INotifyPropertyChanging INotifyPropertyChanged IModified
}
@@ -306,6 +309,11 @@ namespace DbMetal
{ "memberAttributes=",
"Comma separated {ATTRIBUTE(S)} of entity members in the generated code.",
attributes => MemberAttributes = attributes },
+ { "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 => Types.Add(type) },
{ "generateEqualsAndHash",
"Generates overrides for Equals() and GetHashCode() methods.",
(bool v) => GenerateEqualsAndHash = v },
--
0001-Add-the-type-option-to-DbMetal.patch.gz

Jonathan Pryor

unread,
Nov 15, 2009, 8:42:18 AM11/15/09
to dbl...@googlegroups.com
On Sat, 2009-11-14 at 19:47 +0100, Emanuele Aina wrote:
> I'll rework my patches such that instead of separated
> --generate-datacontext and --entity options a single --type option will
> do, but it's not clear to me how it should also replace
> --entityInterfaces.

Evidently I wasn't thinking properly, as obviously those refer to two
distinct concepts and thus should be separate options.

That said, --type isn't very clear; perhaps --output-type or
--generate-type would be better?

I do wonder why we have/need --entityInterfaces, though -- what's the
use case for wanting e.g. INotifyPropertyChanged but not
INotifyPropertyChanging? Or is it to prevent generating the IModified
interface? (By the way, I see an IModifiedImplementation type in
DbMetal, but not an IModified interface. I also don't see an IModified
interface in Mono, so I'm not even sure what this looks like...)

So to a certain extent, I'm inclined to just remove --entityInterfaces
and just always generate the appropriate interfaces (both
INotifyPropertyChanged and INotifyPropertyChanging, as L2SQL does).

> Also, we'd like that --type does not prevent references from being
> generated, such that (for example) if Order refers to the Customer table
> (which is not being generated in the current run) the reference
> Order.Customer will be available nonetheless.

This makes perfect sense, and I'm not sure any other way would make
sense.

Thanks,
- Jon


Emanuele Aina

unread,
Nov 15, 2009, 11:31:34 AM11/15/09
to dbl...@googlegroups.com
Jonathan Pryor ripensò:

> That said, --type isn't very clear; perhaps --output-type or
> --generate-type would be better?

"--generate-type" seems the most sensible.

> I do wonder why we have/need --entityInterfaces, though -- what's the
> use case for wanting e.g. INotifyPropertyChanged but not
> INotifyPropertyChanging? Or is it to prevent generating the IModified
> interface? (By the way, I see an IModifiedImplementation type in
> DbMetal, but not an IModified interface. I also don't see an IModified
> interface in Mono, so I'm not even sure what this looks like...)

It could be useful to add custom interfaces but, given that the
generated classes are partial, one could add those in a partial
declaration in his code.

> So to a certain extent, I'm inclined to just remove --entityInterfaces
> and just always generate the appropriate interfaces (both
> INotifyPropertyChanged and INotifyPropertyChanging, as L2SQL does).

I agree.

Do you prefer breaking the command-line interface after 0.19 or should I
start sending patches?

Jonathan Pryor

unread,
Nov 15, 2009, 9:25:51 PM11/15/09
to dbl...@googlegroups.com, dbl...@googlegroups.com
On Nov 15, 2009, at 11:31 AM, Emanuele Aina <e...@nerd.ocracy.org> wrote:
> Jonathan Pryor ripensò:
...
> It could be useful to add custom interfaces but, given that the
> generated classes are partial, one could add those in a partial
> declaration in his code.

Exactly. So it looks like a feature without a purpose. Kill it.

>> So to a certain extent, I'm inclined to just remove --
>> entityInterfaces
>> and just always generate the appropriate interfaces (both
>> INotifyPropertyChanged and INotifyPropertyChanging, as L2SQL does).
>
> I agree.
>
> Do you prefer breaking the command-line interface after 0.19 or
> should I
> start sending patches?

Please send patches. :-)

- Jon

Emanuele Aina

unread,
Nov 16, 2009, 3:37:13 PM11/16/09
to dbl...@googlegroups.com
> > That said, --type isn't very clear; perhaps --output-type or
> > --generate-type would be better?
>
> "--generate-type" seems the most sensible.

Committed as r1276.

Emanuele Aina

unread,
Nov 16, 2009, 3:51:51 PM11/16/09
to dbl...@googlegroups.com
Jonathan Pryor condannò:

> Exactly. So it looks like a feature without a purpose. Kill it.

Gzipped patch attached.

---
src/DbMetal/Generator/GenerationContext.cs | 2 +-
.../CodeTextGenerator/CodeGenerator.Class.cs | 2 +-
src/DbMetal/Parameters.cs | 9 ++-------
3 files changed, 4 insertions(+), 9 deletions(-)

diff --git a/src/DbMetal/Generator/GenerationContext.cs b/src/DbMetal/Generator/GenerationContext.cs
index 90d24c5..7a4c545 100644
--- a/src/DbMetal/Generator/GenerationContext.cs
+++ b/src/DbMetal/Generator/GenerationContext.cs
@@ -98,7 +98,7 @@ namespace DbMetal.Generator
{
foreach (IImplementation implementation in AllImplementations)
{
- if (Array.Exists(Parameters.EntityImplementedInterfaces, interfaceName => implementation.InterfaceName == interfaceName))
+ if (Array.Exists(Parameters.EntityInterfaces, interfaceName => implementation.InterfaceName == interfaceName))
yield return implementation;
}
}
diff --git a/src/DbMetal/Generator/Implementation/CodeTextGenerator/CodeGenerator.Class.cs b/src/DbMetal/Generator/Implementation/CodeTextGenerator/CodeGenerator.Class.cs
index a822130..f09a35c 100644
--- a/src/DbMetal/Generator/Implementation/CodeTextGenerator/CodeGenerator.Class.cs
+++ b/src/DbMetal/Generator/Implementation/CodeTextGenerator/CodeGenerator.Class.cs
@@ -80,7 +80,7 @@ namespace DbMetal.Generator.Implementation.CodeTextGenerator
using (WriteAttributes(writer, GetAttributeNames(context, context.Parameters.EntityExposedAttributes)))
using (writer.WriteAttribute(tableAttribute))
using (writer.WriteClass(specifications,
- table.Type.Name, entityBase, context.Parameters.EntityImplementedInterfaces))
+ table.Type.Name, entityBase, context.Parameters.EntityInterfaces))
{
WriteClassHeader(writer, table, context);
WriteCustomTypes(writer, table, schema, context);
diff --git a/src/DbMetal/Parameters.cs b/src/DbMetal/Parameters.cs
index d5d9dc0..1b4845e 100644
--- a/src/DbMetal/Parameters.cs
+++ b/src/DbMetal/Parameters.cs
@@ -130,8 +130,7 @@ namespace DbMetal
/// <summary>
/// Interfaces to be implemented
/// </summary>
- public string EntityInterfaces { get; set; }
- public string[] EntityImplementedInterfaces { get { return GetArray(EntityInterfaces); } }
+ public string[] EntityInterfaces { get; set; }

/// <summary>
/// Extra attributes to be implemented by class
@@ -229,7 +228,7 @@ namespace DbMetal
Culture = "en";
GenerateTypes = new List<string>();
GenerateTimestamps = true;
- EntityInterfaces = "INotifyPropertyChanging,INotifyPropertyChanged";//INotifyPropertyChanging INotifyPropertyChanged IModified
+ EntityInterfaces = new []{ "INotifyPropertyChanging", "INotifyPropertyChanged" };
}

/// <summary>
@@ -299,10 +298,6 @@ namespace DbMetal
"Base {TYPE} of entity classes in the generated code "
+"(default: entities have no base class).",
type => EntityBase = type },
- { "entityInterfaces=",
- "Comma separated base {INTERFACE(S)} of entity classes in the "
- +"generated code (default: entities implement INotifyPropertyChanging, INotifyPropertyChanged).",
- interfaces => EntityInterfaces = interfaces },
{ "entityAttributes=",
"Comma separated {ATTRIBUTE(S)} of entity classes in the generated code.",
attributes => EntityAttributes = attributes },
--
0001-Removed-the-entityInterfaces-option-from-DbMetal.patch.gz

Emanuele Aina

unread,
Nov 16, 2009, 4:51:32 PM11/16/09
to dbl...@googlegroups.com
> > Exactly. So it looks like a feature without a purpose. Kill it.
>
> Gzipped patch attached.

Committed as r1277.
Reply all
Reply to author
Forward
0 new messages