1 /* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
2 
3 using System.Collections;
4 using Db4objects.Db4o.Internal;
5 using Db4objects.Db4o.Internal.Query.Processor;
6 using Db4objects.Db4o.Query;
7 using Db4objects.Db4o.Reflect;
8 
9 namespace Db4objects.Db4o.Internal.Query.Processor
10 {
11 	/// <summary>Class constraint on queries</summary>
12 	/// <exclude></exclude>
13 	public class QConClass : QConObject
14 	{
15 		[System.NonSerialized]
16 		private IReflectClass _claxx;
17 
18 		private string _className;
19 
20 		private bool i_equal;
21 
QConClass()22 		public QConClass()
23 		{
24 		}
25 
QConClass(Transaction a_trans, QCon a_parent, QField a_field, IReflectClass claxx)26 		internal QConClass(Transaction a_trans, QCon a_parent, QField a_field, IReflectClass
27 			 claxx) : base(a_trans, a_parent, a_field, null)
28 		{
29 			// C/S
30 			if (claxx != null)
31 			{
32 				_classMetadata = a_trans.Container().ProduceClassMetadata(claxx);
33 				if (claxx.Equals(a_trans.Container()._handlers.IclassObject))
34 				{
35 					_classMetadata = (ClassMetadata)_classMetadata.TypeHandler();
36 				}
37 			}
38 			_claxx = claxx;
39 		}
40 
QConClass(Transaction trans, IReflectClass claxx)41 		internal QConClass(Transaction trans, IReflectClass claxx) : this(trans, null, null
42 			, claxx)
43 		{
44 		}
45 
GetClassName()46 		public virtual string GetClassName()
47 		{
48 			return _claxx == null ? null : _claxx.GetName();
49 		}
50 
CanBeIndexLeaf()51 		public override bool CanBeIndexLeaf()
52 		{
53 			return false;
54 		}
55 
Evaluate(QCandidate a_candidate)56 		internal override bool Evaluate(QCandidate a_candidate)
57 		{
58 			bool res = true;
59 			IReflectClass claxx = a_candidate.ClassReflector();
60 			if (claxx == null)
61 			{
62 				res = false;
63 			}
64 			else
65 			{
66 				res = i_equal ? _claxx.Equals(claxx) : _claxx.IsAssignableFrom(claxx);
67 			}
68 			return i_evaluator.Not(res);
69 		}
70 
EvaluateSelf()71 		internal override void EvaluateSelf()
72 		{
73 			// optimization for simple class queries:
74 			// No instantiation of objects, if not necessary.
75 			// Does not handle the special comparison of the
76 			// Compare interface.
77 			//
78 			if (i_candidates.WasLoadedFromClassIndex())
79 			{
80 				if (i_evaluator.IsDefault())
81 				{
82 					if (!HasJoins())
83 					{
84 						if (_classMetadata != null && i_candidates.i_classMetadata != null)
85 						{
86 							if (_classMetadata.GetHigherHierarchy(i_candidates.i_classMetadata) == _classMetadata)
87 							{
88 								return;
89 							}
90 						}
91 					}
92 				}
93 			}
94 			i_candidates.Filter(this);
95 		}
96 
Equal()97 		public override IConstraint Equal()
98 		{
99 			lock (StreamLock())
100 			{
101 				i_equal = true;
102 				return this;
103 			}
104 		}
105 
IsNullConstraint()106 		internal override bool IsNullConstraint()
107 		{
108 			return false;
109 		}
110 
LogObject()111 		internal override string LogObject()
112 		{
113 			return string.Empty;
114 		}
115 
Marshall()116 		internal override void Marshall()
117 		{
118 			base.Marshall();
119 			if (_claxx != null)
120 			{
121 				_className = Container().Config().ResolveAliasRuntimeName(_claxx.GetName());
122 			}
123 		}
124 
ToString()125 		public override string ToString()
126 		{
127 			string str = "QConClass ";
128 			if (_claxx != null)
129 			{
130 				str += _claxx.GetName() + " ";
131 			}
132 			return str + base.ToString();
133 		}
134 
Unmarshall(Transaction a_trans)135 		internal override void Unmarshall(Transaction a_trans)
136 		{
137 			if (i_trans == null)
138 			{
139 				base.Unmarshall(a_trans);
140 				if (_className != null)
141 				{
142 					_className = Container().Config().ResolveAliasStoredName(_className);
143 					_claxx = a_trans.Reflector().ForName(_className);
144 				}
145 			}
146 		}
147 
SetEvaluationMode()148 		internal override void SetEvaluationMode()
149 		{
150 			IEnumerator children = IterateChildren();
151 			while (children.MoveNext())
152 			{
153 				object child = children.Current;
154 				if (child is QConObject)
155 				{
156 					((QConObject)child).SetEvaluationMode();
157 				}
158 			}
159 		}
160 
SetProcessedByIndex()161 		public override void SetProcessedByIndex()
162 		{
163 		}
164 		// do nothing, QConClass needs to stay in the evaluation graph.
165 	}
166 }
167