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.Data.Common;
41 using System.Collections;
43 using System.Globalization;
45 using System.CodeDom.Compiler;
46 using System.ComponentModel;
47 using System.Runtime.Serialization;
48 using System.Xml.Schema;
49 using System.Xml.Serialization;
50 using System.Reflection;
53 using Microsoft.CSharp;
59 #if DATACLASS_GENERATOR_STANDALONE
62 public static void Main (string [] args)
65 if (args.Length < 1) {
66 Console.WriteLine ("mono dsgentest.exe filename");
70 DataSet ds = new DataSet ();
71 ds.ReadXml (args [0]);
72 ICodeGenerator gen = new CSharpCodeProvider ().CreateGenerator ();
74 CodeNamespace cns = new CodeNamespace ("MyNamespace");
75 TextWriter tw = new StreamWriter (Path.ChangeExtension (args [0], ".ms.cs"), false, Encoding.Default);
76 TypedDataSetGenerator.Generate (ds, cns, gen);
77 gen.GenerateCodeFromNamespace (cns, tw, null);
80 cns = new CodeNamespace ("MyNamespace");
81 tw = new StreamWriter (Path.ChangeExtension (args [0], ".mono.cs"), false, Encoding.Default);
82 CustomDataClassGenerator.CreateDataSetClasses (ds, cns, gen, null);
83 gen.GenerateCodeFromNamespace (cns, tw, null);
85 } catch (Exception ex) {
86 Console.WriteLine (ex);
92 #if DATACLASS_GENERATOR_STANDALONE
93 public class CustomDataClassGenerator
95 internal class CustomDataClassGenerator
98 public static void CreateDataSetClasses (DataSet ds,
99 CodeNamespace cns, ICodeGenerator gen,
100 ClassGeneratorOptions options)
102 new Generator (ds, cns, gen, options).Run ();
106 public static void CreateDataSetClasses (DataSet ds,
107 CodeNamespace cns, CodeDomProvider codeProvider,
108 ClassGeneratorOptions options)
110 new Generator (ds, cns, codeProvider, options).Run ();
113 public static void CreateDataSetClasses (DataSet ds,
114 CodeCompileUnit cunit,
116 CodeDomProvider codeProvider,
117 ClassGeneratorOptions options)
119 new Generator (ds, cunit, cns, codeProvider, options).Run ();
122 public static string MakeSafeName (string name, ICodeGenerator codeGen)
124 if (name == null || codeGen == null)
125 throw new NullReferenceException ();
127 name = codeGen.CreateValidIdentifier (name);
129 return MakeSafeNameInternal (name);
133 public static string MakeSafeName (string name, CodeDomProvider provider)
135 if (name == null || provider == null)
136 throw new NullReferenceException ();
138 name = provider.CreateValidIdentifier (name);
140 return MakeSafeNameInternal (name);
144 public static string MakeSafeNameInternal (string name)
146 if (name.Length == 0)
149 StringBuilder sb = null;
150 if (!Char.IsLetter (name, 0) && name [0] != '_') {
151 sb = new StringBuilder ();
156 for (int i = 0; i < name.Length; i++) {
157 if (!Char.IsLetterOrDigit (name, i)) {
159 sb = new StringBuilder ();
160 sb.Append (name, start, i - start);
167 sb.Append (name, start, name.Length - start);
168 return sb.ToString ();
175 #if DATACLASS_GENERATOR_STANDALONE
176 public delegate string CodeNamingMethod (string source, ICodeGenerator gen);
178 internal delegate string CodeNamingMethod (string source, ICodeGenerator gen);
181 #if DATACLASS_GENERATOR_STANDALONE
182 public delegate string CodeDomNamingMethod (string source, CodeDomProvider provider);
184 internal delegate string CodeDomNamingMethod (string source, CodeDomProvider provider);
187 #if DATACLASS_GENERATOR_STANDALONE
188 public class ClassICodeGeneratorOptions : ClassGeneratorOptions
190 internal class ClassICodeGeneratorOptions : ClassGeneratorOptions
195 public CodeNamingMethod CreateDataSetName;
196 public CodeNamingMethod CreateTableTypeName;
197 public CodeNamingMethod CreateTableMemberName;
198 public CodeNamingMethod CreateTableColumnName;
199 public CodeNamingMethod CreateColumnName;
200 public CodeNamingMethod CreateRowName;
201 public CodeNamingMethod CreateRelationName;
202 public CodeNamingMethod CreateTableDelegateName;
203 public CodeNamingMethod CreateEventArgsName;
204 public CodeNamingMethod CreateTableAdapterNSName;
205 public CodeNamingMethod CreateTableAdapterName;
207 public ClassICodeGeneratorOptions (ICodeGenerator codeGen)
212 internal override string DataSetName (string source)
214 if (CreateDataSetName != null)
215 return CreateDataSetName (source, gen);
217 return CustomDataClassGenerator.MakeSafeName (source, gen);
220 internal override string TableTypeName (string source)
222 if (CreateTableTypeName != null)
223 return CreateTableTypeName (source, gen);
225 return CustomDataClassGenerator.MakeSafeName (source, gen) + "DataTable";
228 internal override string TableMemberName (string source)
230 if (CreateTableMemberName != null)
231 return CreateTableMemberName (source, gen);
233 return CustomDataClassGenerator.MakeSafeName (source, gen);
236 internal override string TableColName (string source)
238 if (CreateTableColumnName != null)
239 return CreateTableColumnName (source, gen);
241 return CustomDataClassGenerator.MakeSafeName (source, gen);
244 internal override string TableDelegateName (string source)
246 if (CreateTableDelegateName != null)
247 return CreateTableDelegateName (source, gen);
249 return CustomDataClassGenerator.MakeSafeName (source, gen) + "RowChangedEventHandler";
252 internal override string EventArgsName (string source)
254 if (CreateEventArgsName != null)
255 return CreateEventArgsName (source, gen);
257 return CustomDataClassGenerator.MakeSafeName (source, gen) + "RowChangedEventArgs";
260 internal override string ColumnName (string source)
262 if (CreateColumnName != null)
263 return CreateColumnName (source, gen);
265 return CustomDataClassGenerator.MakeSafeName (source, gen);
268 internal override string RowName (string source)
270 if (CreateRowName != null)
271 return CreateRowName (source, gen);
273 return CustomDataClassGenerator.MakeSafeName (source, gen) + "Row";
276 internal override string RelationName (string source)
278 if (CreateRelationName != null)
279 return CreateRelationName (source, gen);
281 return CustomDataClassGenerator.MakeSafeName (source, gen) + "Relation";
284 internal override string TableAdapterNSName (string source)
286 if (CreateTableAdapterNSName != null)
287 return CreateTableAdapterNSName (source, gen);
289 return CustomDataClassGenerator.MakeSafeName (source, gen) + "TableAdapters";
292 internal override string TableAdapterName (string source)
294 if (CreateTableAdapterName != null)
295 return CreateTableAdapterName (source, gen);
297 return CustomDataClassGenerator.MakeSafeName (source, gen);
302 #if DATACLASS_GENERATOR_STANDALONE
303 public class ClassCodeDomProviderOptions : ClassGeneratorOptions
305 internal class ClassCodeDomProviderOptions : ClassGeneratorOptions
308 CodeDomProvider provider;
310 public CodeDomNamingMethod CreateDataSetName;
311 public CodeDomNamingMethod CreateTableTypeName;
312 public CodeDomNamingMethod CreateTableMemberName;
313 public CodeDomNamingMethod CreateTableColumnName;
314 public CodeDomNamingMethod CreateColumnName;
315 public CodeDomNamingMethod CreateRowName;
316 public CodeDomNamingMethod CreateRelationName;
317 public CodeDomNamingMethod CreateTableDelegateName;
318 public CodeDomNamingMethod CreateEventArgsName;
319 public CodeDomNamingMethod CreateTableAdapterNSName;
320 public CodeDomNamingMethod CreateTableAdapterName;
322 public ClassCodeDomProviderOptions (CodeDomProvider codeProvider)
324 this.provider = codeProvider;
327 internal override string DataSetName (string source)
329 if (CreateDataSetName != null)
330 return CreateDataSetName (source, provider);
332 return CustomDataClassGenerator.MakeSafeName (source, provider);
335 internal override string TableTypeName (string source)
337 if (CreateTableTypeName != null)
338 return CreateTableTypeName (source, provider);
340 return CustomDataClassGenerator.MakeSafeName (source, provider) + "DataTable";
343 internal override string TableMemberName (string source)
345 if (CreateTableMemberName != null)
346 return CreateTableMemberName (source, provider);
348 return CustomDataClassGenerator.MakeSafeName (source, provider);
351 internal override string TableColName (string source)
353 if (CreateTableColumnName != null)
354 return CreateTableColumnName (source, provider);
356 return CustomDataClassGenerator.MakeSafeName (source, provider);
359 internal override string TableDelegateName (string source)
361 if (CreateTableDelegateName != null)
362 return CreateTableDelegateName (source, provider);
364 return CustomDataClassGenerator.MakeSafeName (source, provider) + "RowChangedEventHandler";
367 internal override string EventArgsName (string source)
369 if (CreateEventArgsName != null)
370 return CreateEventArgsName (source, provider);
372 return CustomDataClassGenerator.MakeSafeName (source, provider) + "RowChangedEventArgs";
375 internal override string ColumnName (string source)
377 if (CreateColumnName != null)
378 return CreateColumnName (source, provider);
380 return CustomDataClassGenerator.MakeSafeName (source, provider);
383 internal override string RowName (string source)
385 if (CreateRowName != null)
386 return CreateRowName (source, provider);
388 return CustomDataClassGenerator.MakeSafeName (source, provider) + "Row";
391 internal override string RelationName (string source)
393 if (CreateRelationName != null)
394 return CreateRelationName (source, provider);
396 return CustomDataClassGenerator.MakeSafeName (source, provider) + "Relation";
399 internal override string TableAdapterNSName (string source)
401 if (CreateTableAdapterNSName != null)
402 return CreateTableAdapterNSName (source, provider);
404 return CustomDataClassGenerator.MakeSafeName (source, provider) + "TableAdapters";
407 internal override string TableAdapterName (string source)
409 if (CreateTableAdapterName != null)
410 return CreateTableAdapterName (source, provider);
412 return CustomDataClassGenerator.MakeSafeName (source, provider);
417 #if DATACLASS_GENERATOR_STANDALONE
418 public abstract class ClassGeneratorOptions
420 internal abstract class ClassGeneratorOptions
423 public bool MakeClassesInsideDataSet = true; // default = MS compatible
425 internal abstract string DataSetName (string source);
426 internal abstract string TableTypeName (string source);
427 internal abstract string TableMemberName (string source);
428 internal abstract string TableColName (string source);
429 internal abstract string TableDelegateName (string source);
430 internal abstract string EventArgsName (string source);
431 internal abstract string ColumnName (string source);
432 internal abstract string RowName (string source);
433 internal abstract string RelationName (string source);
434 internal abstract string TableAdapterNSName (string source);
435 internal abstract string TableAdapterName (string source);
438 internal class Generator
440 // static ClassGeneratorOptions DefaultOptions = new ClassGeneratorOptions ();
444 ClassGeneratorOptions opts;
445 CodeCompileUnit cunit;
447 CodeTypeDeclaration dsType;
449 public Generator (DataSet ds, CodeNamespace cns, ICodeGenerator codeGen, ClassGeneratorOptions options)
456 opts = new ClassICodeGeneratorOptions (codeGen);
459 public Generator (DataSet ds, CodeNamespace cns, CodeDomProvider codeProvider,
460 ClassGeneratorOptions options)
467 opts = new ClassCodeDomProviderOptions (codeProvider);
470 public Generator (DataSet ds, CodeCompileUnit cunit, CodeNamespace cns,
471 CodeDomProvider codeProvider, ClassGeneratorOptions options)
478 opts = new ClassCodeDomProviderOptions (codeProvider);
484 cns.Imports.Add (new CodeNamespaceImport ("System"));
485 cns.Imports.Add (new CodeNamespaceImport ("System.Collections"));
486 cns.Imports.Add (new CodeNamespaceImport ("System.ComponentModel"));
487 cns.Imports.Add (new CodeNamespaceImport ("System.Data"));
488 cns.Imports.Add (new CodeNamespaceImport ("System.Runtime.Serialization"));
489 cns.Imports.Add (new CodeNamespaceImport ("System.Xml"));
492 CodeTypeDeclaration dsType = GenerateDataSetType ();
493 cns.Types.Add (dsType);
495 foreach (DataTable dt in ds.Tables) {
496 // 1. table types ([foo]DataTable)
497 // 2. row types ([foo]Row)
498 // 3. delegates ([foo]RowChangedEventHandler)
499 // 4. eventargs ([foo]RowChangeEventArgs)
501 CodeTypeDeclaration dtType = GenerateDataTableType (dt);
503 CodeTypeDeclaration dtRow = GenerateDataRowType (dt);
505 CodeTypeDelegate dtDelegate = new CodeTypeDelegate (opts.TableDelegateName (dt.TableName));
506 dtDelegate.Parameters.Add (Param (typeof (object), "o"));
507 dtDelegate.Parameters.Add (Param (opts.EventArgsName (dt.TableName), "e"));
509 CodeTypeDeclaration dtEventType = GenerateEventType (dt);
511 // Add types to either DataSet or CodeNamespace
512 if (opts.MakeClassesInsideDataSet) {
513 dsType.Members.Add (dtType);
514 dsType.Members.Add (dtRow);
515 dsType.Members.Add (dtDelegate);
516 dsType.Members.Add (dtEventType);
519 cns.Types.Add (dtType);
520 cns.Types.Add (dtRow);
521 cns.Types.Add (dtDelegate);
522 cns.Types.Add (dtEventType);
530 TableAdapterSchemaInfo adapterInfo = ds.TableAdapterSchemaData;
531 if (adapterInfo != null) {
533 //Console.WriteLine (opts.TableAdapterNSName(opts.DataSetName (ds.DataSetName)));
534 CodeNamespace cnsTA = new CodeNamespace (opts.TableAdapterNSName(opts.DataSetName (ds.DataSetName)));
535 CodeTypeDeclaration dtAdapter = GenerateTableAdapterType (adapterInfo);
536 cnsTA.Types.Add (dtAdapter);
537 cunit.Namespaces.Add (cnsTA);
542 private CodeThisReferenceExpression This ()
544 return new CodeThisReferenceExpression ();
547 private CodeBaseReferenceExpression Base ()
549 return new CodeBaseReferenceExpression ();
552 private CodePrimitiveExpression Const (object value)
554 return new CodePrimitiveExpression (value);
557 private CodeTypeReference TypeRef (Type t)
559 return new CodeTypeReference (t);
562 private CodeTypeReference TypeRef (string name)
564 return new CodeTypeReference (name);
567 private CodeTypeReference TypeRefArray (Type t, int dimension)
569 return new CodeTypeReference (TypeRef (t), dimension);
572 private CodeTypeReference TypeRefArray (string name, int dimension)
574 return new CodeTypeReference (TypeRef (name), dimension);
577 private CodeParameterDeclarationExpression Param (string t, string name)
579 return new CodeParameterDeclarationExpression (t, name);
582 private CodeParameterDeclarationExpression Param (Type t, string name)
584 return new CodeParameterDeclarationExpression (t, name);
587 private CodeParameterDeclarationExpression Param (CodeTypeReference t, string name)
589 return new CodeParameterDeclarationExpression (t, name);
592 private CodeArgumentReferenceExpression ParamRef (string name)
594 return new CodeArgumentReferenceExpression (name);
597 private CodeCastExpression Cast (string t, CodeExpression exp)
599 return new CodeCastExpression (t, exp);
602 private CodeCastExpression Cast (Type t, CodeExpression exp)
604 return new CodeCastExpression (t, exp);
607 private CodeCastExpression Cast (CodeTypeReference t, CodeExpression exp)
609 return new CodeCastExpression (t, exp);
612 private CodeExpression New (Type t, params CodeExpression [] parameters)
614 return new CodeObjectCreateExpression (t, parameters);
617 private CodeExpression New (string t, params CodeExpression [] parameters)
619 return new CodeObjectCreateExpression (TypeRef (t), parameters);
622 private CodeExpression NewArray (Type t, params CodeExpression [] parameters)
624 return new CodeArrayCreateExpression (t, parameters);
627 private CodeExpression NewArray (Type t, int size )
629 return new CodeArrayCreateExpression (t, size);
632 private CodeVariableReferenceExpression Local (string name)
634 return new CodeVariableReferenceExpression (name);
637 private CodeFieldReferenceExpression FieldRef (string name)
639 return new CodeFieldReferenceExpression (new CodeThisReferenceExpression (), name);
642 private CodeFieldReferenceExpression FieldRef (CodeExpression exp, string name)
644 return new CodeFieldReferenceExpression (exp, name);
647 private CodePropertyReferenceExpression PropRef (string name)
649 return new CodePropertyReferenceExpression (new CodeThisReferenceExpression (), name);
652 private CodePropertyReferenceExpression PropRef (CodeExpression target, string name)
654 return new CodePropertyReferenceExpression (target, name);
657 private CodeIndexerExpression IndexerRef (CodeExpression target, CodeExpression parameters)
659 return new CodeIndexerExpression (target, parameters);
662 private CodeIndexerExpression IndexerRef (CodeExpression param)
664 return new CodeIndexerExpression (new CodeThisReferenceExpression (), param);
667 private CodeEventReferenceExpression EventRef (string name)
669 return new CodeEventReferenceExpression (new CodeThisReferenceExpression (), name);
672 private CodeEventReferenceExpression EventRef (CodeExpression target, string name)
674 return new CodeEventReferenceExpression (target, name);
677 private CodeMethodInvokeExpression MethodInvoke (string name, params CodeExpression [] parameters)
679 return new CodeMethodInvokeExpression (new CodeThisReferenceExpression (), name, parameters);
682 private CodeMethodInvokeExpression MethodInvoke (CodeExpression target, string name, params CodeExpression [] parameters)
684 return new CodeMethodInvokeExpression (target, name, parameters);
687 private CodeBinaryOperatorExpression EqualsValue (CodeExpression exp1, CodeExpression exp2)
689 return new CodeBinaryOperatorExpression (exp1, CodeBinaryOperatorType.ValueEquality, exp2);
692 // note that this is "Identity" equality comparison
693 private CodeBinaryOperatorExpression Equals (CodeExpression exp1, CodeExpression exp2)
695 return new CodeBinaryOperatorExpression (exp1, CodeBinaryOperatorType.IdentityEquality, exp2);
698 private CodeBinaryOperatorExpression Inequals (CodeExpression exp1, CodeExpression exp2)
700 return new CodeBinaryOperatorExpression (exp1, CodeBinaryOperatorType.IdentityInequality, exp2);
703 private CodeBinaryOperatorExpression GreaterThan (CodeExpression exp1, CodeExpression exp2)
705 return new CodeBinaryOperatorExpression (exp1, CodeBinaryOperatorType.GreaterThan, exp2);
708 private CodeBinaryOperatorExpression LessThan (CodeExpression exp1, CodeExpression exp2)
710 return new CodeBinaryOperatorExpression (exp1, CodeBinaryOperatorType.LessThan, exp2);
713 private CodeBinaryOperatorExpression Compute (CodeExpression exp1, CodeExpression exp2, CodeBinaryOperatorType ops)
715 if (ops >= CodeBinaryOperatorType.Add && ops < CodeBinaryOperatorType.Assign)
716 return new CodeBinaryOperatorExpression (exp1, ops, exp2);
721 private CodeBinaryOperatorExpression BitOps (CodeExpression exp1, CodeExpression exp2, CodeBinaryOperatorType ops)
723 if (ops >= CodeBinaryOperatorType.BitwiseOr && ops <= CodeBinaryOperatorType.BitwiseAnd)
724 return new CodeBinaryOperatorExpression (exp1, ops, exp2);
729 private CodeBinaryOperatorExpression BooleanOps (CodeExpression exp1, CodeExpression exp2, CodeBinaryOperatorType ops)
731 if (ops >= CodeBinaryOperatorType.BooleanOr && ops <= CodeBinaryOperatorType.BooleanAnd)
732 return new CodeBinaryOperatorExpression (exp1, ops, exp2);
737 private CodeTypeReferenceExpression TypeRefExp (Type t)
739 return new CodeTypeReferenceExpression (t);
742 private CodeTypeOfExpression TypeOfRef (string name)
744 return new CodeTypeOfExpression (TypeRef (name));
747 private CodeExpressionStatement Eval (CodeExpression exp)
749 return new CodeExpressionStatement (exp);
752 private CodeAssignStatement Let (CodeExpression exp, CodeExpression value)
754 return new CodeAssignStatement (exp, value);
757 private CodeMethodReturnStatement Return (CodeExpression exp)
759 return new CodeMethodReturnStatement (exp);
762 private CodeVariableDeclarationStatement VarDecl (Type t,
763 string name, CodeExpression init)
765 return new CodeVariableDeclarationStatement (t, name, init);
768 private CodeVariableDeclarationStatement VarDecl (string t,
769 string name, CodeExpression init)
771 return new CodeVariableDeclarationStatement (t, name, init);
774 private CodeCommentStatement Comment (string comment)
776 return new CodeCommentStatement (comment);
779 private CodeThrowExceptionStatement Throw (CodeExpression exp)
781 return new CodeThrowExceptionStatement (exp);
784 #region DataSet class
786 private CodeTypeDeclaration GenerateDataSetType ()
789 dsType = new CodeTypeDeclaration (opts.DataSetName (ds.DataSetName));
790 dsType.BaseTypes.Add (TypeRef (typeof (DataSet)));
791 dsType.BaseTypes.Add (TypeRef (typeof (IXmlSerializable)));
794 dsType.Members.Add (CreateDataSetDefaultCtor ());
795 // runtime serialization .ctor()
796 dsType.Members.Add (CreateDataSetSerializationCtor ());
799 dsType.Members.Add (CreateDataSetCloneMethod (dsType));
801 // FIXME: I keep these methods out of the generated source right now.
802 // It should be added after runtime serialization was implemented.
804 // ShouldSerializeTables()
805 dsType.Members.Add (CreateDataSetShouldSerializeTables ());
807 // ShouldSerializeRelations()
808 dsType.Members.Add (CreateDataSetShouldSerializeRelations ());
810 // ReadXmlSerializable()
811 dsType.Members.Add (CreateDataSetReadXmlSerializable ());
814 // GetSchemaSerializable()
815 dsType.Members.Add (CreateDataSetGetSchemaSerializable ());
817 dsType.Members.Add (CreateDataSetGetSchema ());
818 dsType.Members.Add (CreateDataSetInitializeClass ());
819 dsType.Members.Add (CreateDataSetInitializeFields ());
820 dsType.Members.Add (CreateDataSetSchemaChanged ());
822 // table class and members
823 foreach (DataTable table in ds.Tables)
824 CreateDataSetTableMembers (dsType, table);
825 // relation class and members
826 foreach (DataRelation rel in ds.Relations)
827 CreateDataSetRelationMembers (dsType, rel);
835 // InitializeClass();
836 // CollectionChangeEventHandler handler = new CollectionChangeEventHandler (SchemaChanged);
837 // Tables.CollectionChanged += handler;
838 // Relations.CollectionChanged += handler;
840 private CodeConstructor CreateDataSetDefaultCtor ()
842 CodeConstructor ctor = new CodeConstructor ();
843 ctor.Attributes = MemberAttributes.Public;
844 // Code: InitializeClass().
845 ctor.Statements.Add (Eval (MethodInvoke ("InitializeClass")));
847 // Code: CollectionChangedEventHandler handler = new CollectionChangeEventHandler (SchemeChanged);
848 CodeVariableDeclarationStatement stmt2 =
850 typeof (CollectionChangeEventHandler),
853 typeof (CollectionChangeEventHandler),
854 new CodeDelegateCreateExpression (
855 new CodeTypeReference (typeof (CollectionChangeEventHandler)),
856 new CodeThisReferenceExpression (),
859 ctor.Statements.Add (stmt2);
861 // Code: Tables.CollectionChanged += handler;
862 ctor.Statements.Add (
863 new CodeAttachEventStatement (
866 "CollectionChanged"),
869 // Code: Relations.CollectionChanged += handler;
870 ctor.Statements.Add (
871 new CodeAttachEventStatement (
873 PropRef ("Relations"),
874 "CollectionChanged"),
883 // protected Foo (SerializationInfo info, StreamingContext ctx)
885 // throw new NotImplementedException ();
887 private CodeConstructor CreateDataSetSerializationCtor ()
889 CodeConstructor ctor = new CodeConstructor ();
890 ctor.Attributes = MemberAttributes.Family;
891 ctor.Parameters.Add (Param (typeof (SerializationInfo), "info"));
892 ctor.Parameters.Add (Param (typeof (StreamingContext), "ctx"));
895 // // TODO: implement
896 // throw new NotImplementedException ();
897 ctor.Statements.Add (Comment ("TODO: implement"));
898 ctor.Statements.Add (Throw (New (typeof (NotImplementedException))));
904 // public override DataSet Clone()
906 // [foo] set = ([foo]) base.Clone ();
907 // set.InitializeFields ();
910 private CodeMemberMethod CreateDataSetCloneMethod (CodeTypeDeclaration dsType)
912 CodeMemberMethod m = new CodeMemberMethod ();
913 m.ReturnType = TypeRef (typeof (DataSet));
914 m.Attributes = MemberAttributes.Public | MemberAttributes.Override;
916 // Code: [foo] set = ([foo]) base.Clone ();
917 CodeVariableReferenceExpression set = Local ("set");
918 m.Statements.Add (VarDecl (
923 MethodInvoke (Base (), "Clone"))));
924 m.Statements.Add (Eval (MethodInvoke (set, "InitializeFields")));
925 m.Statements.Add (Return (set));
930 // protected override bool ShouldSerializeTables ()
932 // return true; // it should be false
935 private CodeMemberMethod CreateDataSetShouldSerializeTables ()
937 CodeMemberMethod m = new CodeMemberMethod ();
938 m.Name = "ShouldSerializeTables";
939 m.ReturnType = TypeRef (typeof (bool));
940 m.Attributes = MemberAttributes.Family | MemberAttributes.Override;
941 // FIXME: set "false" after serialization .ctor() implementation
942 m.Statements.Add (Return (Const (true)));
947 // protected override bool ShouldSerializeRelations ()
949 // return true; // it should be false
953 private CodeMemberMethod CreateDataSetShouldSerializeRelations ()
955 CodeMemberMethod m = new CodeMemberMethod ();
956 m.Name = "ShouldSerializeRelations";
957 m.ReturnType = TypeRef (typeof (bool));
958 m.Attributes = MemberAttributes.Family | MemberAttributes.Override;
959 // FIXME: set "false" after serialization .ctor() implementation
960 m.Statements.Add (Return (Const (true)));
966 // protected override void ReadXmlSerializable()
968 // // TODO: implement
969 // throw new NotImplementedException ();
972 private CodeMemberMethod CreateDataSetReadXmlSerializable ()
974 CodeMemberMethod method = new CodeMemberMethod ();
975 method.Name = "ReadXmlSerializable";
976 method.Attributes = MemberAttributes.Family | MemberAttributes.Override;
977 method.Parameters.Add (Param (TypeRef (typeof (XmlReader)), "reader"));
979 method.Statements.Add (Comment ("TODO: implement"));
980 // Hey, how can I specify the constructor to invoke chained ctor with an empty parameter list!?
981 method.Statements.Add (Throw (New (typeof (NotImplementedException))));
986 private CodeMemberMethod CreateDataSetGetSchema ()
988 CodeMemberMethod m = new CodeMemberMethod ();
989 m.PrivateImplementationType = TypeRef (typeof (IXmlSerializable));
990 m.Name = "GetSchema";
991 m.ReturnType = TypeRef (typeof (XmlSchema));
992 m.Statements.Add (Return (MethodInvoke ("GetSchemaSerializable")));
997 private CodeMemberMethod CreateDataSetGetSchemaSerializable ()
999 CodeMemberMethod m = new CodeMemberMethod ();
1000 m.Attributes = MemberAttributes.Family |
1001 MemberAttributes.Override;
1002 m.Name = "GetSchemaSerializable";
1003 m.ReturnType = TypeRef (typeof (XmlSchema));
1005 m.Statements.Add (VarDecl (typeof (StringWriter), "sw",
1006 New (typeof (StringWriter))));
1007 m.Statements.Add (Eval (MethodInvoke ("WriteXmlSchema", Local ("sw"))));
1008 m.Statements.Add (Return (MethodInvoke (
1009 TypeRefExp (typeof (XmlSchema)),
1011 New (typeof (XmlTextReader),
1012 New (typeof (StringReader),
1013 MethodInvoke (Local ("sw"),
1020 private CodeMemberMethod CreateDataSetInitializeClass ()
1022 CodeMemberMethod m = new CodeMemberMethod ();
1023 m.Name = "InitializeClass";
1024 m.Attributes = MemberAttributes.Assembly;
1026 // dataset properties
1027 m.Statements.Add (Let (PropRef ("DataSetName"), Const (ds.DataSetName)));
1028 m.Statements.Add (Let (PropRef ("Prefix"), Const (ds.Prefix)));
1029 m.Statements.Add (Let (PropRef ("Namespace"), Const (ds.Namespace)));
1030 m.Statements.Add (Let (PropRef ("Locale"), New (typeof (CultureInfo), Const (ds.Locale.Name))));
1031 m.Statements.Add (Let (PropRef ("CaseSensitive"), Const (ds.CaseSensitive)));
1032 m.Statements.Add (Let (PropRef ("EnforceConstraints"), Const (ds.EnforceConstraints)));
1035 foreach (DataTable dt in ds.Tables) {
1036 string tableFieldName = "__table" + opts.TableMemberName (dt.TableName);
1037 string tableTypeName = opts.TableTypeName (dt.TableName);
1038 m.Statements.Add (Let (FieldRef (tableFieldName), New (tableTypeName)));
1039 m.Statements.Add (Eval (MethodInvoke (PropRef ("Tables"), "Add", FieldRef (tableFieldName))));
1042 bool fkcExists = false;
1043 bool ucExists = false;
1044 // First the UniqueConstraints
1045 foreach (DataTable dt in ds.Tables) {
1046 string tname = "__table" + opts.TableMemberName (dt.TableName);
1047 foreach (Constraint c in dt.Constraints) {
1048 UniqueConstraint uc = c as UniqueConstraint;
1051 m.Statements.Add (VarDecl (typeof (UniqueConstraint), "uc", null));
1054 CreateUniqueKeyStatements (m, uc, tname);
1058 // Then the ForeignKeyConstraints
1059 foreach (DataTable dt in ds.Tables) {
1060 string tname = "__table" + opts.TableMemberName (dt.TableName);
1061 foreach (Constraint c in dt.Constraints) {
1062 ForeignKeyConstraint fkc = c as ForeignKeyConstraint;
1065 m.Statements.Add (VarDecl (typeof (ForeignKeyConstraint), "fkc", null));
1068 string rtname = "__table" + opts.TableMemberName (fkc.RelatedTable.TableName);
1069 CreateForeignKeyStatements (m, fkc, tname, rtname);
1073 // What if other cases? dunno. Just ignore ;-)
1074 foreach (DataRelation rel in ds.Relations) {
1075 string relName = opts.RelationName (rel.RelationName);
1076 ArrayList pcols = new ArrayList ();
1077 foreach (DataColumn pcol in rel.ParentColumns)
1078 pcols.Add (IndexerRef (PropRef (FieldRef ("__table" + opts.TableMemberName (rel.ParentTable.TableName)), "Columns"), Const (pcol.ColumnName)));
1080 ArrayList ccols = new ArrayList ();
1081 foreach (DataColumn ccol in rel.ChildColumns)
1082 ccols.Add (IndexerRef (PropRef (FieldRef ("__table" + opts.TableMemberName (rel.ChildTable.TableName)), "Columns"), Const (ccol.ColumnName)));
1085 string fieldName = "__relation" + relName;
1086 m.Statements.Add (Let (FieldRef (fieldName), New (typeof (DataRelation),
1087 Const (rel.RelationName),
1088 NewArray (typeof (DataColumn), pcols.ToArray (typeof (CodeExpression)) as CodeExpression []),
1089 NewArray (typeof (DataColumn), ccols.ToArray (typeof (CodeExpression)) as CodeExpression []),
1092 m.Statements.Add (Let (PropRef (FieldRef (fieldName), "Nested"), Const (rel.Nested)));
1093 m.Statements.Add (MethodInvoke (PropRef ("Relations"), "Add", FieldRef (fieldName)));
1099 private void CreateUniqueKeyStatements (CodeMemberMethod m, UniqueConstraint uc, string tableField)
1101 ArrayList al = new ArrayList ();
1102 foreach (DataColumn col in uc.Columns)
1103 al.Add (IndexerRef (PropRef (FieldRef (tableField), "Columns"), Const (col.ColumnName)));
1105 m.Statements.Add (Let (Local ("uc"), New (
1106 typeof (UniqueConstraint),
1107 Const (uc.ConstraintName),
1109 typeof (DataColumn),
1110 al.ToArray (typeof (CodeExpression)) as CodeExpression []),
1111 Const (uc.IsPrimaryKey))));
1112 m.Statements.Add (MethodInvoke (PropRef (FieldRef (tableField), "Constraints"), "Add", Local ("uc")));
1115 private void CreateForeignKeyStatements (CodeMemberMethod m,ForeignKeyConstraint fkc, string tableField, string rtableField)
1117 ArrayList pcols = new ArrayList ();
1118 foreach (DataColumn col in fkc.RelatedColumns)
1119 pcols.Add (IndexerRef (PropRef (FieldRef (rtableField), "Columns"), Const (col.ColumnName)));
1121 ArrayList ccols = new ArrayList ();
1122 foreach (DataColumn col in fkc.Columns)
1123 ccols.Add (IndexerRef (PropRef (FieldRef (tableField), "Columns"), Const (col.ColumnName)));
1125 m.Statements.Add (Let (Local ("fkc"), New (
1126 typeof (ForeignKeyConstraint),
1127 Const (fkc.ConstraintName),
1129 typeof (DataColumn),
1130 pcols.ToArray (typeof (CodeExpression)) as CodeExpression []),
1132 typeof (DataColumn),
1133 ccols.ToArray (typeof (CodeExpression)) as CodeExpression []))));
1135 m.Statements.Add (Let (
1136 PropRef (Local ("fkc"), "AcceptRejectRule"),
1137 FieldRef (TypeRefExp (typeof (AcceptRejectRule)), Enum.GetName (typeof (AcceptRejectRule), fkc.AcceptRejectRule))));
1138 m.Statements.Add (Let (
1139 PropRef (Local ("fkc"), "DeleteRule"),
1140 FieldRef (TypeRefExp (typeof (Rule)), Enum.GetName (typeof (Rule), fkc.DeleteRule))));
1141 m.Statements.Add (Let (
1142 PropRef (Local ("fkc"), "UpdateRule"),
1143 FieldRef (TypeRefExp (typeof (Rule)), Enum.GetName (typeof (Rule), fkc.UpdateRule))));
1145 m.Statements.Add (MethodInvoke (PropRef (FieldRef (tableField), "Constraints"), "Add", Local ("fkc")));
1148 private CodeMemberMethod CreateDataSetInitializeFields ()
1150 CodeMemberMethod m = new CodeMemberMethod ();
1151 m.Attributes = MemberAttributes.Assembly;
1152 m.Name = "InitializeFields";
1154 foreach (DataTable dt in ds.Tables)
1155 m.Statements.Add (Eval (MethodInvoke (FieldRef ("__table" + opts.TableMemberName (dt.TableName)), "InitializeFields")));
1157 foreach (DataRelation rel in ds.Relations)
1158 m.Statements.Add (Let (FieldRef ("__relation" + opts.RelationName (rel.RelationName)), IndexerRef (PropRef ("Relations"), Const (rel.RelationName))));
1163 private CodeMemberMethod CreateDataSetSchemaChanged ()
1165 CodeMemberMethod m = new CodeMemberMethod ();
1166 m.Name = "SchemaChanged";
1167 m.Parameters.Add (Param (typeof (object), "sender"));
1168 m.Parameters.Add (Param (typeof (CollectionChangeEventArgs), "e"));
1171 new CodeConditionStatement (
1173 PropRef (ParamRef ("e"), "Action"),
1174 FieldRef (TypeRefExp (typeof (CollectionChangeAction)), "Remove")),
1175 new CodeStatement [] { Eval (MethodInvoke ("InitializeFields")) },
1176 new CodeStatement [] {}));
1180 private void CreateDataSetTableMembers (CodeTypeDeclaration dsType, DataTable table)
1182 string tableTypeName = opts.TableTypeName (table.TableName);
1183 string tableVarName = opts.TableMemberName (table.TableName);
1185 CodeMemberField privTable = new CodeMemberField ();
1186 privTable.Type = TypeRef (tableTypeName);
1187 privTable.Name = "__table" + tableVarName;
1188 dsType.Members.Add (privTable);
1190 CodeMemberProperty pubTable = new CodeMemberProperty ();
1191 pubTable.Type = TypeRef (tableTypeName);
1192 pubTable.Attributes = MemberAttributes.Public;
1193 pubTable.Name = tableVarName == table.TableName ? "_"+tableVarName : tableVarName;
1194 pubTable.HasSet = false;
1195 // Code: return __table[foo];
1196 pubTable.GetStatements.Add (Return (FieldRef ("__table" + tableVarName)));
1198 dsType.Members.Add (pubTable);
1202 private void CreateDataSetRelationMembers (CodeTypeDeclaration dsType, DataRelation relation)
1204 string relName = opts.RelationName (relation.RelationName);
1205 string fieldName = "__relation" + relName;
1207 CodeMemberField field = new CodeMemberField ();
1208 field.Type = TypeRef (typeof (DataRelation));
1209 field.Name = fieldName;
1210 dsType.Members.Add (field);
1212 // This is not supported in MS.NET
1213 CodeMemberProperty prop = new CodeMemberProperty ();
1214 prop.Type = TypeRef (typeof (DataRelation));
1215 prop.Attributes = MemberAttributes.Public;
1216 prop.Name = relName;
1217 prop.HasSet = false;
1218 // Code: return __relation[foo_bar];
1219 prop.GetStatements.Add (Return (FieldRef (fieldName)));
1220 dsType.Members.Add (prop);
1227 #region DataTable class
1229 private CodeTypeDeclaration GenerateDataTableType (DataTable dt)
1231 CodeTypeDeclaration t = new CodeTypeDeclaration ();
1232 t.Name = opts.TableTypeName (dt.TableName);
1233 t.BaseTypes.Add (TypeRef (typeof (DataTable)));
1234 t.BaseTypes.Add (TypeRef (typeof (IEnumerable)));
1236 t.Members.Add (CreateTableCtor1 (dt));
1237 t.Members.Add (CreateTableCtor2 (dt));
1239 t.Members.Add (CreateTableCount (dt));
1240 t.Members.Add (CreateTableIndexer (dt));
1242 t.Members.Add (CreateTableInitializeClass (dt));
1243 t.Members.Add (CreateTableInitializeFields (dt));
1245 t.Members.Add (CreateTableGetEnumerator (dt));
1246 t.Members.Add (CreateTableClone (dt));
1247 t.Members.Add (CreateTableCreateInstance (dt));
1249 t.Members.Add (CreateTableAddRow1 (dt));
1250 t.Members.Add (CreateTableAddRow2 (dt));
1251 t.Members.Add (CreateTableNewRow (dt));
1252 t.Members.Add (CreateTableNewRowFromBuilder (dt));
1253 t.Members.Add (CreateTableRemoveRow (dt));
1254 t.Members.Add (CreateTableGetRowType (dt));
1256 t.Members.Add (CreateTableEventStarter (dt, "Changing"));
1257 t.Members.Add (CreateTableEventStarter (dt, "Changed"));
1258 t.Members.Add (CreateTableEventStarter (dt, "Deleting"));
1259 t.Members.Add (CreateTableEventStarter (dt, "Deleted"));
1262 t.Members.Add (CreateTableEvent (dt, "RowChanging"));
1263 t.Members.Add (CreateTableEvent (dt, "RowChanged"));
1264 t.Members.Add (CreateTableEvent (dt, "RowDeleting"));
1265 t.Members.Add (CreateTableEvent (dt, "RowDeleted"));
1268 foreach (DataColumn col in dt.Columns) {
1269 t.Members.Add (CreateTableColumnField (dt, col));
1270 t.Members.Add (CreateTableColumnProperty (dt, col));
1277 // internal [foo]DataTable () : base ("[foo]")
1279 // InitializeClass ();
1281 private CodeConstructor CreateTableCtor1 (DataTable dt)
1283 CodeConstructor c = new CodeConstructor ();
1284 c.Attributes = MemberAttributes.Assembly;
1285 c.BaseConstructorArgs.Add (Const (dt.TableName));
1286 c.Statements.Add (Eval (MethodInvoke ("InitializeClass")));
1287 c.Statements.Add (Eval (MethodInvoke ("InitializeFields")));
1292 // internal [foo]DataTable (DataTable table) : base (table.TableName)
1294 // // TODO: implement
1295 // throw new NotImplementedException ();
1297 private CodeConstructor CreateTableCtor2 (DataTable dt)
1299 CodeConstructor c = new CodeConstructor ();
1300 c.Attributes = MemberAttributes.Assembly;
1301 c.Parameters.Add (Param (typeof (DataTable), GetRowTableFieldName (dt)));
1302 c.BaseConstructorArgs.Add (PropRef (ParamRef (GetRowTableFieldName (dt)), "TableName"));
1304 c.Statements.Add (Comment ("TODO: implement"));
1305 c.Statements.Add (Throw (New (typeof (NotImplementedException))));
1309 private CodeMemberMethod CreateTableInitializeClass (DataTable dt)
1311 CodeMemberMethod m = new CodeMemberMethod ();
1312 m.Name = "InitializeClass";
1313 foreach (DataColumn col in dt.Columns) {
1314 m.Statements.Add (Eval (MethodInvoke (
1315 PropRef ("Columns"),
1317 New (typeof (DataColumn),
1318 Const (col.ColumnName),
1319 new CodeTypeOfExpression (col.DataType)
1325 private CodeMemberMethod CreateTableInitializeFields (DataTable dt)
1327 CodeMemberMethod m = new CodeMemberMethod ();
1328 m.Name = "InitializeFields";
1329 m.Attributes = MemberAttributes.Assembly;
1332 foreach (DataColumn col in dt.Columns) {
1333 colRef = String.Format("__column{0}", opts.TableColName (col.ColumnName));
1335 m.Statements.Add (Let (FieldRef (colRef), IndexerRef (PropRef ("Columns"), Const (col.ColumnName))));
1336 if (!col.AllowDBNull)
1337 m.Statements.Add (Let (FieldRef (PropRef (colRef), "AllowDBNull"), Const (col.AllowDBNull)));
1338 if (col.DefaultValue != null && col.DefaultValue.GetType() != typeof(System.DBNull))
1339 m.Statements.Add (Let (FieldRef (PropRef (colRef), "DefaultValue"), Const (col.DefaultValue)));
1340 if (col.AutoIncrement)
1341 m.Statements.Add (Let (FieldRef (PropRef (colRef), "AutoIncrement"), Const (col.AutoIncrement)));
1342 if (col.AutoIncrementSeed != 0)
1343 m.Statements.Add (Let (FieldRef (PropRef (colRef), "AutoIncrementSeed"), Const (col.AutoIncrementSeed)));
1344 if (col.AutoIncrementStep != 1)
1345 m.Statements.Add (Let (FieldRef (PropRef (colRef), "AutoIncrementStep"), Const (col.AutoIncrementStep)));
1347 m.Statements.Add (Let (FieldRef (PropRef (colRef), "ReadOnly"), Const (col.ReadOnly)));
1352 private CodeMemberMethod CreateTableClone (DataTable dt)
1354 CodeMemberMethod m = new CodeMemberMethod ();
1356 m.Attributes = MemberAttributes.Public | MemberAttributes.Override;
1357 m.ReturnType = TypeRef (typeof (DataTable));
1358 string typeName = opts.TableTypeName (dt.TableName);
1360 VarDecl (typeName, "t", Cast (typeName, MethodInvoke (Base (), "Clone"))));
1361 m.Statements.Add (Eval (MethodInvoke (Local ("t"), "InitializeFields")));
1362 m.Statements.Add (Return (Local ("t")));
1366 private CodeMemberMethod CreateTableGetEnumerator (DataTable dt)
1368 CodeMemberMethod m = new CodeMemberMethod ();
1369 m.Name = "GetEnumerator";
1370 m.Attributes = MemberAttributes.Public;
1371 m.ReturnType = TypeRef (typeof (IEnumerator));
1372 m.Statements.Add (Return (MethodInvoke (PropRef ("Rows"), "GetEnumerator")));
1373 m.ImplementationTypes.Add (TypeRef (typeof (IEnumerable)));
1377 private CodeMemberMethod CreateTableCreateInstance (DataTable dt)
1379 CodeMemberMethod m = new CodeMemberMethod ();
1380 m.Name = "CreateInstance";
1381 m.Attributes = MemberAttributes.Family | MemberAttributes.Override;
1382 m.ReturnType = TypeRef (typeof (DataTable));
1383 m.Statements.Add (Return (New (opts.TableTypeName (dt.TableName))));
1387 private CodeMemberField CreateTableColumnField (DataTable dt, DataColumn col)
1389 CodeMemberField f = new CodeMemberField ();
1390 f.Name = "__column" + opts.ColumnName (col.ColumnName);
1391 f.Type = TypeRef (typeof (DataColumn));
1395 private CodeMemberProperty CreateTableColumnProperty (DataTable dt, DataColumn col)
1397 string name = opts.ColumnName (col.ColumnName);
1398 CodeMemberProperty p = new CodeMemberProperty ();
1399 p.Name = name + "Column";
1400 p.Attributes = MemberAttributes.Assembly;
1401 p.Type = TypeRef (typeof (DataColumn));
1403 p.GetStatements.Add (Return (FieldRef ("__column" + name)));
1407 private CodeMemberProperty CreateTableCount (DataTable dt)
1409 CodeMemberProperty p = new CodeMemberProperty ();
1411 p.Attributes = MemberAttributes.Public;
1412 p.Type = TypeRef (typeof (int));
1414 p.GetStatements.Add (Return (PropRef (PropRef ("Rows"), "Count")));
1418 private CodeMemberProperty CreateTableIndexer (DataTable dt)
1420 string rowName = opts.RowName (dt.TableName);
1421 CodeMemberProperty ix = new CodeMemberProperty ();
1422 ix.Name = "Item"; // indexer
1423 ix.Attributes = MemberAttributes.Public;
1424 ix.Type = TypeRef (rowName);
1425 ix.Parameters.Add (Param (typeof (int), "i"));
1427 ix.GetStatements.Add (Return (Cast (rowName, IndexerRef (PropRef ("Rows"), ParamRef ("i")))));
1431 private CodeMemberMethod CreateTableAddRow1 (DataTable dt)
1433 CodeMemberMethod m = new CodeMemberMethod ();
1434 string rowType = opts.RowName (dt.TableName);
1435 m.Name = "Add" + rowType;
1436 m.Attributes = MemberAttributes.Public;
1437 m.Parameters.Add (Param (TypeRef (rowType), "row"));
1438 m.Statements.Add (Eval (MethodInvoke (PropRef ("Rows"), "Add", ParamRef ("row"))));
1442 private CodeMemberMethod CreateTableAddRow2 (DataTable dt)
1444 CodeMemberMethod m = new CodeMemberMethod ();
1445 string rowType = opts.RowName (dt.TableName);
1446 m.Name = "Add" + rowType;
1447 m.ReturnType = TypeRef (rowType);
1448 m.Attributes = MemberAttributes.Public;
1450 m.Statements.Add (VarDecl (rowType, "row", MethodInvoke ("New" + rowType)));
1452 foreach (DataColumn col in dt.Columns) {
1453 if (col.ColumnMapping == MappingType.Hidden) {
1454 foreach (DataRelation r in dt.DataSet.Relations) {
1455 if (r.ChildTable == dt) {
1457 string paramType = opts.RowName (r.ParentTable.TableName);
1458 string paramName = paramType;
1459 m.Parameters.Add (Param (paramType, paramName));
1460 // CODE: SetParentRow (fooRow, DataSet.Relations ["foo_bar"]);
1461 m.Statements.Add (Eval (MethodInvoke (Local ("row"), "SetParentRow", ParamRef (paramName), IndexerRef (PropRef (PropRef ("DataSet"), "Relations"), Const (r.RelationName)))));
1468 string paramName = opts.ColumnName (col.ColumnName);
1469 m.Parameters.Add (Param (col.DataType, paramName));
1470 // row ["foo"] = foo;
1471 m.Statements.Add (Let (IndexerRef (Local ("row"), Const (paramName)), ParamRef (paramName)));
1476 m.Statements.Add (MethodInvoke (PropRef ("Rows"), "Add", Local ("row")));
1477 m.Statements.Add (Return (Local ("row")));
1482 private CodeMemberMethod CreateTableNewRow (DataTable dt)
1484 CodeMemberMethod m = new CodeMemberMethod ();
1485 string rowType = opts.RowName (dt.TableName);
1486 m.Name = "New" + rowType;
1487 m.ReturnType = TypeRef (rowType);
1488 m.Attributes = MemberAttributes.Public;
1489 m.Statements.Add (Return (Cast (rowType, MethodInvoke ("NewRow"))));
1493 private CodeMemberMethod CreateTableNewRowFromBuilder (DataTable dt)
1495 CodeMemberMethod m = new CodeMemberMethod ();
1496 m.Name = "NewRowFromBuilder";
1497 m.Attributes = MemberAttributes.Family | MemberAttributes.Override;
1498 m.ReturnType = TypeRef (typeof (DataRow));
1499 m.Parameters.Add (Param (typeof (DataRowBuilder), "builder"));
1500 m.Statements.Add (Return (New (opts.RowName (dt.TableName), ParamRef ("builder"))));
1504 private CodeMemberMethod CreateTableRemoveRow (DataTable dt)
1506 CodeMemberMethod m = new CodeMemberMethod ();
1507 string rowType = opts.RowName (dt.TableName);
1508 m.Name = "Remove" + rowType;
1509 m.Attributes = MemberAttributes.Public;
1510 m.Parameters.Add (Param (TypeRef (rowType), "row"));
1511 m.Statements.Add (Eval (MethodInvoke (PropRef ("Rows"), "Remove", ParamRef ("row"))));
1515 private CodeMemberMethod CreateTableGetRowType (DataTable dt)
1517 CodeMemberMethod m = new CodeMemberMethod ();
1518 m.Name = "GetRowType";
1519 m.Attributes = MemberAttributes.Family | MemberAttributes.Override;
1520 m.ReturnType = TypeRef (typeof (Type));
1521 m.Statements.Add (Return (new CodeTypeOfExpression (opts.RowName (dt.TableName))));
1525 private CodeMemberMethod CreateTableEventStarter (DataTable dt, string type)
1527 CodeMemberMethod m = new CodeMemberMethod ();
1528 m.Name = "OnRow" + type;
1529 m.Attributes = MemberAttributes.Family | MemberAttributes.Override;
1530 m.Parameters.Add (Param (typeof (DataRowChangeEventArgs), "e"));
1532 m.Statements.Add (Eval (MethodInvoke (
1536 string eventName = opts.TableMemberName (dt.TableName) + "Row" + type;
1537 CodeStatement trueStmt = Eval (
1538 new CodeDelegateInvokeExpression(
1539 new CodeEventReferenceExpression (This (), eventName),
1542 opts.EventArgsName (dt.TableName),
1543 Cast (opts.RowName (dt.TableName), PropRef (ParamRef ("e"), "Row")),
1544 PropRef (ParamRef ("e"), "Action"))));
1547 new CodeConditionStatement (
1548 Inequals (EventRef (eventName), Const (null)),
1549 new CodeStatement [] {trueStmt},
1550 new CodeStatement [] {}));
1555 private CodeMemberEvent CreateTableEvent (DataTable dt, string nameSuffix)
1557 CodeMemberEvent cme = new CodeMemberEvent ();
1558 cme.Attributes = MemberAttributes.Public;
1559 cme.Name = opts.TableMemberName (dt.TableName) + nameSuffix;
1560 cme.Type = TypeRef (opts.TableDelegateName (dt.TableName));
1570 public CodeTypeDeclaration GenerateDataRowType (DataTable dt)
1572 CodeTypeDeclaration t = new CodeTypeDeclaration ();
1573 t.Name = opts.RowName (dt.TableName);
1574 t.BaseTypes.Add (TypeRef (typeof (DataRow)));
1576 t.Members.Add (CreateRowCtor (dt));
1578 t.Members.Add (CreateRowTableField (dt));
1580 foreach (DataColumn col in dt.Columns) {
1581 if (col.ColumnMapping != MappingType.Hidden) {
1582 t.Members.Add (CreateRowColumnProperty (dt, col));
1583 t.Members.Add (CreateRowColumnIsNull (dt, col));
1584 t.Members.Add (CreateRowColumnSetNull (dt, col));
1588 foreach (DataRelation rel in dt.ParentRelations)
1589 t.Members.Add (CreateRowParentRowProperty (dt, rel));
1590 foreach (DataRelation rel in dt.ChildRelations)
1591 t.Members.Add (CreateRowGetChildRows (dt, rel));
1596 private CodeConstructor CreateRowCtor (DataTable dt)
1598 CodeConstructor c = new CodeConstructor ();
1599 c.Attributes = MemberAttributes.Assembly;
1600 c.Parameters.Add (Param (typeof (DataRowBuilder), "builder"));
1601 c.BaseConstructorArgs.Add (ParamRef ("builder"));
1602 c.Statements.Add (Let (FieldRef (GetRowTableFieldName (dt)), Cast (
1603 opts.TableTypeName (dt.TableName),
1604 PropRef ("Table"))));
1608 private string GetRowTableFieldName (DataTable dt)
1610 return "table" + dt.TableName;
1612 private CodeMemberField CreateRowTableField (DataTable dt)
1614 CodeMemberField f = new CodeMemberField ();
1615 f.Name = GetRowTableFieldName (dt);
1616 f.Type = TypeRef (opts.TableTypeName (dt.TableName));
1620 private CodeMemberProperty CreateRowColumnProperty (DataTable dt, DataColumn col)
1622 CodeMemberProperty p = new CodeMemberProperty ();
1623 p.Name = opts.ColumnName (col.ColumnName);
1624 p.Type = TypeRef (col.DataType);
1625 p.Attributes = MemberAttributes.Public;
1627 // This part should be better than MS code output.
1629 // object ret = this [col];
1630 // if (ret == DBNull.Value)
1631 // throw new StrongTypingException ()
1633 // return (type) ret;
1634 p.GetStatements.Add (VarDecl (typeof (object), "ret",
1636 (PropRef (GetRowTableFieldName (dt)),
1637 opts.TableColName (col.ColumnName) + "Column"))));
1638 p.GetStatements.Add (new CodeConditionStatement (
1641 PropRef (TypeRefExp (typeof (DBNull)), "Value")),
1642 new CodeStatement [] {
1643 Throw (New (typeof (StrongTypingException), Const ("Cannot get strong typed value since it is DB null."), Const (null))) },
1644 new CodeStatement [] {
1645 Return (Cast (col.DataType, Local ("ret"))) }));
1647 p.SetStatements.Add (Let (IndexerRef (PropRef (PropRef (GetRowTableFieldName (dt)), opts.TableColName (col.ColumnName) + "Column")), new CodePropertySetValueReferenceExpression ()));
1652 private CodeMemberMethod CreateRowColumnIsNull (DataTable dt, DataColumn col)
1654 CodeMemberMethod m = new CodeMemberMethod ();
1655 m.Name = "Is" + opts.ColumnName (col.ColumnName) + "Null";
1656 m.Attributes = MemberAttributes.Public;
1657 m.ReturnType = TypeRef (typeof (bool));
1658 m.Statements.Add (Return (MethodInvoke (
1660 // table[foo].[bar]Column
1662 PropRef (GetRowTableFieldName (dt)),
1663 opts.TableColName (col.ColumnName) + "Column"))));
1667 private CodeMemberMethod CreateRowColumnSetNull (DataTable dt, DataColumn col)
1669 CodeMemberMethod m = new CodeMemberMethod ();
1670 m.Name = "Set" + opts.ColumnName (col.ColumnName) + "Null";
1671 m.Attributes = MemberAttributes.Public;
1672 m.Statements.Add (Let (IndexerRef (
1674 PropRef (GetRowTableFieldName (dt)),
1675 opts.TableColName (col.ColumnName) + "Column")),
1676 PropRef (TypeRefExp (typeof (DBNull)), "Value")));
1681 private CodeMemberProperty CreateRowParentRowProperty (DataTable dt, DataRelation rel)
1683 CodeMemberProperty p = new CodeMemberProperty ();
1684 p.Name = opts.TableMemberName (rel.ParentTable.TableName) + "Row" +
1685 (rel.ParentTable.TableName == rel.ChildTable.TableName ? "Parent" : String.Empty);
1686 p.Attributes = MemberAttributes.Public;
1687 p.Type = TypeRef (opts.RowName (rel.ParentTable.TableName));
1688 p.GetStatements.Add (Return (Cast (p.Type, MethodInvoke (
1696 Const (rel.RelationName))))));
1697 p.SetStatements.Add (Eval (MethodInvoke (
1699 new CodePropertySetValueReferenceExpression (),
1706 Const (rel.RelationName)))));
1711 private CodeMemberMethod CreateRowGetChildRows (DataTable dt, DataRelation rel)
1713 CodeMemberMethod m = new CodeMemberMethod ();
1714 m.Name = "Get" + opts.TableMemberName (rel.ChildTable.TableName) + "Rows";
1715 m.Attributes = MemberAttributes.Public;
1716 m.ReturnType = new CodeTypeReference (opts.RowName (rel.ChildTable.TableName), 1);
1717 m.Statements.Add (Return (Cast (m.ReturnType, MethodInvoke (
1725 Const (rel.RelationName))))));
1735 // public class [foo]ChangeEventArgs : EventArgs
1737 // private [foo]Row eventRow;
1738 // private DataRowAction eventAction;
1743 private CodeTypeDeclaration GenerateEventType (DataTable dt)
1745 CodeTypeDeclaration t = new CodeTypeDeclaration ();
1746 t.Name = opts.EventArgsName (dt.TableName);
1747 t.BaseTypes.Add (TypeRef (typeof (EventArgs)));
1748 t.Attributes = MemberAttributes.Public;
1751 new CodeMemberField (
1752 TypeRef (opts.RowName (dt.TableName)),
1755 new CodeMemberField (
1756 TypeRef (typeof (DataRowAction)), "eventAction"));
1757 t.Members.Add (CreateEventCtor (dt));
1759 t.Members.Add (CreateEventRow (dt));
1761 t.Members.Add (CreateEventAction (dt));
1767 // public [foo]RowChangeEventArgs ([foo]Row r, DataRowAction a)
1772 private CodeConstructor CreateEventCtor (DataTable dt)
1774 CodeConstructor c = new CodeConstructor ();
1775 c.Attributes = MemberAttributes.Public;
1776 c.Parameters.Add (Param (TypeRef (opts.RowName (dt.TableName)), "r"));
1777 c.Parameters.Add (Param (TypeRef (typeof (DataRowAction)), "a"));
1778 c.Statements.Add (Let (FieldRef ("eventRow"), ParamRef ("r")));
1779 c.Statements.Add (Let (FieldRef ("eventAction"), ParamRef ("a")));
1785 // public [foo]Row Row {
1786 // get { return eventRow; }
1788 private CodeMemberProperty CreateEventRow (DataTable dt)
1790 CodeMemberProperty p = new CodeMemberProperty ();
1792 p.Attributes = MemberAttributes.Public | MemberAttributes.Final;
1793 p.Type = TypeRef (opts.RowName (dt.TableName));
1795 p.GetStatements.Add (Return (FieldRef ("eventRow")));
1800 // public DataRowAction Action {
1801 // get { return eventAction; }
1803 private CodeMemberProperty CreateEventAction (DataTable dt)
1805 CodeMemberProperty p = new CodeMemberProperty ();
1807 p.Attributes = MemberAttributes.Public | MemberAttributes.Final;
1808 p.Type = TypeRef (typeof (DataRowAction));
1810 p.GetStatements.Add (Return (FieldRef ("eventAction")));
1817 #region Table Adapter class
1819 private CodeTypeDeclaration GenerateTableAdapterType (TableAdapterSchemaInfo taInfo)
1821 CodeTypeDeclaration t = new CodeTypeDeclaration ();
1822 t.Name = opts.TableAdapterName (taInfo.Name);
1823 t.BaseTypes.Add (TypeRef (taInfo.BaseClass));
1825 t.Members.Add (CreateTableAdapterDefaultCtor ());
1827 // table adapter fields/properties
1828 CreateDBAdapterFieldAndProperty (t, taInfo.Adapter);
1829 CreateDBConnectionFieldAndProperty (t, taInfo.Connection);
1831 DbCommand cmd = null;
1832 if (taInfo.Commands.Count > 0)
1833 cmd = ((DbCommandInfo)taInfo.Commands[0]).Command;
1835 cmd = taInfo.Provider.CreateCommand ();
1836 CreateDBCommandCollectionFieldAndProperty (t, cmd);
1837 CreateAdapterClearBeforeFillFieldAndProperty (t);
1839 CreateAdapterInitializeMethod (t, taInfo);
1840 CreateConnectionInitializeMethod (t, taInfo);
1841 CreateCommandCollectionInitializeMethod (t, taInfo);
1843 CreateDbSourceMethods (t, taInfo);
1844 if (taInfo.ShortCommands)
1845 CreateShortCommandMethods (t, taInfo);
1850 private CodeConstructor CreateTableAdapterDefaultCtor ()
1852 CodeConstructor ctor = new CodeConstructor ();
1853 ctor.Attributes = MemberAttributes.Public;
1854 ctor.Statements.Add (Let (PropRef ("ClearBeforeFill"), Const (true)));
1859 private void CreateDBAdapterFieldAndProperty (CodeTypeDeclaration t, DbDataAdapter adapter)
1861 CodeExpression expr;
1862 CodeStatement setStmt;
1864 CodeMemberField f = new CodeMemberField ();
1865 f.Name = "_adapter";
1866 f.Type = TypeRef (adapter.GetType ());
1869 CodeMemberProperty p = new CodeMemberProperty ();
1871 p.Attributes = MemberAttributes.Private;
1875 expr = FieldRef ("_adapter");
1876 setStmt = Eval (MethodInvoke ("InitAdapter"));
1877 stmt = new CodeConditionStatement (Equals (expr, Const (null)),
1878 new CodeStatement [] {setStmt},
1879 new CodeStatement [] {});
1880 p.GetStatements.Add (stmt);
1881 p.GetStatements.Add (Return (expr));
1885 private void CreateDBConnectionFieldAndProperty (CodeTypeDeclaration t, DbConnection conn)
1887 CodeExpression expr;
1888 CodeStatement setStmt;
1890 CodeMemberField f = new CodeMemberField ();
1891 f.Name = "_connection";
1892 f.Type = TypeRef (conn.GetType ());
1895 CodeMemberProperty p = new CodeMemberProperty ();
1896 p.Name = "Connection";
1897 p.Attributes = MemberAttributes.Assembly;
1900 expr = FieldRef ("_connection");
1901 setStmt = Eval (MethodInvoke ("InitConnection"));
1902 stmt = new CodeConditionStatement (Equals (expr, Const (null)),
1903 new CodeStatement [] {setStmt},
1904 new CodeStatement [] {});
1905 p.GetStatements.Add (stmt);
1906 p.GetStatements.Add (Return (expr));
1907 p.SetStatements.Add (Let (expr, new CodePropertySetValueReferenceExpression()));
1909 // update connection in Insert/Delete/Update commands of adapter
1912 string cmdStr = "InsertCommand";
1913 string connStr = "Connection";
1918 expr = PropRef (PropRef ("Adapter"), cmdStr);
1919 setStmt = Let (PropRef (expr, connStr), new CodePropertySetValueReferenceExpression());
1920 stmt = new CodeConditionStatement (Inequals (expr, Const (null)),
1921 new CodeStatement [] {setStmt},
1922 new CodeStatement [] {});
1923 p.SetStatements.Add (stmt);
1930 cmdStr = "DeleteCommand";
1931 expr = PropRef (PropRef ("Adapter"), cmdStr);
1932 setStmt = Let (PropRef (expr, connStr), new CodePropertySetValueReferenceExpression());
1933 stmt = new CodeConditionStatement (Inequals (expr, Const (null)),
1934 new CodeStatement [] {setStmt}, new CodeStatement [] {});
1935 p.SetStatements.Add (stmt);
1941 cmdStr = "UpdateCommand";
1942 expr = PropRef (PropRef ("Adapter"), cmdStr);
1943 setStmt = Let (PropRef (expr, connStr), new CodePropertySetValueReferenceExpression());
1944 stmt = new CodeConditionStatement (Inequals (expr, Const (null)),
1945 new CodeStatement [] {setStmt}, new CodeStatement [] {});
1946 p.SetStatements.Add (stmt);
1948 // iterate through command collection and update it
1952 setStmt = VarDecl (typeof (int), "i", Const (0));
1953 expr = LessThan (Local ("i"), PropRef (PropRef ("CommandCollection"), "Length"));
1954 stmt = Let (Local ("i"), Compute (Local ("i"), Const (1), CodeBinaryOperatorType.Add));
1956 // statements to execute in the loop
1957 CodeExpression expr1 = IndexerRef (PropRef ("CommandCollection"), Local ("i"));
1958 CodeStatement setStmt1 = Let (PropRef (expr1, "Connection"), new CodePropertySetValueReferenceExpression());
1959 CodeStatement stmt1 = new CodeConditionStatement (Inequals (expr1, Const (null)),
1960 new CodeStatement [] {setStmt1}, new CodeStatement [] {});
1961 CodeIterationStatement forLoop = new CodeIterationStatement (setStmt, expr, stmt,
1962 new CodeStatement[] {stmt1});
1963 p.SetStatements.Add (forLoop);
1967 private void CreateDBCommandCollectionFieldAndProperty (CodeTypeDeclaration t, DbCommand cmd)
1969 CodeExpression expr;
1970 CodeStatement setStmt;
1972 CodeMemberField f = new CodeMemberField ();
1973 f.Name = "_commandCollection";
1974 f.Type = TypeRefArray (cmd.GetType (), 1);
1977 CodeMemberProperty p = new CodeMemberProperty ();
1978 p.Name = "CommandCollection";
1979 p.Attributes = MemberAttributes.Family;
1983 expr = FieldRef ("_commandCollection");
1984 setStmt = Eval (MethodInvoke ("InitCommandCollection"));
1985 stmt = new CodeConditionStatement (Equals (expr, Const (null)),
1986 new CodeStatement [] {setStmt},
1987 new CodeStatement [] {});
1988 p.GetStatements.Add (stmt);
1989 p.GetStatements.Add (Return (expr));
1993 private void CreateAdapterClearBeforeFillFieldAndProperty (CodeTypeDeclaration t)
1995 CodeMemberField f = new CodeMemberField ();
1996 f.Name = "_clearBeforeFill";
1997 f.Type = TypeRef (typeof (bool));
2000 CodeMemberProperty p = new CodeMemberProperty ();
2001 p.Name = "ClearBeforeFill";
2002 p.Attributes = MemberAttributes.Public;
2004 p.SetStatements.Add (Let (FieldRef ("_clearBeforeFill"),
2005 new CodePropertySetValueReferenceExpression()));
2006 p.GetStatements.Add (Return (FieldRef ("_clearBeforeFill")));
2010 private void CreateAdapterInitializeMethod (CodeTypeDeclaration t, TableAdapterSchemaInfo taInfo)
2012 CodeMemberMethod m = new CodeMemberMethod ();
2013 m.Name = "InitAdapter";
2014 m.Attributes = MemberAttributes.Private;
2017 CodeExpression expr;
2020 // initialize adapter
2021 expr = FieldRef ("_adapter");
2022 stmt = Let (expr, New (taInfo.Adapter.GetType ()));
2023 m.Statements.Add (stmt);
2025 // populate tableMapping
2026 stmt = VarDecl (typeof (DataTableMapping), "tableMapping", null);
2027 m.Statements.Add (stmt);
2028 foreach (DataTableMapping tblMap in taInfo.Adapter.TableMappings) {
2029 expr = Local ("tableMapping");
2030 stmt = Let (expr, New (tblMap.GetType ()));
2031 m.Statements.Add (stmt);
2033 stmt = Let (PropRef (expr, "SourceTable"), Const (tblMap.SourceTable));
2034 m.Statements.Add (stmt);
2036 stmt = Let (PropRef (expr, "DataSetTable"), Const (tblMap.DataSetTable));
2037 m.Statements.Add (stmt);
2039 foreach (DataColumnMapping colMap in tblMap.ColumnMappings) {
2040 stmt = Eval (MethodInvoke (PropRef (expr, "ColumnMappings"), "Add",
2041 new CodeExpression [] {Const (colMap.SourceColumn), Const (colMap.DataSetColumn)}));
2042 m.Statements.Add (stmt);
2044 expr = PropRef (FieldRef ("_adapter"), "TableMappings");
2045 stmt = Eval (MethodInvoke (expr, "Add", Local ("tableMapping")));
2046 m.Statements.Add (stmt);
2048 // Generate code for adapter's deletecommand
2049 expr = PropRef (FieldRef ("_adapter"), "DeleteCommand");
2050 DbCommand cmd = taInfo.Adapter.DeleteCommand;
2051 AddDbCommandStatements (m, expr, cmd);
2053 // Generate code for adapter's insertcommand
2054 expr = PropRef (FieldRef ("_adapter"), "InsertCommand");
2055 cmd = taInfo.Adapter.InsertCommand;
2056 AddDbCommandStatements (m, expr, cmd);
2058 // Generate code for adapter's updatecommand
2059 expr = PropRef (FieldRef ("_adapter"), "UpdateCommand");
2060 cmd = taInfo.Adapter.UpdateCommand;
2061 AddDbCommandStatements (m, expr, cmd);
2066 private void AddDbCommandStatements (CodeMemberMethod m,
2067 CodeExpression expr,
2073 CodeExpression expr1;
2074 CodeStatement stmt = Let (expr, New (cmd.GetType ()));
2075 m.Statements.Add (stmt);
2077 stmt = Let (PropRef (expr,"Connection"), PropRef ("Connection"));
2078 m.Statements.Add (stmt);
2079 stmt = Let (PropRef (expr, "CommandText"), Const (cmd.CommandText));
2080 m.Statements.Add (stmt);
2081 expr1 = PropRef (Local(typeof (CommandType).FullName), cmd.CommandType.ToString ());
2082 stmt = Let (PropRef (expr, "CommandType"), expr1);
2083 m.Statements.Add (stmt);
2085 expr1 = PropRef (expr, "Parameters");
2086 foreach (DbParameter param in cmd.Parameters) {
2087 AddDbParameterStatements (m, expr1, param);
2091 private void AddDbParameterStatements (CodeMemberMethod m,
2092 CodeExpression expr,
2095 object dbType = param.FrameworkDbType;
2096 string srcColumn = null;
2098 if (param.SourceColumn != String.Empty)
2099 srcColumn = param.SourceColumn;
2101 CodeExpression[] args = new CodeExpression[] {
2102 Const (param.ParameterName),
2103 PropRef (Local(dbType.GetType().FullName), dbType.ToString ()),
2105 PropRef(Local(typeof (ParameterDirection).FullName), param.Direction.ToString ()),
2106 Const (param.IsNullable),
2107 Const (((IDbDataParameter)param).Precision),
2108 Const (((IDbDataParameter)param).Scale),
2110 PropRef (Local (typeof (DataRowVersion).FullName), param.SourceVersion.ToString ()),
2111 /* Const (param.SourceColumnNullMapping), */ // TODO: Investigate with other providers
2114 m.Statements.Add (Eval (MethodInvoke (expr, "Add", New (param.GetType (), args))));
2116 private void CreateConnectionInitializeMethod (CodeTypeDeclaration t,
2117 TableAdapterSchemaInfo taInfo)
2119 CodeMemberMethod m = new CodeMemberMethod ();
2120 m.Name = "InitConnection";
2121 m.Attributes = MemberAttributes.Private;
2124 CodeExpression expr, expr1;
2127 // initialize connection
2128 expr = FieldRef ("_connection");
2129 stmt = Let (expr, New (taInfo.Connection.GetType ()));
2130 m.Statements.Add (stmt);
2132 // assign connection string
2133 expr = PropRef (FieldRef ("_connection"), "ConnectionString");
2134 expr1 = IndexerRef (PropRef (Local (typeof (System.Configuration.ConfigurationManager).ToString()), "ConnectionStrings"),
2135 Const (taInfo.ConnectionString));
2136 stmt = Let (expr, PropRef (expr1, "ConnectionString"));
2137 m.Statements.Add (stmt);
2142 private void CreateCommandCollectionInitializeMethod (CodeTypeDeclaration t,
2143 TableAdapterSchemaInfo taInfo)
2145 //string tmp = null;
2147 CodeMemberMethod m = new CodeMemberMethod ();
2148 m.Name = "InitCommandCollection";
2149 m.Attributes = MemberAttributes.Private;
2152 CodeExpression expr, expr1;
2155 type = ((DbCommandInfo)taInfo.Commands[0]).Command.GetType();
2157 // initialize connection
2158 expr = FieldRef ("_commandCollection");
2159 stmt = Let (expr, NewArray (type, taInfo.Commands.Count));
2160 m.Statements.Add (stmt);
2162 // loop through the collection and generate the code
2163 for (int idx = 0; idx < taInfo.Commands.Count; idx++) {
2164 DbCommand cmd = ((DbCommandInfo)taInfo.Commands[idx]).Command;
2166 expr1 = IndexerRef (expr, Const (idx));
2167 stmt = Let (expr1, New (type));
2168 m.Statements.Add (stmt);
2170 // Initialize cmd members
2171 stmt = Let (PropRef (expr1, "Connection"), PropRef ("Connection"));
2172 m.Statements.Add (stmt);
2173 stmt = Let (PropRef (expr1, "CommandText"), Const (cmd.CommandText));
2174 m.Statements.Add (stmt);
2175 stmt = Let (PropRef (expr1, "CommandType"),
2176 PropRef (Local(typeof (CommandType).FullName), cmd.CommandType.ToString ()));
2177 m.Statements.Add (stmt);
2178 expr1 = PropRef (expr1, "Parameters");
2179 foreach (DbParameter param in cmd.Parameters) {
2180 AddDbParameterStatements (m, expr1, param);
2186 private void CreateDbSourceMethods (CodeTypeDeclaration t,
2187 TableAdapterSchemaInfo taInfo)
2190 CodeMemberMethod m = null;
2191 CodeExpression expr, expr1, expr2;
2193 string tmpScalarVal = null;
2195 expr = PropRef (PropRef ("Adapter"), "SelectCommand");
2196 // loop through the collection and generate the code
2197 for (int idx = 0; idx < taInfo.Commands.Count; idx++) {
2198 DbCommandInfo cmdInfo = (DbCommandInfo)taInfo.Commands[idx];
2200 foreach (DbSourceMethodInfo mInfo in cmdInfo.Methods) {
2201 //Console.WriteLine ("Generating code for {0} method", mInfo.Name);
2203 // TODO: Add support for Fill methods
2204 if (mInfo.MethodType == GenerateMethodsType.Fill)
2207 m = new CodeMemberMethod ();
2208 m.Name = mInfo.Name;
2210 stmt = Let (expr, IndexerRef (PropRef ("CommandCollection"), Const (idx)));
2211 m.Statements.Add (stmt);
2213 switch ((MemberAttributes) Enum.Parse (typeof (MemberAttributes), mInfo.Modifier)) {
2214 case MemberAttributes.Public:
2215 m.Attributes = MemberAttributes.Public;
2218 case MemberAttributes.Private:
2219 m.Attributes = MemberAttributes.Private;
2222 case MemberAttributes.Assembly:
2223 m.Attributes = MemberAttributes.Assembly;
2226 case MemberAttributes.Family:
2227 m.Attributes = MemberAttributes.Family;
2230 //Console.WriteLine ("QueryType: {0}", mInfo.QueryType);
2231 QueryType qType = (QueryType) Enum.Parse (typeof (QueryType), mInfo.QueryType);
2233 case QueryType.Scalar:
2234 case QueryType.NoData:
2235 // executes non query and returns status
2236 m.ReturnType = TypeRef (typeof (int));
2237 AddGeneratedMethodParametersAndStatements (m, expr, cmdInfo.Command);
2239 // store connection state
2240 tmp = typeof (System.Data.ConnectionState).FullName;
2241 expr1 = PropRef (Local ("command"), "Connection");
2242 expr2 = PropRef (PropRef (Local ("System"), "Data"), "ConnectionState");
2243 stmt = VarDecl (tmp, "previousConnectionState", PropRef (expr1, "State"));
2244 m.Statements.Add (stmt);
2246 // Open connection, if its not already
2247 CodeExpression expr3 = BitOps (PropRef (expr1, "State"), PropRef (expr2, "Open"),
2248 CodeBinaryOperatorType.BitwiseAnd);
2249 stmt = new CodeConditionStatement (Inequals (expr3, PropRef (expr2, "Open")),
2250 new CodeStatement[] {Eval (MethodInvoke (expr1, "Open",
2251 new CodeExpression[] {}))},
2252 new CodeStatement[] {});
2253 m.Statements.Add (stmt);
2255 // declare return variable and execute query
2256 CodeTryCatchFinallyStatement try1 = new CodeTryCatchFinallyStatement ();
2258 if (qType == QueryType.NoData) {
2259 m.Statements.Add (VarDecl (typeof (int), "returnValue", null));
2260 expr3 = MethodInvoke (Local ("command"), "ExecuteNonQuery", new CodeExpression[] {});
2262 tmpScalarVal = mInfo.ScalarCallRetval.Substring (0, mInfo.ScalarCallRetval.IndexOf (','));
2263 m.Statements.Add (VarDecl (TypeRef (tmpScalarVal).BaseType, "returnValue", null));
2264 expr3 = MethodInvoke (Local ("command"), "ExecuteScalar", new CodeExpression[] {});
2268 try1.TryStatements.Add (Let (Local ("returnValue"), expr3));
2270 // fill finally block
2271 stmt = new CodeConditionStatement (Equals (Local ("previousConnectionState"), PropRef (expr2, "Closed")),
2272 new CodeStatement[] {Eval (MethodInvoke (expr1, "Close",
2273 new CodeExpression[] {}))},
2274 new CodeStatement[] {});
2275 try1.FinallyStatements.Add (stmt);
2276 m.Statements.Add (try1);
2279 if (qType == QueryType.NoData) {
2280 m.Statements.Add (Return (Local ("returnValue")));
2282 expr2 = Equals (Local ("returnValue"), Const (null));
2283 expr3 = Equals (MethodInvoke (Local ("returnValue"), "GetType", new CodeExpression[] {}),
2284 TypeOfRef ("System.DBNull"));
2285 stmt = new CodeConditionStatement (BooleanOps (expr2, expr3, CodeBinaryOperatorType.BooleanOr),
2286 new CodeStatement[] {Return (Const (null))},
2287 new CodeStatement[] {Return (Cast (tmpScalarVal, Local ("returnValue")))});
2288 m.Statements.Add (stmt);
2293 case QueryType.Rowset:
2294 // returns DataTable
2295 // TODO: Handle multiple DataTables
2296 tmp = opts.DataSetName (ds.DataSetName) + "." + opts.TableTypeName (ds.Tables[0].TableName);
2297 m.ReturnType = TypeRef (tmp);
2299 AddGeneratedMethodParametersAndStatements (m, expr, cmdInfo.Command);
2300 stmt = VarDecl (tmp, "dataTable", New (tmp));
2301 m.Statements.Add (stmt);
2304 expr = PropRef ("Adapter");
2305 stmt = Eval (MethodInvoke (expr, "Fill", Local ("dataTable")));
2306 m.Statements.Add (stmt);
2309 m.Statements.Add (Return (Local ("dataTable")));
2317 private void AddGeneratedMethodParametersAndStatements (CodeMemberMethod m,
2318 CodeExpression expr,
2322 CodeExpression expr1;
2326 foreach (DbParameter param in cmd.Parameters) {
2327 if (param.Direction != ParameterDirection.ReturnValue) {
2328 if (param.ParameterName[0] == '@')
2329 tmp = param.ParameterName.Substring (1);
2331 tmp = param.ParameterName;
2332 if (param.SystemType != null)
2333 m.Parameters.Add (Param (TypeRef(param.SystemType), tmp));
2334 expr1 = IndexerRef (PropRef (expr, "Parameters"), Const (idx));
2335 stmt = Let (expr1, ParamRef (tmp));
2336 m.Statements.Add (stmt);
2342 private void CreateShortCommandMethods (CodeTypeDeclaration t, TableAdapterSchemaInfo taInfo)
2355 /* =========================================================
2358 MonoDataSetGenerator API notes
2362 CreateDataSetClasses (
2366 GeneratorOptions options)
2370 *** Code naming method delegate
2372 public delegate string CodeNamingMethod (string sourceName);
2374 It is used in CodeGeneratorOptions (describled immediately below).
2378 *** Generator Options
2380 public bool MakeClassesInsideDataSet
2381 indicates whether classes and delegates other than DataSet
2382 itself are "contained" in the DataSet class or not.
2384 public CodeNamingMethod CreateDataSetName;
2385 public CodeNamingMethod CreateTableTypeName;
2386 public CodeNamingMethod CreateTableMemberName;
2387 public CodeNamingMethod CreateColumnName;
2388 public CodeNamingMethod CreateRowName;
2389 public CodeNamingMethod CreateRelationName;
2390 public CodeNamingMethod CreateTableDelegateName;
2391 public CodeNamingMethod CreateEventArgsName;
2392 Custom methods each of that returns type or member name.
2394 By default, they are set as to useTypedDataSetGenerator.
2395 CreateIdName() with modifications listed as below:
2398 TableTypeName: "DataTable" suffix
2399 TableMemberName: as is
2401 RowName: "Row" suffix
2402 RelationName: (TBD; maybe had better have another delegate type)
2403 DelegateName: "RowChangedEventHandler" suffix
2404 EventArgsName: "RowChangedEventArgs" suffix
2406 ** Auto Generated classes
2408 1. Custom DataSet class
2410 class name = dataset name, encoded by options.CreateDataSetName().
2414 public default .ctor()
2416 set custom delegate on Tables.CollectionChanged
2417 set custom delegate on Relations.CollectionChanged
2419 runtime serialization .ctor()
2424 data tables: [foo]DataTable foo { return this.table[foo]; }
2427 init variables on new dataset.
2429 *** protected members
2431 ShouldSerializeTables()
2432 returns false, while default DataSet returns true.
2433 ShouldSerializeRelations()
2434 returns false, while default DataSet returns true.
2436 ReadXmlSerializable() ... similar to runtime serialization
2439 GetSchemaSerializable()
2440 Write its schema to temporary MemoryStream
2441 Read XML schema from the stream
2443 *** internal members
2446 set member fields (tables, relations)
2447 call members' "init variables"
2450 set DataSetName, Prefix, Namespace, Locale, CaseSensitive, EnforceConstraints
2454 create FKC: new FKC([rel], new DataColumn [] {table[foo].[keyColumnName]Column}, new DataColumn [] {table[child].[childColName]Column}
2455 fill Rule properties.
2456 allocate relation[rel] and fill Nested, then Relations.Add()
2460 data tables: [foo]DataTable table[foo];
2462 data relations: DataRelation relation[rel];
2464 ShouldSerialize[foo]
2468 2. Custom DataTable classes for each DataTable
2470 This class is created under the dataset.
2472 *** internal members
2474 .ctor() : base("[foo]")
2480 DataColumn [bar]Column { return column[bar]; }
2483 fill each column fields
2487 int Count { rowcount }
2489 this [int index] { row [i]; }
2491 event [foo]RowChangedEventHandler [foo]RowChanged
2492 event [foo]RowChangedEventHandler [foo]RowChanging
2493 event [foo]RowChangedEventHandler [foo]RowDeleted
2494 event [foo]RowChangedEventHandler [foo]RowDeleting
2496 void Add[foo]Row ([foo]Row row) { Rows.Add (row); }
2498 [foo]Row Add[foo]Row ([columnType] [columnName])
2499 create new [foo]row.
2503 // non-relation-children are just created as column type
2504 // relation-children are typeof fooRow[]
2506 GetEnumerator() { Rows.GetEnumerator (); }
2508 override DataTable Clone()
2511 [foo]Row New[foo]Row()
2513 void Remove[foo]Row([foo]Row)
2515 //for each ChildRelations
2516 [bar]Row [] Get[foo_bar]Rows ()
2518 *** protected members
2520 override DataTable CreateInstance() { return new }
2522 override DataRow NewRowFromBuilder(DataRowBuilder)
2524 override Type GetRowType()
2526 override void OnRowChanged(DataRowChangedEventArgs)
2528 check this event [foo]RowChanged.
2530 override void OnRowChanging(DataRowChangedEventArgs)
2531 override void OnRowDeleted(DataRowChangedEventArgs)
2532 override void OnRowDeleting(DataRowChangedEventArgs)
2539 column[bar] = new DataColumn (...);
2543 DataColumn [bar]Column
2545 3. Custom DataRow classses
2552 get { try { } catch { throw StrongTypingException(); }
2553 set { this [[foo]Table.[bar]Column] = value; }
2556 IsNull ([foo]Table.[bar]Column);
2558 void Set[bar]Null ()
2560 if the table is parent of some relations
2562 public [child]Row [] Get[child]Rows()
2564 *** internal members
2566 .ctor(DataRowBuilder) : base.()
2571 [foo]DataTable table[foo]
2574 4. Custom DataRowChangeEvent classes
2579 DataRowAction eventAction
2583 .ctor([foo]Row row, DataRowAction action)
2587 DataRowAction Action
2591 5. public Table RowChangedEventHandler delegates
2593 [foo]RowChangedEventHandler(object, [foo]RowChangedEvent e)
2596 ======================================================== */