DeveelDB  20151217
complete SQL database system, primarly developed for .NET/Mono frameworks
SqlType.cs
Go to the documentation of this file.
1 //
2 // Copyright 2010-2015 Deveel
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 
17 using System;
18 using System.Collections.Generic;
19 using System.IO;
20 using System.Linq;
21 
23 using Deveel.Data.Sql.Parser;
24 using Deveel.Data.Sql.Objects;
25 using Deveel.Data.Store;
26 
27 namespace Deveel.Data.Types {
32  [Serializable]
33  public abstract class SqlType : IComparer<ISqlObject>, IEquatable<SqlType>, ISerializable {
43  protected SqlType(SqlTypeCode sqlType)
44  : this(sqlType.ToString().ToUpperInvariant(), sqlType) {
45  }
46 
53  protected SqlType(string name, SqlTypeCode typeCode) {
54  TypeCode = typeCode;
55  Name = name;
56  }
57 
58  protected SqlType(ObjectData data) {
59  Name = data.GetString("Name");
60  TypeCode = (SqlTypeCode) data.GetInt32("TypeCode");
61  }
62 
75  public string Name { get; private set; }
76 
91  public SqlTypeCode TypeCode { get; private set; }
92 
100  public virtual bool IsIndexable {
101  get { return true; }
102  }
103 
107  public bool IsPrimitive {
108  get { return IsPrimitiveType(TypeCode); }
109  }
110 
111  public bool IsNull {
112  get { return TypeCode == SqlTypeCode.Null; }
113  }
114 
115  public virtual bool IsStorable {
116  get { return false; }
117  }
118 
137  public virtual bool IsComparable(SqlType type) {
138  return TypeCode == type.TypeCode;
139  }
140 
153  public virtual bool CanCastTo(SqlType destType) {
154  return false;
155  }
156 
180  public virtual DataObject CastTo(DataObject value, SqlType destType) {
181  if (Equals(destType))
182  return value;
183 
184  // TODO: Should we return a null value instead? NULL OF TYPE anyway is still a cast ...
185  throw new NotSupportedException();
186  }
187 
188  public virtual object ConvertTo(ISqlObject obj, Type destType) {
189  throw new NotSupportedException();
190  }
191 
192  public virtual ISqlObject Add(ISqlObject a, ISqlObject b) {
193  return SqlNull.Value;
194  }
195 
196  public virtual ISqlObject Subtract(ISqlObject a, ISqlObject b) {
197  return SqlNull.Value;
198  }
199 
200  public virtual ISqlObject Multiply(ISqlObject a, ISqlObject b) {
201  return SqlNull.Value;
202  }
203 
204  public virtual ISqlObject Divide(ISqlObject a, ISqlObject b) {
205  return SqlNull.Value;
206  }
207 
208  public virtual ISqlObject Modulus(ISqlObject a, ISqlObject b) {
209  return SqlNull.Value;
210  }
211 
212  public virtual ISqlObject Negate(ISqlObject value) {
213  return SqlNull.Value;
214  }
215 
216  public virtual SqlBoolean IsEqualTo(ISqlObject a, ISqlObject b) {
217  if (!a.IsComparableTo(b))
218  return SqlBoolean.Null;
219 
220  return a.CompareTo(b) == 0;
221  }
222 
224  if (!a.IsComparableTo(b))
225  return SqlBoolean.Null;
226 
227  return a.CompareTo(b) != 0;
228  }
229 
231  if (!a.IsComparableTo(b))
232  return SqlBoolean.Null;
233 
234  return a.CompareTo(b) > 0;
235  }
236 
238  if (!a.IsComparableTo(b))
239  return SqlBoolean.Null;
240 
241  return a.CompareTo(b) < 0;
242  }
243 
245  if (!a.IsComparableTo(b))
246  return SqlBoolean.Null;
247 
248  return a.CompareTo(b) >= 0;
249  }
250 
252  if (!a.IsComparableTo(b))
253  return SqlBoolean.Null;
254 
255  return a.CompareTo(b) <= 0;
256  }
257 
258  public virtual ISqlObject And(ISqlObject a, ISqlObject b) {
259  return SqlBoolean.Null;
260  }
261 
262  public virtual ISqlObject Or(ISqlObject a, ISqlObject b) {
263  return SqlBoolean.Null;
264  }
265 
266  public virtual ISqlObject XOr(ISqlObject x, ISqlObject y) {
267  return SqlNull.Value;
268  }
269 
270  public virtual ISqlObject UnaryPlus(ISqlObject value) {
271  return SqlNull.Value;
272  }
273 
274  public virtual ISqlObject Reverse(ISqlObject value) {
275  return SqlNull.Value;
276  }
277 
279  data.SetValue("Name", Name);
280  data.SetValue("TypeCode", (int) TypeCode);
281  }
282 
283  protected virtual void GetData(SerializeData data) {
284  }
285 
305  public virtual SqlType Wider(SqlType otherType) {
306  return this;
307  }
308 
321  public static SqlType Parse(string s) {
322  return Parse(null, s);
323  }
324 
338  public static SqlType Parse(IContext context, string s) {
339  var sqlCompiler = SqlParsers.DataType;
340 
341  try {
342  var result = sqlCompiler.Parse(s);
343  if (result.HasErrors)
344  throw new SqlParseException(result.Errors.First().Message);
345 
346  var node = (DataTypeNode) result.RootNode;
347 
348  if (context == null && !node.IsPrimitive)
349  throw new NotSupportedException(String.Format("The type '{0}' is not primitive and no resolve context is provided.", node.TypeName));
350 
351  return DataTypeBuilder.Build(context.TypeResolver(), node);
352  } catch (SqlParseException) {
353  throw new FormatException("Unable to parse the given string to a valid data type.");
354  }
355  }
356 
358  public virtual int Compare(ISqlObject x, ISqlObject y) {
359  if (!x.IsComparableTo(y))
360  throw new NotSupportedException();
361 
362  if (x.IsNull && y.IsNull)
363  return 0;
364  if (x.IsNull && !y.IsNull)
365  return 1;
366  if (!x.IsNull && y.IsNull)
367  return -1;
368 
369  return ((IComparable) x).CompareTo(y);
370  }
371 
373  public override bool Equals(object obj) {
374  var dataType = obj as SqlType;
375  if (dataType == null)
376  return false;
377 
378  return Equals(dataType);
379  }
380 
382  public override int GetHashCode() {
383  return TypeCode.GetHashCode();
384  }
385 
387  public virtual bool Equals(SqlType other) {
388  if (other == null)
389  return false;
390 
391  return TypeCode == other.TypeCode;
392  }
393 
395  public override string ToString() {
396  return Name;
397  }
398 
399  public virtual void SerializeObject(Stream stream, ISqlObject obj) {
400  throw new NotSupportedException(String.Format("Type {0} cannot serialize object of type {1}.", GetType(),
401  obj.GetType()));
402  }
403 
404  public virtual ISqlObject DeserializeObject(Stream stream) {
405  throw new NotSupportedException(String.Format("Type {0} cannot deserialize types.", GetType()));
406  }
407 
408  public virtual bool IsCacheable(ISqlObject value) {
409  return false;
410  }
411 
412  internal virtual int GetCacheUsage(ISqlObject value) {
413  return 0;
414  }
415 
416  internal virtual int ColumnSizeOf(ISqlObject obj) {
417  // TODO: should make this required?
418  return 0;
419  }
420 
421  public virtual Type GetRuntimeType() {
422  throw new NotSupportedException();
423  }
424 
425  public virtual Type GetObjectType() {
426  throw new NotSupportedException();
427  }
428 
430  throw new NotSupportedException(String.Format("SQL Type {0} cannot be created from a large object.", TypeCode));
431  }
432 
433  public static bool IsPrimitiveType(SqlTypeCode typeCode) {
434  return PrimitiveTypes.IsPrimitive(typeCode);
435  }
436 
437  public virtual ISqlObject CreateFrom(object value) {
438  throw new NotSupportedException(String.Format("The type {0} does not support runtime object conversion.", ToString()));
439  }
440 
441  public static SqlType Resolve(SqlTypeCode typeCode) {
442  return Resolve(typeCode, new DataTypeMeta[0]);
443  }
444 
445  public static SqlType Resolve(SqlTypeCode typeCode, DataTypeMeta[] meta) {
446  return Resolve(typeCode, meta, null);
447  }
448 
449  public static SqlType Resolve(SqlTypeCode typeCode, DataTypeMeta[] meta, ITypeResolver resolver) {
450  return Resolve(typeCode, typeCode.ToString().ToUpperInvariant(), meta, resolver);
451  }
452 
453  public static SqlType Resolve(SqlTypeCode typeCode, string name) {
454  return Resolve(typeCode, name, new DataTypeMeta[0]);
455  }
456 
457  public static SqlType Resolve(SqlTypeCode typeCode, string name, DataTypeMeta[] meta) {
458  return Resolve(typeCode, name, meta, null);
459  }
460 
461  public static SqlType Resolve(string name) {
462  return Resolve(name, new DataTypeMeta[0]);
463  }
464 
465  public static SqlType Resolve(string name, DataTypeMeta[] meta) {
466  return Resolve(name, meta, null);
467  }
468 
469  public static SqlType Resolve(string name, DataTypeMeta[] meta, ITypeResolver resolver) {
470  var typeCode = ResolveTypeCode(name);
471  return Resolve(typeCode, name, meta, resolver);
472  }
473 
474  public static SqlType Resolve(SqlTypeCode typeCode, string name, DataTypeMeta[] meta, ITypeResolver resolver) {
475  return TypeResolver.Resolve(typeCode, name, meta, resolver);
476  }
477 
478  private static SqlTypeCode ResolveTypeCode(string name) {
479  var typeCode = PrimitiveTypes.ResolveTypeCode(name);
480  if (typeCode == SqlTypeCode.Unknown)
481  typeCode = SqlTypeCode.Type;
482 
483  return typeCode;
484  }
485  }
486 }
Provides some helper functions for resolving and creating SqlType instances that are primitive to the...
virtual ISqlObject XOr(ISqlObject x, ISqlObject y)
Definition: SqlType.cs:266
static readonly ISqlParser DataType
Definition: SqlParsers.cs:22
void GetData(SerializeData data)
static SqlType Resolve(SqlTypeCode typeCode, DataTypeMeta[] meta, ITypeResolver resolver)
Definition: SqlType.cs:449
A long string in the system.
virtual ISqlObject Subtract(ISqlObject a, ISqlObject b)
Definition: SqlType.cs:196
Defines a referenced object that can be accessed on a multi-phase level.
Definition: ILargeObject.cs:35
static SqlType Resolve(SqlTypeCode typeCode, string name, DataTypeMeta[] meta)
Definition: SqlType.cs:457
virtual ISqlObject UnaryPlus(ISqlObject value)
Definition: SqlType.cs:270
static SqlType Resolve(string name, DataTypeMeta[] meta, ITypeResolver resolver)
Definition: SqlType.cs:469
virtual SqlBoolean IsNotEqualTo(ISqlObject a, ISqlObject b)
Definition: SqlType.cs:223
static SqlType Resolve(SqlTypeCode typeCode, string typeName, DataTypeMeta[] metadata, ITypeResolver resolver)
Definition: TypeResolver.cs:21
virtual ISqlObject Divide(ISqlObject a, ISqlObject b)
Definition: SqlType.cs:204
virtual ISqlObject Negate(ISqlObject value)
Definition: SqlType.cs:212
virtual bool IsComparable(SqlType type)
Verifies if a given SqlType is comparable to this data-type.
Definition: SqlType.cs:137
SqlType(SqlTypeCode sqlType)
Constructs the SqlType for the given specific SQL TYPE.
Definition: SqlType.cs:43
static SqlTypeCode ResolveTypeCode(string name)
Definition: SqlType.cs:478
void SetValue(string key, Type type, object value)
virtual bool Equals(SqlType other)
Definition: SqlType.cs:387
static SqlType Build(ITypeResolver resolver, ISqlNode sqlNode)
static SqlType Resolve(string name, DataTypeMeta[] meta)
Definition: SqlType.cs:465
static bool IsPrimitiveType(SqlTypeCode typeCode)
Definition: SqlType.cs:433
SqlTypeCode TypeCode
Gets the kind of SQL type this data-type handles.
Definition: SqlType.cs:91
SqlType(string name, SqlTypeCode typeCode)
Constructs the SqlType for the given specific SQL TYPE and a given name.
Definition: SqlType.cs:53
bool IsNull
Gets a boolean value indicating if the object is NULL.
Definition: ISqlObject.cs:28
virtual SqlBoolean IsGreaterOrEqualThan(ISqlObject a, ISqlObject b)
Definition: SqlType.cs:244
virtual ISqlObject Multiply(ISqlObject a, ISqlObject b)
Definition: SqlType.cs:200
virtual SqlBoolean IsSmallerOrEqualThan(ISqlObject a, ISqlObject b)
Definition: SqlType.cs:251
static readonly SqlNull Value
Definition: SqlNull.cs:24
static SqlType Resolve(SqlTypeCode typeCode, DataTypeMeta[] meta)
Definition: SqlType.cs:445
Defines the contract for a valid SQL Object
Definition: ISqlObject.cs:23
virtual SqlBoolean IsSmallerThan(ISqlObject a, ISqlObject b)
Definition: SqlType.cs:237
virtual int GetCacheUsage(ISqlObject value)
Definition: SqlType.cs:412
virtual int ColumnSizeOf(ISqlObject obj)
Definition: SqlType.cs:416
virtual bool IsCacheable(ISqlObject value)
Definition: SqlType.cs:408
static SqlType Resolve(SqlTypeCode typeCode, string name)
Definition: SqlType.cs:453
override int GetHashCode()
Definition: SqlType.cs:382
Represents a dynamic object that encapsulates a defined SqlType and a compatible constant ISqlObject ...
Definition: DataObject.cs:35
virtual ISqlObject Reverse(ISqlObject value)
Definition: SqlType.cs:274
virtual SqlType Wider(SqlType otherType)
Gets the one data-type between this and the other one given that handles the wider range of values...
Definition: SqlType.cs:305
virtual ISqlObject Add(ISqlObject a, ISqlObject b)
Definition: SqlType.cs:192
virtual object ConvertTo(ISqlObject obj, Type destType)
Definition: SqlType.cs:188
Defines the properties of a specific SQL Type and handles the values compatible.
Definition: SqlType.cs:33
static SqlTypeCode ResolveTypeCode(string typeName)
virtual ISqlObject And(ISqlObject a, ISqlObject b)
Definition: SqlType.cs:258
override string ToString()
Definition: SqlType.cs:395
virtual void GetData(SerializeData data)
Definition: SqlType.cs:283
SqlParseResult Parse(string input)
Analyzes and parses the input and results an object that describes the parsed nodes in a tree that ca...
SqlTypeCode
Enumerates the codes of all SQL types handled by the system.
Definition: SqlTypeCode.cs:23
bool IsComparableTo(ISqlObject other)
Checks if the current object is comparable with the given one.
SqlType(ObjectData data)
Definition: SqlType.cs:58
virtual ISqlObject DeserializeObject(Stream stream)
Definition: SqlType.cs:404
virtual ISqlObject Or(ISqlObject a, ISqlObject b)
Definition: SqlType.cs:262
static SqlType Parse(IContext context, string s)
Parses a SQL formatted string that defines a data-type into a constructed SqlType object equivalent...
Definition: SqlType.cs:338
virtual void SerializeObject(Stream stream, ISqlObject obj)
Definition: SqlType.cs:399
virtual ISqlObject Modulus(ISqlObject a, ISqlObject b)
Definition: SqlType.cs:208
virtual SqlBoolean IsEqualTo(ISqlObject a, ISqlObject b)
Definition: SqlType.cs:216
static SqlType Resolve(SqlTypeCode typeCode)
Definition: SqlType.cs:441
virtual ISqlObject CreateFrom(object value)
Definition: SqlType.cs:437
virtual bool CanCastTo(SqlType destType)
Verifies if this type can cast any value to the given SqlType.
Definition: SqlType.cs:153
static bool IsPrimitive(SqlTypeCode sqlType)
Describes the information of a data type as found in a SQL string.
Definition: DataTypeNode.cs:28
An error that occurs when compiling a input string into a SQL object.
virtual int Compare(ISqlObject x, ISqlObject y)
Definition: SqlType.cs:358
virtual Type GetRuntimeType()
Definition: SqlType.cs:421
virtual DataObject CastTo(DataObject value, SqlType destType)
Converts the given object value to a SqlType specified.
Definition: SqlType.cs:180
virtual SqlBoolean IsGreatherThan(ISqlObject a, ISqlObject b)
Definition: SqlType.cs:230
virtual Type GetObjectType()
Definition: SqlType.cs:425
override bool Equals(object obj)
Definition: SqlType.cs:373
static SqlType Resolve(SqlTypeCode typeCode, string name, DataTypeMeta[] meta, ITypeResolver resolver)
Definition: SqlType.cs:474
static SqlType Parse(string s)
Parses a SQL formatted string that defines a data-type into a constructed SqlType object equivalent...
Definition: SqlType.cs:321
static SqlType Resolve(string name)
Definition: SqlType.cs:461
virtual ISqlObject CreateFromLargeObject(ILargeObject objRef)
Definition: SqlType.cs:429