Datei: NDODLL/SqlPersistenceHandling/FromGenerator.cs

Last Commit (b95968d)
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using NDOql.Expressions;
6 using NDO.Mapping;
7 using NDO.Query.JoinExpressions;
8
9 namespace NDO.SqlPersistenceHandling
10 {
11 ····/// <summary>
12 ····/// Helper class to generate Column names of the select statement
13 ····/// </summary>
14 ····internal class FromGenerator
15 ····{
16 ········Class cls;
17 ········Dictionary<Relation, Class> relationContext;
18 ········NDOMapping mappings;
19 ········static readonly string anKey = "from";
20
21 ········internal FromGenerator( Class cls, Dictionary<Relation, Class> relationContext )
22 ········{
23 ············this.cls = cls;
24 ············this.mappings = cls.Parent;
25 ············this.relationContext = relationContext;
26 ········}
27
28 ········internal string GenerateFromExpression(OqlExpression expressionTree, List<Relation> prefetchRelations = null)
29 ········{
30 ············StringBuilder sb = new StringBuilder();
31 ············AnnotateExpressionTree( expressionTree, prefetchRelations );
32 ············if (expressionTree != null)
33 ············{
34 ················List<IdentifierExpression> identifiers = expressionTree.GetAll( e => e is IdentifierExpression && !String.Empty.Equals( e.GetAnnotation<string>(anKey) ) ).Select( e => (IdentifierExpression)e ).ToList();
35 ················identifiers.Sort( ( i1, i2 ) => ((string)i1.Value).CompareTo( (string)i2.Value ) );
36 ················bool isFirst = true;
37 ················foreach (IdentifierExpression exp in identifiers)
38 ················{
39 ····················if (!String.IsNullOrEmpty( exp.GetAnnotation<string>(anKey) ))
40 ····················{
41 ························if (isFirst)
42 ························{
43 ····························sb.Append( ' ' );
44 ····························isFirst = false;
45 ························}
46 ························sb.Append( exp.GetAnnotation<string>( anKey ) );
47 ························sb.Append( ' ' );
48 ····················}
49 ················}
50
51 ················if (sb.Length > 0)
52 ················{
53 ····················sb.Length--;
54 ················}
55 ············}
56 ············return "FROM " + cls.GetQualifiedTableName() + sb.ToString();
57 ········}
58
59 ········private void AnnotateExpressionTree( OqlExpression expressionTree, List<Relation> prefetchRelations )
60 ········{
61 ············HashSet<Relation> allJoins = new HashSet<Relation>();
62 ············if (prefetchRelations != null)
63 ············{
64 ················// if a prefetch relation is bidirectional,
65 ················// this will prevent adding the relation into the joins twice
66 ················foreach(var rel in prefetchRelations)
67 ················allJoins.Add( rel );
68 ················// We know, that this must be a prefetch, so the direction
69 ················// of the relation is reversed.
70 #warning Hier muss noch die Annotation rein
 
71 ············}
72
73 ············if (expressionTree == null)
74 ················return;
75
76 ············foreach (IdentifierExpression exp in expressionTree.GetAll( e => e is IdentifierExpression ))
77 ············{
78 ················string fullName = (string)exp.Value;
79 ················if (fullName.IndexOf( '.' ) < 0)
80 ····················continue;
81
82 ················StringBuilder sb = new StringBuilder();
83 ················string[] arr = ((string)exp.Value).Split( '.' );
84 ················Class startClass = this.cls;
85 ················bool isFirst = true;
86
87 ················for (int i = 0; i < arr.Length - 1; i++)··// at least the last element is the field name
88 ················{
89 ····················string relationName = arr[i];
90
91 ····················if (relationName == "oid")
92 ························break;
93
94 ····················Relation relation = startClass.FindRelation( relationName );
95
96 ····················if (relation == null)
97 ························break;
98
99 ····················if (allJoins.Contains( relation ))
100 ························continue;
101
102 ····················allJoins.Add( relation );
103
104 ····················Class childClass = this.relationContext.ContainsKey( relation )
105 ························? this.relationContext[relation]
106 ························: this.mappings.FindClass( relation.ReferencedType );
107
108 ····················if (!isFirst)
109 ························sb.Append( ' ' );
110
111 ····················// In the cases where the following condition doesn't apply, we don't need the join to the table of the class owning the oid.
112 ····················// It's sufficient to compare against the foreign keys stored in the owner class' table.
113 ····················if ((relation.Multiplicity == RelationMultiplicity.List || relation.MappingTable != null) || arr[i + 1] != "oid")
114 ························sb.Append( new InnerJoinExpression( relation, this.relationContext, arr[i + 1] == "oid" ).ToString() );
115
116 ····················startClass = childClass;
117 ····················isFirst = false;
118 ················}
119 ················string join = sb.ToString();
120 ················exp.SetAnnotation( anKey, join );
121 ············}
122 ········}
123 ····}
124 }
125
New Commit (42d0ae7)
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using NDOql.Expressions;
6 using NDO.Mapping;
7 using NDO.Query.JoinExpressions;
8
9 namespace NDO.SqlPersistenceHandling
10 {
11 ····/// <summary>
12 ····/// Helper class to generate Column names of the select statement
13 ····/// </summary>
14 ····internal class FromGenerator
15 ····{
16 ········Class cls;
17 ········Dictionary<Relation, Class> relationContext;
18 ········NDOMapping mappings;
19 ········static readonly string anKey = "from";
20
21 ········internal FromGenerator( Class cls, Dictionary<Relation, Class> relationContext )
22 ········{
23 ············this.cls = cls;
24 ············this.mappings = cls.Parent;
25 ············this.relationContext = relationContext;
26 ········}
27
28 ········internal string GenerateFromExpression(OqlExpression expressionTree, List<Relation> prefetchRelations = null)
29 ········{
30 ············StringBuilder sb = new StringBuilder();
31 ············AnnotateExpressionTree( expressionTree, prefetchRelations );
32 ············if (expressionTree != null)
33 ············{
34 ················List<IdentifierExpression> identifiers = expressionTree.GetAll( e => e is IdentifierExpression && !String.Empty.Equals( e.GetAnnotation<string>(anKey) ) ).Select( e => (IdentifierExpression)e ).ToList();
35 ················identifiers.Sort( ( i1, i2 ) => ((string)i1.Value).CompareTo( (string)i2.Value ) );
36 ················bool isFirst = true;
37 ················foreach (IdentifierExpression exp in identifiers)
38 ················{
39 ····················if (!String.IsNullOrEmpty( exp.GetAnnotation<string>(anKey) ))
40 ····················{
41 ························if (isFirst)
42 ························{
43 ····························sb.Append( ' ' );
44 ····························isFirst = false;
45 ························}
46 ························sb.Append( exp.GetAnnotation<string>( anKey ) );
47 ························sb.Append( ' ' );
48 ····················}
49 ················}
50
51 ················if (sb.Length > 0)
52 ················{
53 ····················sb.Length--;
54 ················}
55 ············}
56 ············return "FROM " + cls.GetQualifiedTableName() + sb.ToString();
57 ········}
58
59 ········private void AnnotateExpressionTree( OqlExpression expressionTree, List<Relation> prefetchRelations )
60 ········{
61 ············HashSet<Relation> allJoins = new HashSet<Relation>();
62 ············if (prefetchRelations != null)
63 ············{
64 ················// if a prefetch relation is bidirectional,
65 ················// this will prevent adding the relation into the joins twice
66 ················foreach(var rel in prefetchRelations)
67 ················allJoins.Add( rel );
68 ················// We know, that this must be a prefetch, so the direction
69 ················// of the relation is reversed.
70
71 ················//TODO: We need to implement the annotation here.
72 ············}
73
74 ············if (expressionTree == null)
75 ················return;
76
77 ············foreach (IdentifierExpression exp in expressionTree.GetAll( e => e is IdentifierExpression ))
78 ············{
79 ················string fullName = (string)exp.Value;
80 ················if (fullName.IndexOf( '.' ) < 0)
81 ····················continue;
82
83 ················StringBuilder sb = new StringBuilder();
84 ················string[] arr = ((string)exp.Value).Split( '.' );
85 ················Class startClass = this.cls;
86 ················bool isFirst = true;
87
88 ················for (int i = 0; i < arr.Length - 1; i++)··// at least the last element is the field name
89 ················{
90 ····················string relationName = arr[i];
91
92 ····················if (relationName == "oid")
93 ························break;
94
95 ····················Relation relation = startClass.FindRelation( relationName );
96
97 ····················if (relation == null)
98 ························break;
99
100 ····················if (allJoins.Contains( relation ))
101 ························continue;
102
103 ····················allJoins.Add( relation );
104
105 ····················Class childClass = this.relationContext.ContainsKey( relation )
106 ························? this.relationContext[relation]
107 ························: this.mappings.FindClass( relation.ReferencedType );
108
109 ····················if (!isFirst)
110 ························sb.Append( ' ' );
111
112 ····················// In the cases where the following condition doesn't apply, we don't need the join to the table of the class owning the oid.
113 ····················// It's sufficient to compare against the foreign keys stored in the owner class' table.
114 ····················if ((relation.Multiplicity == RelationMultiplicity.List || relation.MappingTable != null) || arr[i + 1] != "oid")
115 ························sb.Append( new InnerJoinExpression( relation, this.relationContext, arr[i + 1] == "oid" ).ToString() );
116
117 ····················startClass = childClass;
118 ····················isFirst = false;
119 ················}
120 ················string join = sb.ToString();
121 ················exp.SetAnnotation( anKey, join );
122 ············}
123 ········}
124 ····}
125 }
126