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 string qualifiedBaseClassName;
1825 CodeTypeDeclaration t = new CodeTypeDeclaration ();
1826 t.Name = opts.TableAdapterName (taInfo.Name);
1827 t.BaseTypes.Add (TypeRef (taInfo.BaseClass));
1829 t.Members.Add (CreateTableAdapterDefaultCtor ());
1831 // table adapter fields/properties
1832 CreateDBAdapterFieldAndProperty (t, taInfo.Adapter);
1833 CreateDBConnectionFieldAndProperty (t, taInfo.Connection);
1835 DbCommand cmd = null;
1836 if (taInfo.Commands.Count > 0)
1837 cmd = ((DbCommandInfo)taInfo.Commands[0]).Command;
1839 cmd = taInfo.Provider.CreateCommand ();
1840 CreateDBCommandCollectionFieldAndProperty (t, cmd);
1841 CreateAdapterClearBeforeFillFieldAndProperty (t);
1843 CreateAdapterInitializeMethod (t, taInfo);
1844 CreateConnectionInitializeMethod (t, taInfo);
1845 CreateCommandCollectionInitializeMethod (t, taInfo);
1847 CreateDbSourceMethods (t, taInfo);
1848 if (taInfo.ShortCommands)
1849 CreateShortCommandMethods (t, taInfo);
1854 private CodeConstructor CreateTableAdapterDefaultCtor ()
1856 CodeConstructor ctor = new CodeConstructor ();
1857 ctor.Attributes = MemberAttributes.Public;
1858 ctor.Statements.Add (Let (PropRef ("ClearBeforeFill"), Const (true)));
1863 private void CreateDBAdapterFieldAndProperty (CodeTypeDeclaration t, DbDataAdapter adapter)
1865 CodeExpression expr;
1866 CodeStatement setStmt;
1868 CodeMemberField f = new CodeMemberField ();
1869 f.Name = "_adapter";
1870 f.Type = TypeRef (adapter.GetType ());
1873 CodeMemberProperty p = new CodeMemberProperty ();
1875 p.Attributes = MemberAttributes.Private;
1879 expr = FieldRef ("_adapter");
1880 setStmt = Eval (MethodInvoke ("InitAdapter"));
1881 stmt = new CodeConditionStatement (Equals (expr, Const (null)),
1882 new CodeStatement [] {setStmt},
1883 new CodeStatement [] {});
1884 p.GetStatements.Add (stmt);
1885 p.GetStatements.Add (Return (expr));
1889 private void CreateDBConnectionFieldAndProperty (CodeTypeDeclaration t, DbConnection conn)
1891 CodeExpression expr;
1892 CodeStatement setStmt;
1894 CodeMemberField f = new CodeMemberField ();
1895 f.Name = "_connection";
1896 f.Type = TypeRef (conn.GetType ());
1899 CodeMemberProperty p = new CodeMemberProperty ();
1900 p.Name = "Connection";
1901 p.Attributes = MemberAttributes.Assembly;
1904 expr = FieldRef ("_connection");
1905 setStmt = Eval (MethodInvoke ("InitConnection"));
1906 stmt = new CodeConditionStatement (Equals (expr, Const (null)),
1907 new CodeStatement [] {setStmt},
1908 new CodeStatement [] {});
1909 p.GetStatements.Add (stmt);
1910 p.GetStatements.Add (Return (expr));
1911 p.SetStatements.Add (Let (expr, new CodePropertySetValueReferenceExpression()));
1913 // update connection in Insert/Delete/Update commands of adapter
1916 string cmdStr = "InsertCommand";
1917 string connStr = "Connection";
1922 expr = PropRef (PropRef ("Adapter"), cmdStr);
1923 setStmt = Let (PropRef (expr, connStr), new CodePropertySetValueReferenceExpression());
1924 stmt = new CodeConditionStatement (Inequals (expr, Const (null)),
1925 new CodeStatement [] {setStmt},
1926 new CodeStatement [] {});
1927 p.SetStatements.Add (stmt);
1934 cmdStr = "DeleteCommand";
1935 expr = PropRef (PropRef ("Adapter"), cmdStr);
1936 setStmt = Let (PropRef (expr, connStr), new CodePropertySetValueReferenceExpression());
1937 stmt = new CodeConditionStatement (Inequals (expr, Const (null)),
1938 new CodeStatement [] {setStmt}, new CodeStatement [] {});
1939 p.SetStatements.Add (stmt);
1945 cmdStr = "UpdateCommand";
1946 expr = PropRef (PropRef ("Adapter"), cmdStr);
1947 setStmt = Let (PropRef (expr, connStr), new CodePropertySetValueReferenceExpression());
1948 stmt = new CodeConditionStatement (Inequals (expr, Const (null)),
1949 new CodeStatement [] {setStmt}, new CodeStatement [] {});
1950 p.SetStatements.Add (stmt);
1952 // iterate through command collection and update it
1956 setStmt = VarDecl (typeof (int), "i", Const (0));
1957 expr = LessThan (Local ("i"), PropRef (PropRef ("CommandCollection"), "Length"));
1958 stmt = Let (Local ("i"), Compute (Local ("i"), Const (1), CodeBinaryOperatorType.Add));
1960 // statements to execute in the loop
1961 CodeExpression expr1 = IndexerRef (PropRef ("CommandCollection"), Local ("i"));
1962 CodeStatement setStmt1 = Let (PropRef (expr1, "Connection"), new CodePropertySetValueReferenceExpression());
1963 CodeStatement stmt1 = new CodeConditionStatement (Inequals (expr1, Const (null)),
1964 new CodeStatement [] {setStmt1}, new CodeStatement [] {});
1965 CodeIterationStatement forLoop = new CodeIterationStatement (setStmt, expr, stmt,
1966 new CodeStatement[] {stmt1});
1967 p.SetStatements.Add (forLoop);
1971 private void CreateDBCommandCollectionFieldAndProperty (CodeTypeDeclaration t, DbCommand cmd)
1973 CodeExpression expr;
1974 CodeStatement setStmt;
1976 CodeMemberField f = new CodeMemberField ();
1977 f.Name = "_commandCollection";
1978 f.Type = TypeRefArray (cmd.GetType (), 1);
1981 CodeMemberProperty p = new CodeMemberProperty ();
1982 p.Name = "CommandCollection";
1983 p.Attributes = MemberAttributes.Family;
1987 expr = FieldRef ("_commandCollection");
1988 setStmt = Eval (MethodInvoke ("InitCommandCollection"));
1989 stmt = new CodeConditionStatement (Equals (expr, Const (null)),
1990 new CodeStatement [] {setStmt},
1991 new CodeStatement [] {});
1992 p.GetStatements.Add (stmt);
1993 p.GetStatements.Add (Return (expr));
1997 private void CreateAdapterClearBeforeFillFieldAndProperty (CodeTypeDeclaration t)
1999 CodeMemberField f = new CodeMemberField ();
2000 f.Name = "_clearBeforeFill";
2001 f.Type = TypeRef (typeof (bool));
2004 CodeMemberProperty p = new CodeMemberProperty ();
2005 p.Name = "ClearBeforeFill";
2006 p.Attributes = MemberAttributes.Public;
2008 p.SetStatements.Add (Let (FieldRef ("_clearBeforeFill"),
2009 new CodePropertySetValueReferenceExpression()));
2010 p.GetStatements.Add (Return (FieldRef ("_clearBeforeFill")));
2014 private void CreateAdapterInitializeMethod (CodeTypeDeclaration t, TableAdapterSchemaInfo taInfo)
2016 CodeMemberMethod m = new CodeMemberMethod ();
2017 m.Name = "InitAdapter";
2018 m.Attributes = MemberAttributes.Private;
2021 CodeExpression expr;
2024 // initialize adapter
2025 expr = FieldRef ("_adapter");
2026 stmt = Let (expr, New (taInfo.Adapter.GetType ()));
2027 m.Statements.Add (stmt);
2029 // populate tableMapping
2030 stmt = VarDecl (typeof (DataTableMapping), "tableMapping", null);
2031 m.Statements.Add (stmt);
2032 foreach (DataTableMapping tblMap in taInfo.Adapter.TableMappings) {
2033 expr = Local ("tableMapping");
2034 stmt = Let (expr, New (tblMap.GetType ()));
2035 m.Statements.Add (stmt);
2037 stmt = Let (PropRef (expr, "SourceTable"), Const (tblMap.SourceTable));
2038 m.Statements.Add (stmt);
2040 stmt = Let (PropRef (expr, "DataSetTable"), Const (tblMap.DataSetTable));
2041 m.Statements.Add (stmt);
2043 foreach (DataColumnMapping colMap in tblMap.ColumnMappings) {
2044 stmt = Eval (MethodInvoke (PropRef (expr, "ColumnMappings"), "Add",
2045 new CodeExpression [] {Const (colMap.SourceColumn), Const (colMap.DataSetColumn)}));
2046 m.Statements.Add (stmt);
2048 expr = PropRef (FieldRef ("_adapter"), "TableMappings");
2049 stmt = Eval (MethodInvoke (expr, "Add", Local ("tableMapping")));
2050 m.Statements.Add (stmt);
2052 // Generate code for adapter's deletecommand
2053 expr = PropRef (FieldRef ("_adapter"), "DeleteCommand");
2054 DbCommand cmd = taInfo.Adapter.DeleteCommand;
2055 AddDbCommandStatements (m, expr, cmd);
2057 // Generate code for adapter's insertcommand
2058 expr = PropRef (FieldRef ("_adapter"), "InsertCommand");
2059 cmd = taInfo.Adapter.InsertCommand;
2060 AddDbCommandStatements (m, expr, cmd);
2062 // Generate code for adapter's updatecommand
2063 expr = PropRef (FieldRef ("_adapter"), "UpdateCommand");
2064 cmd = taInfo.Adapter.UpdateCommand;
2065 AddDbCommandStatements (m, expr, cmd);
2070 private void AddDbCommandStatements (CodeMemberMethod m,
2071 CodeExpression expr,
2077 CodeExpression expr1;
2078 CodeStatement stmt = Let (expr, New (cmd.GetType ()));
2079 m.Statements.Add (stmt);
2081 stmt = Let (PropRef (expr,"Connection"), PropRef ("Connection"));
2082 m.Statements.Add (stmt);
2083 stmt = Let (PropRef (expr, "CommandText"), Const (cmd.CommandText));
2084 m.Statements.Add (stmt);
2085 expr1 = PropRef (Local(typeof (CommandType).FullName), cmd.CommandType.ToString ());
2086 stmt = Let (PropRef (expr, "CommandType"), expr1);
2087 m.Statements.Add (stmt);
2089 expr1 = PropRef (expr, "Parameters");
2090 foreach (DbParameter param in cmd.Parameters) {
2091 AddDbParameterStatements (m, expr1, param);
2095 private void AddDbParameterStatements (CodeMemberMethod m,
2096 CodeExpression expr,
2099 object dbType = param.FrameworkDbType;
2100 string srcColumn = null;
2102 if (param.SourceColumn != String.Empty)
2103 srcColumn = param.SourceColumn;
2105 CodeExpression[] args = new CodeExpression[] {
2106 Const (param.ParameterName),
2107 PropRef (Local(dbType.GetType().FullName), dbType.ToString ()),
2109 PropRef(Local(typeof (ParameterDirection).FullName), param.Direction.ToString ()),
2110 Const (param.IsNullable),
2111 Const (((IDbDataParameter)param).Precision),
2112 Const (((IDbDataParameter)param).Scale),
2114 PropRef (Local (typeof (DataRowVersion).FullName), param.SourceVersion.ToString ()),
2115 /* Const (param.SourceColumnNullMapping), */ // TODO: Investigate with other providers
2118 m.Statements.Add (Eval (MethodInvoke (expr, "Add", New (param.GetType (), args))));
2120 private void CreateConnectionInitializeMethod (CodeTypeDeclaration t,
2121 TableAdapterSchemaInfo taInfo)
2123 CodeMemberMethod m = new CodeMemberMethod ();
2124 m.Name = "InitConnection";
2125 m.Attributes = MemberAttributes.Private;
2128 CodeExpression expr, expr1;
2131 // initialize connection
2132 expr = FieldRef ("_connection");
2133 stmt = Let (expr, New (taInfo.Connection.GetType ()));
2134 m.Statements.Add (stmt);
2136 // assign connection string
2137 expr = PropRef (FieldRef ("_connection"), "ConnectionString");
2138 expr1 = IndexerRef (PropRef (Local (typeof (System.Configuration.ConfigurationManager).ToString()), "ConnectionStrings"),
2139 Const (taInfo.ConnectionString));
2140 stmt = Let (expr, PropRef (expr1, "ConnectionString"));
2141 m.Statements.Add (stmt);
2146 private void CreateCommandCollectionInitializeMethod (CodeTypeDeclaration t,
2147 TableAdapterSchemaInfo taInfo)
2149 //string tmp = null;
2151 CodeMemberMethod m = new CodeMemberMethod ();
2152 m.Name = "InitCommandCollection";
2153 m.Attributes = MemberAttributes.Private;
2156 CodeExpression expr, expr1;
2159 type = ((DbCommandInfo)taInfo.Commands[0]).Command.GetType();
2161 // initialize connection
2162 expr = FieldRef ("_commandCollection");
2163 stmt = Let (expr, NewArray (type, taInfo.Commands.Count));
2164 m.Statements.Add (stmt);
2166 // loop through the collection and generate the code
2167 for (int idx = 0; idx < taInfo.Commands.Count; idx++) {
2168 DbCommand cmd = ((DbCommandInfo)taInfo.Commands[idx]).Command;
2170 expr1 = IndexerRef (expr, Const (idx));
2171 stmt = Let (expr1, New (type));
2172 m.Statements.Add (stmt);
2174 // Initialize cmd members
2175 stmt = Let (PropRef (expr1, "Connection"), PropRef ("Connection"));
2176 m.Statements.Add (stmt);
2177 stmt = Let (PropRef (expr1, "CommandText"), Const (cmd.CommandText));
2178 m.Statements.Add (stmt);
2179 stmt = Let (PropRef (expr1, "CommandType"),
2180 PropRef (Local(typeof (CommandType).FullName), cmd.CommandType.ToString ()));
2181 m.Statements.Add (stmt);
2182 expr1 = PropRef (expr1, "Parameters");
2183 foreach (DbParameter param in cmd.Parameters) {
2184 AddDbParameterStatements (m, expr1, param);
2190 private void CreateDbSourceMethods (CodeTypeDeclaration t,
2191 TableAdapterSchemaInfo taInfo)
2194 CodeMemberMethod m = null;
2195 CodeExpression expr, expr1, expr2;
2197 string tmpScalarVal = null;
2199 expr = PropRef (PropRef ("Adapter"), "SelectCommand");
2200 // loop through the collection and generate the code
2201 for (int idx = 0; idx < taInfo.Commands.Count; idx++) {
2202 DbCommandInfo cmdInfo = (DbCommandInfo)taInfo.Commands[idx];
2204 foreach (DbSourceMethodInfo mInfo in cmdInfo.Methods) {
2205 //Console.WriteLine ("Generating code for {0} method", mInfo.Name);
2207 // TODO: Add support for Fill methods
2208 if (mInfo.MethodType == GenerateMethodsType.Fill)
2211 m = new CodeMemberMethod ();
2212 m.Name = mInfo.Name;
2214 stmt = Let (expr, IndexerRef (PropRef ("CommandCollection"), Const (idx)));
2215 m.Statements.Add (stmt);
2217 switch ((MemberAttributes) Enum.Parse (typeof (MemberAttributes), mInfo.Modifier)) {
2218 case MemberAttributes.Public:
2219 m.Attributes = MemberAttributes.Public;
2222 case MemberAttributes.Private:
2223 m.Attributes = MemberAttributes.Private;
2226 case MemberAttributes.Assembly:
2227 m.Attributes = MemberAttributes.Assembly;
2230 case MemberAttributes.Family:
2231 m.Attributes = MemberAttributes.Family;
2234 //Console.WriteLine ("QueryType: {0}", mInfo.QueryType);
2235 QueryType qType = (QueryType) Enum.Parse (typeof (QueryType), mInfo.QueryType);
2237 case QueryType.Scalar:
2238 case QueryType.NoData:
2239 // executes non query and returns status
2240 m.ReturnType = TypeRef (typeof (int));
2241 AddGeneratedMethodParametersAndStatements (m, expr, cmdInfo.Command);
2243 // store connection state
2244 tmp = typeof (System.Data.ConnectionState).FullName;
2245 expr1 = PropRef (Local ("command"), "Connection");
2246 expr2 = PropRef (PropRef (Local ("System"), "Data"), "ConnectionState");
2247 stmt = VarDecl (tmp, "previousConnectionState", PropRef (expr1, "State"));
2248 m.Statements.Add (stmt);
2250 // Open connection, if its not already
2251 CodeExpression expr3 = BitOps (PropRef (expr1, "State"), PropRef (expr2, "Open"),
2252 CodeBinaryOperatorType.BitwiseAnd);
2253 stmt = new CodeConditionStatement (Inequals (expr3, PropRef (expr2, "Open")),
2254 new CodeStatement[] {Eval (MethodInvoke (expr1, "Open",
2255 new CodeExpression[] {}))},
2256 new CodeStatement[] {});
2257 m.Statements.Add (stmt);
2259 // declare return variable and execute query
2260 CodeTryCatchFinallyStatement try1 = new CodeTryCatchFinallyStatement ();
2262 if (qType == QueryType.NoData) {
2263 m.Statements.Add (VarDecl (typeof (int), "returnValue", null));
2264 expr3 = MethodInvoke (Local ("command"), "ExecuteNonQuery", new CodeExpression[] {});
2266 tmpScalarVal = mInfo.ScalarCallRetval.Substring (0, mInfo.ScalarCallRetval.IndexOf (','));
2267 m.Statements.Add (VarDecl (TypeRef (tmpScalarVal).BaseType, "returnValue", null));
2268 expr3 = MethodInvoke (Local ("command"), "ExecuteScalar", new CodeExpression[] {});
2272 try1.TryStatements.Add (Let (Local ("returnValue"), expr3));
2274 // fill finally block
2275 stmt = new CodeConditionStatement (Equals (Local ("previousConnectionState"), PropRef (expr2, "Closed")),
2276 new CodeStatement[] {Eval (MethodInvoke (expr1, "Close",
2277 new CodeExpression[] {}))},
2278 new CodeStatement[] {});
2279 try1.FinallyStatements.Add (stmt);
2280 m.Statements.Add (try1);
2283 if (qType == QueryType.NoData) {
2284 m.Statements.Add (Return (Local ("returnValue")));
2286 expr2 = Equals (Local ("returnValue"), Const (null));
2287 expr3 = Equals (MethodInvoke (Local ("returnValue"), "GetType", new CodeExpression[] {}),
2288 TypeOfRef ("System.DBNull"));
2289 stmt = new CodeConditionStatement (BooleanOps (expr2, expr3, CodeBinaryOperatorType.BooleanOr),
2290 new CodeStatement[] {Return (Const (null))},
2291 new CodeStatement[] {Return (Cast (tmpScalarVal, Local ("returnValue")))});
2292 m.Statements.Add (stmt);
2297 case QueryType.Rowset:
2298 // returns DataTable
2299 // TODO: Handle multiple DataTables
2300 tmp = opts.DataSetName (ds.DataSetName) + "." + opts.TableTypeName (ds.Tables[0].TableName);
2301 m.ReturnType = TypeRef (tmp);
2303 AddGeneratedMethodParametersAndStatements (m, expr, cmdInfo.Command);
2304 stmt = VarDecl (tmp, "dataTable", New (tmp));
2305 m.Statements.Add (stmt);
2308 expr = PropRef ("Adapter");
2309 stmt = Eval (MethodInvoke (expr, "Fill", Local ("dataTable")));
2310 m.Statements.Add (stmt);
2313 m.Statements.Add (Return (Local ("dataTable")));
2321 private void AddGeneratedMethodParametersAndStatements (CodeMemberMethod m,
2322 CodeExpression expr,
2326 CodeExpression expr1;
2329 DbType dbType = DbType.DateTime;
2330 foreach (DbParameter param in cmd.Parameters) {
2331 if (param.Direction != ParameterDirection.ReturnValue) {
2332 if (param.ParameterName[0] == '@')
2333 tmp = param.ParameterName.Substring (1);
2335 tmp = param.ParameterName;
2336 if (param.SystemType != null)
2337 m.Parameters.Add (Param (TypeRef(param.SystemType), tmp));
2338 expr1 = IndexerRef (PropRef (expr, "Parameters"), Const (idx));
2339 stmt = Let (expr1, ParamRef (tmp));
2340 m.Statements.Add (stmt);
2346 private void CreateShortCommandMethods (CodeTypeDeclaration t, TableAdapterSchemaInfo taInfo)
2359 /* =========================================================
2362 MonoDataSetGenerator API notes
2366 CreateDataSetClasses (
2370 GeneratorOptions options)
2374 *** Code naming method delegate
2376 public delegate string CodeNamingMethod (string sourceName);
2378 It is used in CodeGeneratorOptions (describled immediately below).
2382 *** Generator Options
2384 public bool MakeClassesInsideDataSet
2385 indicates whether classes and delegates other than DataSet
2386 itself are "contained" in the DataSet class or not.
2388 public CodeNamingMethod CreateDataSetName;
2389 public CodeNamingMethod CreateTableTypeName;
2390 public CodeNamingMethod CreateTableMemberName;
2391 public CodeNamingMethod CreateColumnName;
2392 public CodeNamingMethod CreateRowName;
2393 public CodeNamingMethod CreateRelationName;
2394 public CodeNamingMethod CreateTableDelegateName;
2395 public CodeNamingMethod CreateEventArgsName;
2396 Custom methods each of that returns type or member name.
2398 By default, they are set as to useTypedDataSetGenerator.
2399 CreateIdName() with modifications listed as below:
2402 TableTypeName: "DataTable" suffix
2403 TableMemberName: as is
2405 RowName: "Row" suffix
2406 RelationName: (TBD; maybe had better have another delegate type)
2407 DelegateName: "RowChangedEventHandler" suffix
2408 EventArgsName: "RowChangedEventArgs" suffix
2410 ** Auto Generated classes
2412 1. Custom DataSet class
2414 class name = dataset name, encoded by options.CreateDataSetName().
2418 public default .ctor()
2420 set custom delegate on Tables.CollectionChanged
2421 set custom delegate on Relations.CollectionChanged
2423 runtime serialization .ctor()
2428 data tables: [foo]DataTable foo { return this.table[foo]; }
2431 init variables on new dataset.
2433 *** protected members
2435 ShouldSerializeTables()
2436 returns false, while default DataSet returns true.
2437 ShouldSerializeRelations()
2438 returns false, while default DataSet returns true.
2440 ReadXmlSerializable() ... similar to runtime serialization
2443 GetSchemaSerializable()
2444 Write its schema to temporary MemoryStream
2445 Read XML schema from the stream
2447 *** internal members
2450 set member fields (tables, relations)
2451 call members' "init variables"
2454 set DataSetName, Prefix, Namespace, Locale, CaseSensitive, EnforceConstraints
2458 create FKC: new FKC([rel], new DataColumn [] {table[foo].[keyColumnName]Column}, new DataColumn [] {table[child].[childColName]Column}
2459 fill Rule properties.
2460 allocate relation[rel] and fill Nested, then Relations.Add()
2464 data tables: [foo]DataTable table[foo];
2466 data relations: DataRelation relation[rel];
2468 ShouldSerialize[foo]
2472 2. Custom DataTable classes for each DataTable
2474 This class is created under the dataset.
2476 *** internal members
2478 .ctor() : base("[foo]")
2484 DataColumn [bar]Column { return column[bar]; }
2487 fill each column fields
2491 int Count { rowcount }
2493 this [int index] { row [i]; }
2495 event [foo]RowChangedEventHandler [foo]RowChanged
2496 event [foo]RowChangedEventHandler [foo]RowChanging
2497 event [foo]RowChangedEventHandler [foo]RowDeleted
2498 event [foo]RowChangedEventHandler [foo]RowDeleting
2500 void Add[foo]Row ([foo]Row row) { Rows.Add (row); }
2502 [foo]Row Add[foo]Row ([columnType] [columnName])
2503 create new [foo]row.
2507 // non-relation-children are just created as column type
2508 // relation-children are typeof fooRow[]
2510 GetEnumerator() { Rows.GetEnumerator (); }
2512 override DataTable Clone()
2515 [foo]Row New[foo]Row()
2517 void Remove[foo]Row([foo]Row)
2519 //for each ChildRelations
2520 [bar]Row [] Get[foo_bar]Rows ()
2522 *** protected members
2524 override DataTable CreateInstance() { return new }
2526 override DataRow NewRowFromBuilder(DataRowBuilder)
2528 override Type GetRowType()
2530 override void OnRowChanged(DataRowChangedEventArgs)
2532 check this event [foo]RowChanged.
2534 override void OnRowChanging(DataRowChangedEventArgs)
2535 override void OnRowDeleted(DataRowChangedEventArgs)
2536 override void OnRowDeleting(DataRowChangedEventArgs)
2543 column[bar] = new DataColumn (...);
2547 DataColumn [bar]Column
2549 3. Custom DataRow classses
2556 get { try { } catch { throw StrongTypingException(); }
2557 set { this [[foo]Table.[bar]Column] = value; }
2560 IsNull ([foo]Table.[bar]Column);
2562 void Set[bar]Null ()
2564 if the table is parent of some relations
2566 public [child]Row [] Get[child]Rows()
2568 *** internal members
2570 .ctor(DataRowBuilder) : base.()
2575 [foo]DataTable table[foo]
2578 4. Custom DataRowChangeEvent classes
2583 DataRowAction eventAction
2587 .ctor([foo]Row row, DataRowAction action)
2591 DataRowAction Action
2595 5. public Table RowChangedEventHandler delegates
2597 [foo]RowChangedEventHandler(object, [foo]RowChangedEvent e)
2600 ======================================================== */