2 // Mono.Data.CustomDataClassGenerator
5 // Atsushi Enomoto <atsushi@ximian.com>
9 // API notes are the bottom of the source.
11 // This class is standalone testable (even under MS.NET) when compiled with
12 // -d:DATACLASS_GENERATOR_STANDALONE .
16 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
18 // Permission is hereby granted, free of charge, to any person obtaining
19 // a copy of this software and associated documentation files (the
20 // "Software"), to deal in the Software without restriction, including
21 // without limitation the rights to use, copy, modify, merge, publish,
22 // distribute, sublicense, and/or sell copies of the Software, and to
23 // permit persons to whom the Software is furnished to do so, subject to
24 // the following conditions:
26 // The above copyright notice and this permission notice shall be
27 // included in all copies or substantial portions of the Software.
29 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
30 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
31 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
32 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
33 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
34 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
35 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
40 using System
.Collections
;
42 using System
.Globalization
;
44 using System
.CodeDom
.Compiler
;
45 using System
.ComponentModel
;
46 using System
.Runtime
.Serialization
;
49 using Microsoft
.CSharp
;
55 #if DATACLASS_GENERATOR_STANDALONE
58 public static void Main (string [] args
)
61 if (args
.Length
< 1) {
62 Console
.WriteLine ("mono dsgentest.exe filename");
66 DataSet ds
= new DataSet ();
67 ds
.ReadXml (args
[0]);
68 ICodeGenerator gen
= new CSharpCodeProvider ().CreateGenerator ();
70 CodeNamespace cns
= new CodeNamespace ("MyNamespace");
71 TextWriter tw
= new StreamWriter (Path
.ChangeExtension (args
[0], ".ms.cs"), false, Encoding
.Default
);
72 TypedDataSetGenerator
.Generate (ds
, cns
, gen
);
73 gen
.GenerateCodeFromNamespace (cns
, tw
, null);
76 cns
= new CodeNamespace ("MyNamespace");
77 tw
= new StreamWriter (Path
.ChangeExtension (args
[0], ".mono.cs"), false, Encoding
.Default
);
78 CustomDataClassGenerator
.CreateDataSetClasses (ds
, cns
, gen
, null);
79 gen
.GenerateCodeFromNamespace (cns
, tw
, null);
81 } catch (Exception ex
) {
82 Console
.WriteLine (ex
);
88 #if DATACLASS_GENERATOR_STANDALONE
89 public class CustomDataClassGenerator
91 internal class CustomDataClassGenerator
94 public static void CreateDataSetClasses (DataSet ds
,
95 CodeNamespace cns
, ICodeGenerator gen
,
96 ClassGeneratorOptions options
)
98 new Generator (ds
, cns
, gen
, options
).Run ();
101 public static string MakeSafeName (string name
, ICodeGenerator codeGen
)
103 if (name
== null || codeGen
== null)
104 throw new NullReferenceException ();
106 name
= codeGen
.CreateValidIdentifier (name
);
108 if (name
.Length
== 0)
111 StringBuilder sb
= null;
112 if (!Char
.IsLetter (name
, 0) && name
[0] != '_') {
113 sb
= new StringBuilder ();
118 for (int i
= 0; i
< name
.Length
; i
++) {
119 if (!Char
.IsLetterOrDigit (name
, i
)) {
121 sb
= new StringBuilder ();
122 sb
.Append (name
, start
, i
- start
);
129 sb
.Append (name
, start
, name
.Length
- start
);
130 return sb
.ToString ();
137 #if DATACLASS_GENERATOR_STANDALONE
138 public delegate string CodeNamingMethod (string source
, ICodeGenerator gen
);
140 internal delegate string CodeNamingMethod (string source
, ICodeGenerator gen
);
143 #if DATACLASS_GENERATOR_STANDALONE
144 public class ClassGeneratorOptions
146 internal class ClassGeneratorOptions
149 public bool MakeClassesInsideDataSet
= true; // default = MS compatible
151 public CodeNamingMethod CreateDataSetName
;
152 public CodeNamingMethod CreateTableTypeName
;
153 public CodeNamingMethod CreateTableMemberName
;
154 public CodeNamingMethod CreateTableColumnName
;
155 public CodeNamingMethod CreateColumnName
;
156 public CodeNamingMethod CreateRowName
;
157 public CodeNamingMethod CreateRelationName
;
158 public CodeNamingMethod CreateTableDelegateName
;
159 public CodeNamingMethod CreateEventArgsName
;
161 internal string DataSetName (string source
, ICodeGenerator gen
)
163 if (CreateDataSetName
!= null)
164 return CreateDataSetName (source
, gen
);
166 return CustomDataClassGenerator
.MakeSafeName (source
, gen
);
169 internal string TableTypeName (string source
, ICodeGenerator gen
)
171 if (CreateTableTypeName
!= null)
172 return CreateTableTypeName (source
, gen
);
174 return CustomDataClassGenerator
.MakeSafeName (source
, gen
) + "DataTable";
177 internal string TableMemberName (string source
, ICodeGenerator gen
)
179 if (CreateTableMemberName
!= null)
180 return CreateTableMemberName (source
, gen
);
182 return CustomDataClassGenerator
.MakeSafeName (source
, gen
);
185 internal string TableColName (string source
, ICodeGenerator gen
)
187 if (CreateTableColumnName
!= null)
188 return CreateTableColumnName (source
, gen
);
190 return CustomDataClassGenerator
.MakeSafeName (source
, gen
);
193 internal string TableDelegateName (string source
, ICodeGenerator gen
)
195 if (CreateTableDelegateName
!= null)
196 return CreateTableDelegateName (source
, gen
);
198 return CustomDataClassGenerator
.MakeSafeName (source
, gen
) + "RowChangedEventHandler";
201 internal string EventArgsName (string source
, ICodeGenerator gen
)
203 if (CreateEventArgsName
!= null)
204 return CreateEventArgsName (source
, gen
);
206 return CustomDataClassGenerator
.MakeSafeName (source
, gen
) + "RowChangedEventArgs";
209 internal string ColumnName (string source
, ICodeGenerator gen
)
211 if (CreateColumnName
!= null)
212 return CreateColumnName (source
, gen
);
214 return CustomDataClassGenerator
.MakeSafeName (source
, gen
);
217 internal string RowName (string source
, ICodeGenerator gen
)
219 if (CreateRowName
!= null)
220 return CreateRowName (source
, gen
);
222 return CustomDataClassGenerator
.MakeSafeName (source
, gen
) + "Row";
225 internal string RelationName (string source
, ICodeGenerator gen
)
227 if (CreateRelationName
!= null)
228 return CreateRelationName (source
, gen
);
230 return CustomDataClassGenerator
.MakeSafeName (source
, gen
) + "Relation";
234 internal class Generator
236 static ClassGeneratorOptions DefaultOptions
= new ClassGeneratorOptions ();
240 ClassGeneratorOptions opts
;
243 CodeTypeDeclaration dsType
;
245 public Generator (DataSet ds
, CodeNamespace cns
, ICodeGenerator gen
, ClassGeneratorOptions options
)
253 opts
= DefaultOptions
;
259 cns
.Imports
.Add (new CodeNamespaceImport ("System"));
260 cns
.Imports
.Add (new CodeNamespaceImport ("System.Collections"));
261 cns
.Imports
.Add (new CodeNamespaceImport ("System.ComponentModel"));
262 cns
.Imports
.Add (new CodeNamespaceImport ("System.Data"));
263 cns
.Imports
.Add (new CodeNamespaceImport ("System.Runtime.Serialization"));
264 cns
.Imports
.Add (new CodeNamespaceImport ("System.Xml"));
267 CodeTypeDeclaration dsType
= GenerateDataSetType ();
268 cns
.Types
.Add (dsType
);
269 foreach (DataTable dt
in ds
.Tables
) {
270 // 1. table types ([foo]DataTable)
271 // 2. row types ([foo]Row)
272 // 3. delegates ([foo]RowChangedEventHandler)
273 // 4. eventargs ([foo]RowChangeEventArgs)
275 CodeTypeDeclaration dtType
= GenerateDataTableType (dt
);
277 CodeTypeDeclaration dtRow
= GenerateDataRowType (dt
);
279 CodeTypeDelegate dtDelegate
= new CodeTypeDelegate (opts
.TableDelegateName (dt
.TableName
, gen
));
280 dtDelegate
.Parameters
.Add (Param (typeof (object), "o"));
281 dtDelegate
.Parameters
.Add (Param (opts
.EventArgsName (dt
.TableName
, gen
), "e"));
283 CodeTypeDeclaration dtEventType
= GenerateEventType (dt
);
285 // Add types to either DataSet or CodeNamespace
286 if (opts
.MakeClassesInsideDataSet
) {
287 dsType
.Members
.Add (dtType
);
288 dsType
.Members
.Add (dtRow
);
289 dsType
.Members
.Add (dtDelegate
);
290 dsType
.Members
.Add (dtEventType
);
293 cns
.Types
.Add (dtType
);
294 cns
.Types
.Add (dtRow
);
295 cns
.Types
.Add (dtDelegate
);
296 cns
.Types
.Add (dtEventType
);
301 private CodeThisReferenceExpression
This ()
303 return new CodeThisReferenceExpression ();
306 private CodeBaseReferenceExpression
Base ()
308 return new CodeBaseReferenceExpression ();
311 private CodePrimitiveExpression
Const (object value)
313 return new CodePrimitiveExpression (value);
316 private CodeTypeReference
TypeRef (Type t
)
318 return new CodeTypeReference (t
);
321 private CodeTypeReference
TypeRef (string name
)
323 return new CodeTypeReference (name
);
326 private CodeParameterDeclarationExpression
Param (string t
, string name
)
328 return new CodeParameterDeclarationExpression (t
, name
);
331 private CodeParameterDeclarationExpression
Param (Type t
, string name
)
333 return new CodeParameterDeclarationExpression (t
, name
);
336 private CodeParameterDeclarationExpression
Param (CodeTypeReference t
, string name
)
338 return new CodeParameterDeclarationExpression (t
, name
);
341 private CodeArgumentReferenceExpression
ParamRef (string name
)
343 return new CodeArgumentReferenceExpression (name
);
346 private CodeCastExpression
Cast (string t
, CodeExpression exp
)
348 return new CodeCastExpression (t
, exp
);
351 private CodeCastExpression
Cast (Type t
, CodeExpression exp
)
353 return new CodeCastExpression (t
, exp
);
356 private CodeCastExpression
Cast (CodeTypeReference t
, CodeExpression exp
)
358 return new CodeCastExpression (t
, exp
);
361 private CodeExpression
New (Type t
, params CodeExpression
[] parameters
)
363 return new CodeObjectCreateExpression (t
, parameters
);
366 private CodeExpression
New (string t
, params CodeExpression
[] parameters
)
368 return new CodeObjectCreateExpression (TypeRef (t
), parameters
);
371 private CodeExpression
NewArray (Type t
, params CodeExpression
[] parameters
)
373 return new CodeArrayCreateExpression (t
, parameters
);
376 private CodeVariableReferenceExpression
Local (string name
)
378 return new CodeVariableReferenceExpression (name
);
381 private CodeFieldReferenceExpression
FieldRef (string name
)
383 return new CodeFieldReferenceExpression (new CodeThisReferenceExpression (), name
);
386 private CodeFieldReferenceExpression
FieldRef (CodeExpression exp
, string name
)
388 return new CodeFieldReferenceExpression (exp
, name
);
391 private CodePropertyReferenceExpression
PropRef (string name
)
393 return new CodePropertyReferenceExpression (new CodeThisReferenceExpression (), name
);
396 private CodePropertyReferenceExpression
PropRef (CodeExpression target
, string name
)
398 return new CodePropertyReferenceExpression (target
, name
);
401 private CodeIndexerExpression
IndexerRef (CodeExpression target
, CodeExpression parameters
)
403 return new CodeIndexerExpression (target
, parameters
);
406 private CodeIndexerExpression
IndexerRef (CodeExpression param
)
408 return new CodeIndexerExpression (new CodeThisReferenceExpression (), param
);
411 private CodeEventReferenceExpression
EventRef (string name
)
413 return new CodeEventReferenceExpression (new CodeThisReferenceExpression (), name
);
416 private CodeEventReferenceExpression
EventRef (CodeExpression target
, string name
)
418 return new CodeEventReferenceExpression (target
, name
);
421 private CodeMethodInvokeExpression
MethodInvoke (string name
, params CodeExpression
[] parameters
)
423 return new CodeMethodInvokeExpression (new CodeThisReferenceExpression (), name
, parameters
);
426 private CodeMethodInvokeExpression
MethodInvoke (CodeExpression target
, string name
, params CodeExpression
[] parameters
)
428 return new CodeMethodInvokeExpression (target
, name
, parameters
);
431 // note that this is "Identity" equality comparison
432 private CodeBinaryOperatorExpression
Equals (CodeExpression exp1
, CodeExpression exp2
)
434 return new CodeBinaryOperatorExpression (exp1
, CodeBinaryOperatorType
.IdentityEquality
, exp2
);
437 private CodeBinaryOperatorExpression
Inequals (CodeExpression exp1
, CodeExpression exp2
)
439 return new CodeBinaryOperatorExpression (exp1
, CodeBinaryOperatorType
.IdentityInequality
, exp2
);
442 private CodeTypeReferenceExpression
TypeRefExp (Type t
)
444 return new CodeTypeReferenceExpression (t
);
448 private CodeExpressionStatement
Eval (CodeExpression exp
)
450 return new CodeExpressionStatement (exp
);
453 private CodeAssignStatement
Let (CodeExpression exp
, CodeExpression
value)
455 return new CodeAssignStatement (exp
, value);
458 private CodeMethodReturnStatement
Return (CodeExpression exp
)
460 return new CodeMethodReturnStatement (exp
);
463 private CodeVariableDeclarationStatement
VarDecl (Type t
,
464 string name
, CodeExpression init
)
466 return new CodeVariableDeclarationStatement (t
, name
, init
);
469 private CodeVariableDeclarationStatement
VarDecl (string t
,
470 string name
, CodeExpression init
)
472 return new CodeVariableDeclarationStatement (t
, name
, init
);
475 private CodeCommentStatement
Comment (string comment
)
477 return new CodeCommentStatement (comment
);
480 private CodeThrowExceptionStatement
Throw (CodeExpression exp
)
482 return new CodeThrowExceptionStatement (exp
);
485 #region DataSet class
487 private CodeTypeDeclaration
GenerateDataSetType ()
490 dsType
= new CodeTypeDeclaration (opts
.DataSetName (ds
.DataSetName
, gen
));
491 dsType
.BaseTypes
.Add (TypeRef (typeof (DataSet
)));
494 dsType
.Members
.Add (CreateDataSetDefaultCtor ());
495 // runtime serialization .ctor()
496 dsType
.Members
.Add (CreateDataSetSerializationCtor ());
499 dsType
.Members
.Add (CreateDataSetCloneMethod (dsType
));
501 // FIXME: I keep these methods out of the generated source right now.
502 // It should be added after runtime serialization was implemented.
504 // ShouldSerializeTables()
505 dsType.Members.Add (CreateDataSetShouldSerializeTables ());
507 // ShouldSerializeRelations()
508 dsType.Members.Add (CreateDataSetShouldSerializeRelations ());
510 // ReadXmlSerializable()
511 dsType.Members.Add (CreateDataSetReadXmlSerializable ());
513 // GetSchemaSerializable()
514 dsType.Members.Add (CreateDataSetGetSchemaSerializable ());
516 dsType
.Members
.Add (CreateDataSetInitializeClass ());
517 dsType
.Members
.Add (CreateDataSetInitializeFields ());
518 dsType
.Members
.Add (CreateDataSetSchemaChanged ());
520 // table class and members
521 foreach (DataTable table
in ds
.Tables
)
522 CreateDataSetTableMembers (dsType
, table
);
523 // relation class and members
524 foreach (DataRelation rel
in ds
.Relations
)
525 CreateDataSetRelationMembers (dsType
, rel
);
533 // InitializeClass();
534 // CollectionChangeEventHandler handler = new CollectionChangeEventHandler (SchemaChanged);
535 // Tables.CollectionChanged += handler;
536 // Relations.CollectionChanged += handler;
538 private CodeConstructor
CreateDataSetDefaultCtor ()
540 CodeConstructor ctor
= new CodeConstructor ();
541 ctor
.Attributes
= MemberAttributes
.Public
;
542 // Code: InitializeClass().
543 ctor
.Statements
.Add (Eval (MethodInvoke ("InitializeClass")));
545 // Code: CollectionChangedEventHandler handler = new CollectionChangeEventHandler (SchemeChanged);
546 CodeVariableDeclarationStatement stmt2
=
548 typeof (CollectionChangeEventHandler
),
550 New (typeof (CollectionChangeEventHandler
), FieldRef ("SchemaChanged")));
551 ctor
.Statements
.Add (stmt2
);
553 // Code: Tables.CollectionChanged += handler;
554 ctor
.Statements
.Add (
555 new CodeAttachEventStatement (
558 "CollectionChanged"),
561 // Code: Relations.CollectionChanged += handler;
562 ctor
.Statements
.Add (
563 new CodeAttachEventStatement (
565 PropRef ("Relations"),
566 "CollectionChanged"),
575 // protected Foo (SerializationInfo info, StreamingContext ctx)
577 // throw new NotImplementedException ();
579 private CodeConstructor
CreateDataSetSerializationCtor ()
581 CodeConstructor ctor
= new CodeConstructor ();
582 ctor
.Attributes
= MemberAttributes
.Family
;
583 ctor
.Parameters
.Add (Param (typeof (SerializationInfo
), "info"));
584 ctor
.Parameters
.Add (Param (typeof (StreamingContext
), "ctx"));
587 // // TODO: implement
588 // throw new NotImplementedException ();
589 ctor
.Statements
.Add (Comment ("TODO: implement"));
590 ctor
.Statements
.Add (Throw (New (typeof (NotImplementedException
))));
596 // public override DataSet Clone()
598 // [foo] set = ([foo]) base.Clone ();
599 // set.InitializeFields ();
602 private CodeMemberMethod
CreateDataSetCloneMethod (CodeTypeDeclaration dsType
)
604 CodeMemberMethod m
= new CodeMemberMethod ();
605 m
.ReturnType
= TypeRef (typeof (DataSet
));
606 m
.Attributes
= MemberAttributes
.Public
| MemberAttributes
.Override
;
608 // Code: [foo] set = ([foo]) base.Clone ();
609 CodeVariableReferenceExpression
set = Local ("set");
610 m
.Statements
.Add (VarDecl (
615 MethodInvoke (Base (), "Clone"))));
616 m
.Statements
.Add (Eval (MethodInvoke (set, "InitializeFields")));
617 m
.Statements
.Add (Return (set));
622 // protected override bool ShouldSerializeTables ()
624 // return true; // it should be false
626 private CodeMemberMethod
CreateDataSetShouldSerializeTables ()
628 CodeMemberMethod m
= new CodeMemberMethod ();
629 m
.Name
= "ShouldSerializeTables";
630 m
.ReturnType
= TypeRef (typeof (bool));
631 m
.Attributes
= MemberAttributes
.Family
| MemberAttributes
.Override
;
632 // FIXME: set "false" after serialization .ctor() implementation
633 m
.Statements
.Add (Return (Const (true)));
638 // protected override bool ShouldSerializeRelations ()
640 // return true; // it should be false
642 private CodeMemberMethod
CreateDataSetShouldSerializeRelations ()
644 CodeMemberMethod m
= new CodeMemberMethod ();
645 m
.Name
= "ShouldSerializeRelations";
646 m
.ReturnType
= TypeRef (typeof (bool));
647 m
.Attributes
= MemberAttributes
.Family
| MemberAttributes
.Override
;
648 // FIXME: set "false" after serialization .ctor() implementation
649 m
.Statements
.Add (Return (Const (true)));
654 // protected override void ReadXmlSerializable()
656 // // TODO: implement
657 // throw new NotImplementedException ();
659 private CodeMemberMethod
CreateDataSetReadXmlSerializable ()
661 CodeMemberMethod method
= new CodeMemberMethod ();
662 method
.Name
= "ReadXmlSerializable";
663 method
.Attributes
= MemberAttributes
.Family
| MemberAttributes
.Override
;
664 method
.Parameters
.Add (Param (TypeRef (typeof (XmlReader
)), "reader"));
666 method
.Statements
.Add (Comment ("TODO: implement"));
667 // Hey, how can I specify the constructor to invoke chained ctor with an empty parameter list!?
668 method
.Statements
.Add (Throw (New (typeof (NotImplementedException
))));
672 private CodeMemberMethod
CreateDataSetInitializeClass ()
674 CodeMemberMethod m
= new CodeMemberMethod ();
675 m
.Name
= "InitializeClass";
676 m
.Attributes
= MemberAttributes
.Assembly
;
678 // dataset properties
679 m
.Statements
.Add (Let (PropRef ("DataSetName"), Const (ds
.DataSetName
)));
680 m
.Statements
.Add (Let (PropRef ("Prefix"), Const (ds
.Prefix
)));
681 m
.Statements
.Add (Let (PropRef ("Namespace"), Const (ds
.Namespace
)));
682 m
.Statements
.Add (Let (PropRef ("Locale"), New (typeof (CultureInfo
), Const (ds
.Locale
.Name
))));
683 m
.Statements
.Add (Let (PropRef ("CaseSensitive"), Const (ds
.CaseSensitive
)));
684 m
.Statements
.Add (Let (PropRef ("EnforceConstraints"), Const (ds
.EnforceConstraints
)));
687 foreach (DataTable dt
in ds
.Tables
) {
688 string tableFieldName
= "__table" + opts
.TableMemberName (dt
.TableName
, gen
);
689 string tableTypeName
= opts
.TableTypeName (dt
.TableName
, gen
);
690 m
.Statements
.Add (Let (FieldRef (tableFieldName
), New (tableTypeName
)));
691 m
.Statements
.Add (Eval (MethodInvoke (PropRef ("Tables"), "Add", FieldRef (tableFieldName
))));
694 bool fkcExists
= false;
695 bool ucExists
= false;
696 foreach (DataTable dt
in ds
.Tables
) {
697 string tname
= "__table" + opts
.TableMemberName (dt
.TableName
, gen
);
698 foreach (Constraint c
in dt
.Constraints
) {
699 UniqueConstraint uc
= c
as UniqueConstraint
;
702 m
.Statements
.Add (VarDecl (typeof (UniqueConstraint
), "uc", null));
705 CreateUniqueKeyStatements (m
, uc
, tname
);
708 ForeignKeyConstraint fkc
= c
as ForeignKeyConstraint
;
711 m
.Statements
.Add (VarDecl (typeof (ForeignKeyConstraint
), "fkc", null));
714 CreateForeignKeyStatements (m
, fkc
, tname
);
716 // What if other cases? dunno. Just ignore ;-)
719 foreach (DataRelation rel
in ds
.Relations
) {
720 string relName
= opts
.RelationName (rel
.RelationName
, gen
);
721 ArrayList pcols
= new ArrayList ();
722 foreach (DataColumn pcol
in rel
.ParentColumns
)
723 pcols
.Add (IndexerRef (PropRef (FieldRef ("__table" + opts
.TableMemberName (rel
.ParentTable
.TableName
, gen
)), "Columns"), Const (pcol
.ColumnName
)));
725 ArrayList ccols
= new ArrayList ();
726 foreach (DataColumn ccol
in rel
.ChildColumns
)
727 ccols
.Add (IndexerRef (PropRef (FieldRef ("__table" + opts
.TableMemberName (rel
.ChildTable
.TableName
, gen
)), "Columns"), Const (ccol
.ColumnName
)));
730 string fieldName
= "__relation" + relName
;
731 m
.Statements
.Add (Let (FieldRef (fieldName
), New (typeof (DataRelation
),
732 Const (rel
.RelationName
),
733 NewArray (typeof (DataColumn
), pcols
.ToArray (typeof (CodeExpression
)) as CodeExpression
[]),
734 NewArray (typeof (DataColumn
), ccols
.ToArray (typeof (CodeExpression
)) as CodeExpression
[]),
737 m
.Statements
.Add (Let (PropRef (FieldRef (fieldName
), "Nested"), Const (rel
.Nested
)));
743 private void CreateUniqueKeyStatements (CodeMemberMethod m
, UniqueConstraint uc
, string tableField
)
745 ArrayList al
= new ArrayList ();
746 foreach (DataColumn col
in uc
.Columns
)
747 al
.Add (IndexerRef (PropRef (FieldRef (tableField
), "Columns"), Const (col
.ColumnName
)));
749 m
.Statements
.Add (Let (Local ("uc"), New (
750 typeof (UniqueConstraint
),
751 Const (uc
.ConstraintName
),
754 al
.ToArray (typeof (CodeExpression
)) as CodeExpression
[]),
755 Const (uc
.IsPrimaryKey
))));
756 m
.Statements
.Add (MethodInvoke (PropRef (FieldRef (tableField
), "Constraints"), "Add", Local ("uc")));
759 private void CreateForeignKeyStatements (CodeMemberMethod m
,ForeignKeyConstraint fkc
, string tableField
)
761 ArrayList pcols
= new ArrayList ();
762 foreach (DataColumn col
in fkc
.Columns
)
763 pcols
.Add (IndexerRef (PropRef (FieldRef (tableField
), "Columns"), Const (col
.ColumnName
)));
765 ArrayList ccols
= new ArrayList ();
766 foreach (DataColumn col
in fkc
.RelatedColumns
)
767 pcols
.Add (IndexerRef (PropRef (FieldRef (tableField
), "Columns"), Const (col
.ColumnName
)));
769 m
.Statements
.Add (Let (Local ("fkc"), New (
770 typeof (ForeignKeyConstraint
),
771 Const (fkc
.ConstraintName
),
774 pcols
.ToArray (typeof (CodeExpression
)) as CodeExpression
[]),
777 ccols
.ToArray (typeof (CodeExpression
)) as CodeExpression
[]))));
779 m
.Statements
.Add (Let (
780 PropRef (Local ("fkc"), "AcceptRejectRule"),
781 FieldRef (TypeRefExp (typeof (AcceptRejectRule
)), Enum
.GetName (typeof (AcceptRejectRule
), fkc
.AcceptRejectRule
))));
782 m
.Statements
.Add (Let (
783 PropRef (Local ("fkc"), "DeleteRule"),
784 FieldRef (TypeRefExp (typeof (Rule
)), Enum
.GetName (typeof (Rule
), fkc
.DeleteRule
))));
785 m
.Statements
.Add (Let (
786 PropRef (Local ("fkc"), "UpdateRule"),
787 FieldRef (TypeRefExp (typeof (Rule
)), Enum
.GetName (typeof (Rule
), fkc
.UpdateRule
))));
789 m
.Statements
.Add (MethodInvoke (PropRef (FieldRef (tableField
), "Constraints"), "Add", Local ("fkc")));
792 private CodeMemberMethod
CreateDataSetInitializeFields ()
794 CodeMemberMethod m
= new CodeMemberMethod ();
795 m
.Attributes
= MemberAttributes
.Assembly
;
796 m
.Name
= "InitializeFields";
798 foreach (DataTable dt
in ds
.Tables
)
799 m
.Statements
.Add (Eval (MethodInvoke (FieldRef ("__table" + opts
.TableMemberName (dt
.TableName
, gen
)), "InitializeFields")));
801 foreach (DataRelation rel
in ds
.Relations
)
802 m
.Statements
.Add (Let (FieldRef ("__relation" + opts
.RelationName (rel
.RelationName
, gen
)), IndexerRef (PropRef ("Relations"), Const (rel
.RelationName
))));
807 private CodeMemberMethod
CreateDataSetSchemaChanged ()
809 CodeMemberMethod m
= new CodeMemberMethod ();
810 m
.Name
= "SchemaChanged";
811 m
.Parameters
.Add (Param (typeof (object), "sender"));
812 m
.Parameters
.Add (Param (typeof (CollectionChangeEventArgs
), "e"));
815 new CodeConditionStatement (
817 PropRef (ParamRef ("e"), "Action"),
818 FieldRef (TypeRefExp (typeof (CollectionChangeAction
)), "Remove")),
819 new CodeStatement
[] { Eval (MethodInvoke ("InitializeFields")) }
,
820 new CodeStatement
[] {}));
824 private void CreateDataSetTableMembers (CodeTypeDeclaration dsType
, DataTable table
)
826 string tableTypeName
= opts
.TableTypeName (table
.TableName
, gen
);
827 string tableVarName
= opts
.TableMemberName (table
.TableName
, gen
);
829 CodeMemberField privTable
= new CodeMemberField ();
830 privTable
.Type
= TypeRef (tableTypeName
);
831 privTable
.Name
= "__table" + tableVarName
;
832 dsType
.Members
.Add (privTable
);
834 CodeMemberProperty pubTable
= new CodeMemberProperty ();
835 pubTable
.Type
= TypeRef (tableTypeName
);
836 pubTable
.Attributes
= MemberAttributes
.Public
;
837 pubTable
.Name
= tableVarName
;
838 pubTable
.HasSet
= false;
839 // Code: return __table[foo];
840 pubTable
.GetStatements
.Add (Return (FieldRef ("__table" + tableVarName
)));
842 dsType
.Members
.Add (pubTable
);
846 private void CreateDataSetRelationMembers (CodeTypeDeclaration dsType
, DataRelation relation
)
848 string relName
= opts
.RelationName (relation
.RelationName
, gen
);
849 string fieldName
= "__relation" + relName
;
851 CodeMemberField field
= new CodeMemberField ();
852 field
.Type
= TypeRef (typeof (DataRelation
));
853 field
.Name
= fieldName
;
854 dsType
.Members
.Add (field
);
856 // This is not supported in MS.NET
857 CodeMemberProperty prop
= new CodeMemberProperty ();
858 prop
.Type
= TypeRef (typeof (DataRelation
));
859 prop
.Attributes
= MemberAttributes
.Public
;
862 // Code: return __relation[foo_bar];
863 prop
.GetStatements
.Add (Return (FieldRef (fieldName
)));
864 dsType
.Members
.Add (prop
);
871 #region DataTable class
873 private CodeTypeDeclaration
GenerateDataTableType (DataTable dt
)
875 CodeTypeDeclaration t
= new CodeTypeDeclaration ();
876 t
.Name
= opts
.TableTypeName (dt
.TableName
, gen
);
877 t
.BaseTypes
.Add (TypeRef (typeof (DataTable
)));
878 t
.BaseTypes
.Add (TypeRef (typeof (IEnumerable
)));
880 t
.Members
.Add (CreateTableCtor1 (dt
));
881 t
.Members
.Add (CreateTableCtor2 (dt
));
883 t
.Members
.Add (CreateTableCount (dt
));
884 t
.Members
.Add (CreateTableIndexer (dt
));
886 t
.Members
.Add (CreateTableInitializeClass (dt
));
887 t
.Members
.Add (CreateTableInitializeFields (dt
));
889 t
.Members
.Add (CreateTableGetEnumerator (dt
));
890 t
.Members
.Add (CreateTableClone (dt
));
891 t
.Members
.Add (CreateTableCreateInstance (dt
));
893 t
.Members
.Add (CreateTableAddRow1 (dt
));
894 t
.Members
.Add (CreateTableAddRow2 (dt
));
895 t
.Members
.Add (CreateTableNewRow (dt
));
896 t
.Members
.Add (CreateTableNewRowFromBuilder (dt
));
897 t
.Members
.Add (CreateTableRemoveRow (dt
));
898 t
.Members
.Add (CreateTableGetRowType (dt
));
900 t
.Members
.Add (CreateTableEventStarter (dt
, "Changing"));
901 t
.Members
.Add (CreateTableEventStarter (dt
, "Changed"));
902 t
.Members
.Add (CreateTableEventStarter (dt
, "Deleting"));
903 t
.Members
.Add (CreateTableEventStarter (dt
, "Deleted"));
906 t
.Members
.Add (CreateTableEvent (dt
, "RowChanging"));
907 t
.Members
.Add (CreateTableEvent (dt
, "RowChanged"));
908 t
.Members
.Add (CreateTableEvent (dt
, "RowDeleting"));
909 t
.Members
.Add (CreateTableEvent (dt
, "RowDeleted"));
912 foreach (DataColumn col
in dt
.Columns
) {
913 t
.Members
.Add (CreateTableColumnField (dt
, col
));
914 t
.Members
.Add (CreateTableColumnProperty (dt
, col
));
921 // internal [foo]DataTable () : base ("[foo]")
923 // InitializeClass ();
925 private CodeConstructor
CreateTableCtor1 (DataTable dt
)
927 CodeConstructor c
= new CodeConstructor ();
928 c
.Attributes
= MemberAttributes
.Assembly
;
929 c
.BaseConstructorArgs
.Add (Const (dt
.TableName
));
930 c
.Statements
.Add (Eval (MethodInvoke ("InitializeClass")));
931 c
.Statements
.Add (Eval (MethodInvoke ("InitializeFields")));
936 // internal [foo]DataTable (DataTable table) : base (table.TableName)
938 // // TODO: implement
939 // throw new NotImplementedException ();
941 private CodeConstructor
CreateTableCtor2 (DataTable dt
)
943 CodeConstructor c
= new CodeConstructor ();
944 c
.Attributes
= MemberAttributes
.Assembly
;
945 c
.Parameters
.Add (Param (typeof (DataTable
), "table"));
946 c
.BaseConstructorArgs
.Add (PropRef (ParamRef ("table"), "TableName"));
948 c
.Statements
.Add (Comment ("TODO: implement"));
949 c
.Statements
.Add (Throw (New (typeof (NotImplementedException
))));
953 private CodeMemberMethod
CreateTableInitializeClass (DataTable dt
)
955 CodeMemberMethod m
= new CodeMemberMethod ();
956 m
.Name
= "InitializeClass";
957 foreach (DataColumn col
in dt
.Columns
) {
958 m
.Statements
.Add (Eval (MethodInvoke (
961 New (typeof (DataColumn
),
962 Const (col
.ColumnName
),
963 new CodeTypeOfExpression (col
.DataType
)
969 private CodeMemberMethod
CreateTableInitializeFields (DataTable dt
)
971 CodeMemberMethod m
= new CodeMemberMethod ();
972 m
.Name
= "InitializeFields";
973 m
.Attributes
= MemberAttributes
.Assembly
;
974 foreach (DataColumn col
in dt
.Columns
)
975 m
.Statements
.Add (Let (FieldRef ("__column" + opts
.TableColName (col
.ColumnName
, gen
)), IndexerRef (PropRef ("Columns"), Const (col
.ColumnName
))));
979 private CodeMemberMethod
CreateTableClone (DataTable dt
)
981 CodeMemberMethod m
= new CodeMemberMethod ();
983 m
.Attributes
= MemberAttributes
.Public
| MemberAttributes
.Override
;
984 m
.ReturnType
= TypeRef (typeof (DataTable
));
985 string typeName
= opts
.TableTypeName (dt
.TableName
, gen
);
987 VarDecl (typeName
, "t", Cast (typeName
, MethodInvoke (Base (), "Clone"))));
988 m
.Statements
.Add (Eval (MethodInvoke (Local ("t"), "InitializeFields")));
989 m
.Statements
.Add (Return (Local ("t")));
993 private CodeMemberMethod
CreateTableGetEnumerator (DataTable dt
)
995 CodeMemberMethod m
= new CodeMemberMethod ();
996 m
.Name
= "GetEnumerator";
997 m
.Attributes
= MemberAttributes
.Public
;
998 m
.ReturnType
= TypeRef (typeof (IEnumerator
));
999 m
.Statements
.Add (Return (MethodInvoke (PropRef ("Rows"), "GetEnumerator")));
1003 private CodeMemberMethod
CreateTableCreateInstance (DataTable dt
)
1005 CodeMemberMethod m
= new CodeMemberMethod ();
1006 m
.Name
= "CreateInstance";
1007 m
.Attributes
= MemberAttributes
.Family
| MemberAttributes
.Override
;
1008 m
.ReturnType
= TypeRef (typeof (DataTable
));
1009 m
.Statements
.Add (Return (New (opts
.TableTypeName (dt
.TableName
, gen
))));
1013 private CodeMemberField
CreateTableColumnField (DataTable dt
, DataColumn col
)
1015 CodeMemberField f
= new CodeMemberField ();
1016 f
.Name
= "__column" + opts
.ColumnName (col
.ColumnName
, gen
);
1017 f
.Type
= TypeRef (typeof (DataColumn
));
1021 private CodeMemberProperty
CreateTableColumnProperty (DataTable dt
, DataColumn col
)
1023 string name
= opts
.ColumnName (col
.ColumnName
, gen
);
1024 CodeMemberProperty p
= new CodeMemberProperty ();
1025 p
.Name
= name
+ "Column";
1026 p
.Attributes
= MemberAttributes
.Assembly
;
1027 p
.Type
= TypeRef (typeof (DataColumn
));
1029 p
.GetStatements
.Add (Return (FieldRef ("__column" + name
)));
1033 private CodeMemberProperty
CreateTableCount (DataTable dt
)
1035 CodeMemberProperty p
= new CodeMemberProperty ();
1037 p
.Attributes
= MemberAttributes
.Public
;
1038 p
.Type
= TypeRef (typeof (int));
1040 p
.GetStatements
.Add (Return (PropRef (PropRef ("Rows"), "Count")));
1044 private CodeMemberProperty
CreateTableIndexer (DataTable dt
)
1046 string rowName
= opts
.RowName (dt
.TableName
, gen
);
1047 CodeMemberProperty ix
= new CodeMemberProperty ();
1048 ix
.Name
= "Item"; // indexer
1049 ix
.Attributes
= MemberAttributes
.Public
;
1050 ix
.Type
= TypeRef (rowName
);
1051 ix
.Parameters
.Add (Param (typeof (int), "i"));
1053 ix
.GetStatements
.Add (Return (Cast (rowName
, IndexerRef (PropRef ("Rows"), ParamRef ("i")))));
1057 private CodeMemberMethod
CreateTableAddRow1 (DataTable dt
)
1059 CodeMemberMethod m
= new CodeMemberMethod ();
1060 string rowType
= opts
.RowName (dt
.TableName
, gen
);
1061 m
.Name
= "Add" + rowType
;
1062 m
.Attributes
= MemberAttributes
.Public
;
1063 m
.Parameters
.Add (Param (TypeRef (rowType
), "row"));
1064 m
.Statements
.Add (Eval (MethodInvoke (PropRef ("Rows"), "Add", ParamRef ("row"))));
1068 private CodeMemberMethod
CreateTableAddRow2 (DataTable dt
)
1070 CodeMemberMethod m
= new CodeMemberMethod ();
1071 string rowType
= opts
.RowName (dt
.TableName
, gen
);
1072 m
.Name
= "Add" + rowType
;
1073 m
.ReturnType
= TypeRef (rowType
);
1074 m
.Attributes
= MemberAttributes
.Public
;
1076 m
.Statements
.Add (VarDecl (rowType
, "row", MethodInvoke ("New" + rowType
)));
1078 foreach (DataColumn col
in dt
.Columns
) {
1079 if (col
.ColumnMapping
== MappingType
.Hidden
) {
1080 foreach (DataRelation r
in dt
.DataSet
.Relations
) {
1081 if (r
.ChildTable
== dt
) {
1083 string paramType
= opts
.RowName (r
.ParentTable
.TableName
, gen
);
1084 string paramName
= paramType
;
1085 m
.Parameters
.Add (Param (paramType
, paramName
));
1086 // CODE: SetParentRow (fooRow, DataSet.Relations ["foo_bar"]);
1087 m
.Statements
.Add (Eval (MethodInvoke (Local ("row"), "SetParentRow", ParamRef (paramName
), IndexerRef (PropRef (PropRef ("DataSet"), "Relations"), Const (r
.RelationName
)))));
1094 string paramName
= opts
.ColumnName (col
.ColumnName
, gen
);
1095 m
.Parameters
.Add (Param (col
.DataType
, paramName
));
1096 // row ["foo"] = foo;
1097 m
.Statements
.Add (Let (IndexerRef (Local ("row"), Const (paramName
)), ParamRef (paramName
)));
1102 m
.Statements
.Add (MethodInvoke (PropRef ("Rows"), "Add", Local ("row")));
1103 m
.Statements
.Add (Return (Local ("row")));
1108 private CodeMemberMethod
CreateTableNewRow (DataTable dt
)
1110 CodeMemberMethod m
= new CodeMemberMethod ();
1111 string rowType
= opts
.RowName (dt
.TableName
, gen
);
1112 m
.Name
= "New" + rowType
;
1113 m
.ReturnType
= TypeRef (rowType
);
1114 m
.Attributes
= MemberAttributes
.Public
;
1115 m
.Statements
.Add (Return (Cast (rowType
, MethodInvoke ("NewRow"))));
1119 private CodeMemberMethod
CreateTableNewRowFromBuilder (DataTable dt
)
1121 CodeMemberMethod m
= new CodeMemberMethod ();
1122 m
.Name
= "NewRowFromBuilder";
1123 m
.Attributes
= MemberAttributes
.Family
| MemberAttributes
.Override
;
1124 m
.ReturnType
= TypeRef (typeof (DataRow
));
1125 m
.Parameters
.Add (Param (typeof (DataRowBuilder
), "builder"));
1126 m
.Statements
.Add (Return (New (opts
.RowName (dt
.TableName
, gen
), ParamRef ("builder"))));
1130 private CodeMemberMethod
CreateTableRemoveRow (DataTable dt
)
1132 CodeMemberMethod m
= new CodeMemberMethod ();
1133 string rowType
= opts
.RowName (dt
.TableName
, gen
);
1134 m
.Name
= "Remove" + rowType
;
1135 m
.Attributes
= MemberAttributes
.Public
;
1136 m
.Parameters
.Add (Param (TypeRef (rowType
), "row"));
1137 m
.Statements
.Add (Eval (MethodInvoke (PropRef ("Rows"), "Remove", ParamRef ("row"))));
1141 private CodeMemberMethod
CreateTableGetRowType (DataTable dt
)
1143 CodeMemberMethod m
= new CodeMemberMethod ();
1144 m
.Name
= "GetRowType";
1145 m
.Attributes
= MemberAttributes
.Family
| MemberAttributes
.Override
;
1146 m
.ReturnType
= TypeRef (typeof (Type
));
1147 m
.Statements
.Add (Return (new CodeTypeOfExpression (opts
.RowName (dt
.TableName
, gen
))));
1151 private CodeMemberMethod
CreateTableEventStarter (DataTable dt
, string type
)
1153 CodeMemberMethod m
= new CodeMemberMethod ();
1154 m
.Name
= "OnRow" + type
;
1155 m
.Attributes
= MemberAttributes
.Family
| MemberAttributes
.Override
;
1156 m
.Parameters
.Add (Param (typeof (DataRowChangeEventArgs
), "e"));
1158 m
.Statements
.Add (Eval (MethodInvoke (
1162 string eventName
= opts
.TableMemberName (dt
.TableName
, gen
) + "Row" + type
;
1163 CodeStatement trueStmt
= Eval (
1168 opts
.EventArgsName (dt
.TableName
, gen
),
1169 Cast (opts
.RowName (dt
.TableName
, gen
), PropRef (ParamRef ("e"), "Row")),
1170 PropRef (ParamRef ("e"), "Action"))));
1173 new CodeConditionStatement (
1174 Inequals (EventRef (eventName
), Const (null)),
1175 new CodeStatement
[] {trueStmt}
,
1176 new CodeStatement
[] {}));
1181 private CodeMemberEvent
CreateTableEvent (DataTable dt
, string nameSuffix
)
1183 CodeMemberEvent cme
= new CodeMemberEvent ();
1184 cme
.Attributes
= MemberAttributes
.Public
;
1185 cme
.Name
= opts
.TableMemberName (dt
.TableName
, gen
) + nameSuffix
;
1186 cme
.Type
= TypeRef (opts
.TableDelegateName (dt
.TableName
, gen
));
1196 public CodeTypeDeclaration
GenerateDataRowType (DataTable dt
)
1198 CodeTypeDeclaration t
= new CodeTypeDeclaration ();
1199 t
.Name
= opts
.RowName (dt
.TableName
, gen
);
1200 t
.BaseTypes
.Add (TypeRef (typeof (DataRow
)));
1202 t
.Members
.Add (CreateRowCtor (dt
));
1204 t
.Members
.Add (CreateRowTableField (dt
));
1206 foreach (DataColumn col
in dt
.Columns
) {
1207 if (col
.ColumnMapping
!= MappingType
.Hidden
) {
1208 t
.Members
.Add (CreateRowColumnProperty (dt
, col
));
1209 t
.Members
.Add (CreateRowColumnIsNull (dt
, col
));
1210 t
.Members
.Add (CreateRowColumnSetNull (dt
, col
));
1214 foreach (DataRelation rel
in dt
.ParentRelations
)
1215 t
.Members
.Add (CreateRowParentRowProperty (dt
, rel
));
1216 foreach (DataRelation rel
in dt
.ChildRelations
)
1217 t
.Members
.Add (CreateRowGetChildRows (dt
, rel
));
1222 private CodeConstructor
CreateRowCtor (DataTable dt
)
1224 CodeConstructor c
= new CodeConstructor ();
1225 c
.Attributes
= MemberAttributes
.Assembly
;
1226 c
.Parameters
.Add (Param (typeof (DataRowBuilder
), "builder"));
1227 c
.BaseConstructorArgs
.Add (ParamRef ("builder"));
1228 c
.Statements
.Add (Let (FieldRef ("table"), Cast (
1229 opts
.TableTypeName (dt
.TableName
, gen
),
1230 PropRef ("Table"))));
1234 private CodeMemberField
CreateRowTableField (DataTable dt
)
1236 CodeMemberField f
= new CodeMemberField ();
1238 f
.Type
= TypeRef (opts
.TableTypeName (dt
.TableName
, gen
));
1242 private CodeMemberProperty
CreateRowColumnProperty (DataTable dt
, DataColumn col
)
1244 CodeMemberProperty p
= new CodeMemberProperty ();
1245 p
.Name
= opts
.ColumnName (col
.ColumnName
, gen
);
1246 p
.Type
= TypeRef (col
.DataType
);
1247 p
.Attributes
= MemberAttributes
.Public
;
1249 // This part should be better than MS code output.
1251 // object ret = this [col];
1252 // if (ret == DBNull.Value)
1253 // throw new StrongTypingException ()
1255 // return (type) ret;
1256 p
.GetStatements
.Add (VarDecl (typeof (object), "ret",
1259 opts
.TableColName (col
.ColumnName
, gen
) + "Column"))));
1260 p
.GetStatements
.Add (new CodeConditionStatement (
1263 PropRef (TypeRefExp (typeof (DBNull
)), "Value")),
1264 new CodeStatement
[] {
1265 Throw (New (typeof (StrongTypingException
), Const ("Cannot get strong typed value since it is DB null."), Const (null))) },
1266 new CodeStatement
[] {
1267 Return (Cast (col
.DataType
, Local ("ret"))) }));
1269 p
.SetStatements
.Add (Let (IndexerRef (PropRef (PropRef ("table"), opts
.TableColName (col
.ColumnName
, gen
) + "Column")), new CodePropertySetValueReferenceExpression ()));
1274 private CodeMemberMethod
CreateRowColumnIsNull (DataTable dt
, DataColumn col
)
1276 CodeMemberMethod m
= new CodeMemberMethod ();
1277 m
.Name
= "Is" + opts
.ColumnName (col
.ColumnName
, gen
) + "Null";
1278 m
.Attributes
= MemberAttributes
.Public
;
1279 m
.ReturnType
= TypeRef (typeof (bool));
1280 m
.Statements
.Add (Return (MethodInvoke (
1282 // table[foo].[bar]Column
1285 opts
.TableColName (col
.ColumnName
, gen
) + "Column"))));
1289 private CodeMemberMethod
CreateRowColumnSetNull (DataTable dt
, DataColumn col
)
1291 CodeMemberMethod m
= new CodeMemberMethod ();
1292 m
.Name
= "Set" + opts
.ColumnName (col
.ColumnName
, gen
) + "Null";
1293 m
.Attributes
= MemberAttributes
.Public
;
1294 m
.Statements
.Add (Let (IndexerRef (
1297 opts
.TableColName (col
.ColumnName
, gen
) + "Column")),
1298 PropRef (TypeRefExp (typeof (DBNull
)), "Value")));
1303 private CodeMemberProperty
CreateRowParentRowProperty (DataTable dt
, DataRelation rel
)
1305 CodeMemberProperty p
= new CodeMemberProperty ();
1306 p
.Name
= opts
.TableMemberName (rel
.ParentTable
.TableName
, gen
) + "Row";
1307 p
.Attributes
= MemberAttributes
.Public
;
1308 p
.Type
= TypeRef (opts
.RowName (rel
.ParentTable
.TableName
, gen
));
1309 p
.GetStatements
.Add (Return (Cast (p
.Type
, MethodInvoke (
1317 Const (rel
.RelationName
))))));
1318 p
.SetStatements
.Add (Eval (MethodInvoke (
1320 new CodePropertySetValueReferenceExpression (),
1327 Const (rel
.RelationName
)))));
1332 private CodeMemberMethod
CreateRowGetChildRows (DataTable dt
, DataRelation rel
)
1334 CodeMemberMethod m
= new CodeMemberMethod ();
1335 m
.Name
= "Get" + opts
.TableMemberName (rel
.ChildTable
.TableName
, gen
) + "Rows";
1336 m
.Attributes
= MemberAttributes
.Public
;
1337 m
.ReturnType
= new CodeTypeReference (opts
.RowName (rel
.ChildTable
.TableName
, gen
), 1);
1338 m
.Statements
.Add (Return (Cast (m
.ReturnType
, MethodInvoke (
1346 Const (rel
.RelationName
))))));
1356 // public class [foo]ChangeEventArgs : EventArgs
1358 // private [foo]Row row;
1359 // private DataRowAction action;
1364 private CodeTypeDeclaration
GenerateEventType (DataTable dt
)
1366 CodeTypeDeclaration t
= new CodeTypeDeclaration ();
1367 t
.Name
= opts
.EventArgsName (dt
.TableName
, gen
);
1368 t
.BaseTypes
.Add (TypeRef (typeof (EventArgs
)));
1369 t
.Attributes
= MemberAttributes
.Public
;
1372 new CodeMemberField (
1373 TypeRef (opts
.RowName (dt
.TableName
, gen
)),
1376 new CodeMemberField (
1377 TypeRef (typeof (DataRowAction
)), "action"));
1378 t
.Members
.Add (CreateEventCtor (dt
));
1380 t
.Members
.Add (CreateEventRow (dt
));
1382 t
.Members
.Add (CreateEventAction (dt
));
1388 // public [foo]RowChangeEventArgs ([foo]Row r, DataRowAction a)
1393 private CodeConstructor
CreateEventCtor (DataTable dt
)
1395 CodeConstructor c
= new CodeConstructor ();
1396 c
.Attributes
= MemberAttributes
.Public
;
1397 c
.Parameters
.Add (Param (TypeRef (opts
.RowName (dt
.TableName
, gen
)), "r"));
1398 c
.Parameters
.Add (Param (TypeRef (typeof (DataRowAction
)), "a"));
1399 c
.Statements
.Add (Let (FieldRef ("row"), ParamRef ("r")));
1400 c
.Statements
.Add (Let (FieldRef ("action"), ParamRef ("a")));
1406 // public [foo]Row Row {
1407 // get { return row; }
1409 private CodeMemberProperty
CreateEventRow (DataTable dt
)
1411 CodeMemberProperty p
= new CodeMemberProperty ();
1413 p
.Attributes
= MemberAttributes
.Public
| MemberAttributes
.Final
;
1414 p
.Type
= TypeRef (opts
.RowName (dt
.TableName
, gen
));
1416 p
.GetStatements
.Add (Return (FieldRef ("row")));
1421 // public DataRowAction Action {
1422 // get { return action; }
1424 private CodeMemberProperty
CreateEventAction (DataTable dt
)
1426 CodeMemberProperty p
= new CodeMemberProperty ();
1428 p
.Attributes
= MemberAttributes
.Public
| MemberAttributes
.Final
;
1429 p
.Type
= TypeRef (typeof (DataRowAction
));
1431 p
.GetStatements
.Add (Return (FieldRef ("action")));
1441 /* =========================================================
1444 MonoDataSetGenerator API notes
1448 CreateDataSetClasses (
1452 GeneratorOptions options)
1456 *** Code naming method delegate
1458 public delegate string CodeNamingMethod (string sourceName);
1460 It is used in CodeGeneratorOptions (describled immediately below).
1464 *** Generator Options
1466 public bool MakeClassesInsideDataSet
1467 indicates whether classes and delegates other than DataSet
1468 itself are "contained" in the DataSet class or not.
1470 public CodeNamingMethod CreateDataSetName;
1471 public CodeNamingMethod CreateTableTypeName;
1472 public CodeNamingMethod CreateTableMemberName;
1473 public CodeNamingMethod CreateColumnName;
1474 public CodeNamingMethod CreateRowName;
1475 public CodeNamingMethod CreateRelationName;
1476 public CodeNamingMethod CreateTableDelegateName;
1477 public CodeNamingMethod CreateEventArgsName;
1478 Custom methods each of that returns type or member name.
1480 By default, they are set as to useTypedDataSetGenerator.
1481 CreateIdName() with modifications listed as below:
1484 TableTypeName: "DataTable" suffix
1485 TableMemberName: as is
1487 RowName: "Row" suffix
1488 RelationName: (TBD; maybe had better have another delegate type)
1489 DelegateName: "RowChangedEventHandler" suffix
1490 EventArgsName: "RowChangedEventArgs" suffix
1492 ** Auto Generated classes
1494 1. Custom DataSet class
1496 class name = dataset name, encoded by options.CreateDataSetName().
1500 public default .ctor()
1502 set custom delegate on Tables.CollectionChanged
1503 set custom delegate on Relations.CollectionChanged
1505 runtime serialization .ctor()
1510 data tables: [foo]DataTable foo { return this.table[foo]; }
1513 init variables on new dataset.
1515 *** protected members
1517 ShouldSerializeTables()
1518 returns false, while default DataSet returns true.
1519 ShouldSerializeRelations()
1520 returns false, while default DataSet returns true.
1522 ReadXmlSerializable() ... similar to runtime serialization
1525 GetSchemaSerializable()
1526 Write its schema to temporary MemoryStream
1527 Read XML schema from the stream
1529 *** internal members
1532 set member fields (tables, relations)
1533 call members' "init variables"
1536 set DataSetName, Prefix, Namespace, Locale, CaseSensitive, EnforceConstraints
1540 create FKC: new FKC([rel], new DataColumn [] {table[foo].[keyColumnName]Column}, new DataColumn [] {table[child].[childColName]Column}
1541 fill Rule properties.
1542 allocate relation[rel] and fill Nested, then Relations.Add()
1546 data tables: [foo]DataTable table[foo];
1548 data relations: DataRelation relation[rel];
1550 ShouldSerialize[foo]
1554 2. Custom DataTable classes for each DataTable
1556 This class is created under the dataset.
1558 *** internal members
1560 .ctor() : base("[foo]")
1566 DataColumn [bar]Column { return column[bar]; }
1569 fill each column fields
1573 int Count { rowcount }
1575 this [int index] { row [i]; }
1577 event [foo]RowChangedEventHandler [foo]RowChanged
1578 event [foo]RowChangedEventHandler [foo]RowChanging
1579 event [foo]RowChangedEventHandler [foo]RowDeleted
1580 event [foo]RowChangedEventHandler [foo]RowDeleting
1582 void Add[foo]Row ([foo]Row row) { Rows.Add (row); }
1584 [foo]Row Add[foo]Row ([columnType] [columnName])
1585 create new [foo]row.
1589 // non-relation-children are just created as column type
1590 // relation-children are typeof fooRow[]
1592 GetEnumerator() { Rows.GetEnumerator (); }
1594 override DataTable Clone()
1597 [foo]Row New[foo]Row()
1599 void Remove[foo]Row([foo]Row)
1601 //for each ChildRelations
1602 [bar]Row [] Get[foo_bar]Rows ()
1604 *** protected members
1606 override DataTable CreateInstance() { return new }
1608 override DataRow NewRowFromBuilder(DataRowBuilder)
1610 override Type GetRowType()
1612 override void OnRowChanged(DataRowChangedEventArgs)
1614 check this event [foo]RowChanged.
1616 override void OnRowChanging(DataRowChangedEventArgs)
1617 override void OnRowDeleted(DataRowChangedEventArgs)
1618 override void OnRowDeleting(DataRowChangedEventArgs)
1625 column[bar] = new DataColumn (...);
1629 DataColumn [bar]Column
1631 3. Custom DataRow classses
1638 get { try { } catch { throw StrongTypingException(); }
1639 set { this [[foo]Table.[bar]Column] = value; }
1642 IsNull ([foo]Table.[bar]Column);
1644 void Set[bar]Null ()
1646 if the table is parent of some relations
1648 public [child]Row [] Get[child]Rows()
1650 *** internal members
1652 .ctor(DataRowBuilder) : base.()
1657 [foo]DataTable table[foo]
1660 4. Custom DataRowChangeEvent classes
1665 DataRowAction eventAction
1669 .ctor([foo]Row row, DataRowAction action)
1673 DataRowAction Action
1677 5. public Table RowChangedEventHandler delegates
1679 [foo]RowChangedEventHandler(object, [foo]RowChangedEvent e)
1682 ======================================================== */