DeveelDB  20151217
complete SQL database system, primarly developed for .NET/Mono frameworks
SystemFunctionsProvider.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 
20 using Deveel.Data;
21 using Deveel.Data.Sql;
23 using Deveel.Data.Sql.Fluid;
24 using Deveel.Data.Types;
25 
26 namespace Deveel.Data.Routines {
28  public override string SchemaName {
29  get { return SystemSchema.Name; }
30  }
31 
32  protected override ObjectName NormalizeName(ObjectName functionName) {
33  if (functionName.Parent == null)
34  return new ObjectName(new ObjectName(SchemaName), functionName.Name);
35 
36  return base.NormalizeName(functionName);
37  }
38 
39  private InvokeResult Simple(InvokeContext context, Func<DataObject[], DataObject> func) {
40  var evaluated = context.EvaluatedArguments;
41  var value = func(evaluated);
42  return context.Result(value);
43  }
44 
45  private InvokeResult Binary(InvokeContext context, Func<DataObject, DataObject, DataObject> func) {
46  var evaluated = context.EvaluatedArguments;
47  var value = func(evaluated[0], evaluated[1]);
48  return context.Result(value);
49  }
50 
51  private void AddAggregateFunctions() {
52  Register(configuration => configuration
53  .Named("aggor")
54  .WithParameter(p => p.Named("args").Unbounded().OfDynamicType())
55  .OfAggregateType()
56  .WhenExecute(context => Binary(context, SystemFunctions.Or)));
57 
58  // COUNT
59  Register(config => config.Named("count")
60  .WithUnoundedParameter("args", Function.DynamicType)
61  .WhenExecute(Count.Execute)
62  .OfAggregateType()
63  .ReturnsNumeric());
64 
65  }
66 
67  private void AddSecurityFunctions() {
68  Register(config => config.Named("user")
69  .WhenExecute(context => context.Result(SystemFunctions.User(context.Request)))
70  .ReturnsString());
71  }
72 
73  private void AddConversionFunctions() {
74  Register(config => config.Named("cast")
75  .WithDynamicParameter("value")
76  .WithStringParameter("destType")
77  .WhenExecute(Cast.Execute)
78  .ReturnsType(Cast.ReturnType));
79 
80  Register(config => config.Named("tonumber")
81  .WithDynamicParameter("value")
82  .WhenExecute(context => Simple(context, args => SystemFunctions.ToNumber(args[0])))
83  .ReturnsNumeric());
84 
85  Register(config => config.Named("tostring")
86  .WithDynamicParameter("value")
87  .WhenExecute(context => Simple(context, args => SystemFunctions.ToString(args[0])))
88  .ReturnsString());
89 
90  Register(config => config.Named("tobinary")
91  .WithDynamicParameter("value")
92  .WhenExecute(context => Simple(context, args => SystemFunctions.ToBinary(args[0])))
93  .ReturnsType(PrimitiveTypes.Binary()));
94 
95  // Date Conversions
96  Register(config => config.Named("todate")
97  .WithStringParameter("value")
98  .WhenExecute(context => Simple(context, objects => SystemFunctions.ToDate(objects[0])))
99  .ReturnsType(PrimitiveTypes.Date()));
100 
101  Register(config => config.Named("todatetime")
102  .WithStringParameter("value")
103  .WhenExecute(context => Simple(context, args => SystemFunctions.ToDateTime(args[0])))
104  .ReturnsType(PrimitiveTypes.DateTime()));
105 
106  Register(config => config.Named("totimestamp")
107  .WithParameter(p => p.Named("value").OfStringType())
108  .WhenExecute(context => Simple(context, args => SystemFunctions.ToTimeStamp(args[0])))
109  .ReturnsType(PrimitiveTypes.TimeStamp()));
110  }
111 
112  private void AddSequenceFunctions() {
113  Register(config => config.Named("uniquekey")
114  .WithStringParameter("table")
115  .WhenExecute(context => Simple(context, args => SystemFunctions.UniqueKey(context.Request, args[0])))
116  .ReturnsNumeric());
117 
118  Register(config => config.Named("curval")
119  .WithStringParameter("table")
120  .WhenExecute(context => Simple(context, args => SystemFunctions.CurrentValue(context.Request, args[0])))
121  .ReturnsNumeric());
122  }
123 
124  private void AddMiscFunctions() {
125  Register(config => config.Named("iif")
126  .WithBooleanParameter("condition")
127  .WithDynamicParameter("ifTrue")
128  .WithDynamicParameter("ifFalse")
129  .WhenExecute(context => SystemFunctions.Iif(context))
130  .ReturnsType(Function.DynamicType));
131 
132  Register(config => config.Named("i_frule_convert")
133  .WithDynamicParameter("rule")
134  .WhenExecute(context => Simple(context, args => SystemFunctions.FRuleConvert(args[0])))
135  .ReturnsType(context => {
136  var argType = ReturnType(context.Arguments[0], context);
138  }));
139  }
140 
141  private static SqlType ReturnType(SqlExpression exp, InvokeContext context) {
142  return exp.ReturnType(context.Request, context.VariableResolver);
143  }
144 
145  protected override void OnInit() {
146  AddAggregateFunctions();
147 
148  AddConversionFunctions();
149  AddSecurityFunctions();
150  AddSequenceFunctions();
151 
152  AddMiscFunctions();
153  }
154 
155  #region Count
156 
157  private static class Count {
158  public static InvokeResult Execute(InvokeContext context) {
159  if (context.GroupResolver == null)
160  throw new Exception("'count' can only be used as an aggregate function.");
161 
162  int size = context.GroupResolver.Count;
163  DataObject result;
164  // if, count(*)
165  if (size == 0 || context.Invoke.IsGlobArgument) {
166  result = DataObject.Integer(size);
167  } else {
168  // Otherwise we need to count the number of non-null entries in the
169  // columns list(s).
170 
171  int totalCount = size;
172 
173  var exp = context.Arguments[0];
174  for (int i = 0; i < size; ++i) {
175  var val = exp.EvaluateToConstant(context.Request, context.GroupResolver.GetVariableResolver(i));
176  if (val.IsNull) {
177  --totalCount;
178  }
179  }
180 
181  result = DataObject.Integer(totalCount);
182  }
183 
184  return context.Result(result);
185  }
186  }
187 
188  #endregion
189 
190  #region DistinctCount
191 
192  static class DistinctCount {
193  public static InvokeResult Execute(InvokeContext context) {
194  throw new NotImplementedException();
195  }
196  }
197 
198  #endregion
199 
200  #region Cast
201 
202  static class Cast {
203  public static InvokeResult Execute(InvokeContext context) {
204  var value = context.EvaluatedArguments[0];
205  var typeArg = context.EvaluatedArguments[1];
206  var typeString = typeArg.AsVarChar().Value.ToString();
207  var type = SqlType.Parse(context.Request.Context, typeString);
208 
209  return context.Result(SystemFunctions.Cast(value, type));
210  }
211 
212  public static SqlType ReturnType(InvokeContext context) {
213  var typeArg = context.EvaluatedArguments[1];
214  var typeString = typeArg.AsVarChar().Value.ToString();
215  return SqlType.Parse(context.Request.Context, typeString);
216  }
217  }
218 
219  #endregion
220  }
221 }
Provides some helper functions for resolving and creating SqlType instances that are primitive to the...
static DataObject Integer(int value)
Definition: DataObject.cs:576
static readonly SqlType DynamicType
A special SqlType that is used to mark an argument of a function as dynamic.
Definition: Function.cs:39
static DataObject ToDate(DataObject obj)
static InvokeResult Execute(InvokeContext context)
A system routine that returns a value at the end of its execution.
Definition: Function.cs:31
static InvokeResult Iif(InvokeContext context)
IVariableResolver GetVariableResolver(int setIndex)
Returns a IVariableResolver that can be used to resolve variable in the get set of the group...
static DataObject CurrentValue(IRequest query, DataObject tableName)
SqlExpression[] Arguments
Gets the array of expressions forming the arguments of the execution.
static BinaryType Binary(int maxSize)
Invoke Invoke
Gets the information about the invoke of the routine.
static DataObject UniqueKey(IRequest query, DataObject tableName)
static DataObject Or(DataObject ob1, DataObject ob2)
Describes the name of an object within a database.
Definition: ObjectName.cs:44
static InvokeResult Execute(InvokeContext context)
ISqlObject Value
Gets the underlined value that is handled.
Definition: DataObject.cs:84
static DataObject ToBinary(DataObject value)
bool IsGlobArgument
Gets a boolean value indicating if the arguments of the invocation represent a single glob (*)...
Definition: Invoke.cs:73
InvokeResult Simple(InvokeContext context, Func< DataObject[], DataObject > func)
override ObjectName NormalizeName(ObjectName functionName)
static DataObject ToString(DataObject value)
DataObject AsVarChar()
Definition: DataObject.cs:528
static DataObject ToNumber(DataObject value)
static DataObject Cast(DataObject value, SqlType destType)
static NumericType Numeric()
Represents the result of the execution of a routine.
Definition: InvokeResult.cs:25
Represents a dynamic object that encapsulates a defined SqlType and a compatible constant ISqlObject ...
Definition: DataObject.cs:35
static DataObject ToTimeStamp(DataObject obj)
static DataObject User(IRequest query)
InvokeResult Binary(InvokeContext context, Func< DataObject, DataObject, DataObject > func)
Provides utilities and properties for handling the SYSTEN schema of a database.
Definition: SystemSchema.cs:37
Defines the properties of a specific SQL Type and handles the values compatible.
Definition: SqlType.cs:33
ObjectName Parent
Gets the parent reference of the current one, if any or null if none.
Definition: ObjectName.cs:99
static SqlType ReturnType(SqlExpression exp, InvokeContext context)
InvokeResult Result(DataObject value)
string Name
Gets the name of the object being referenced.
Definition: ObjectName.cs:108
Defines parameters uniquely identified within the query context by a name. In this form query paramet...
static SqlType ReturnType(InvokeContext context)
int Count
Gets the total number of items in this group.
Defines the base class for instances that represent SQL expression tree nodes.
const string Name
The name of the system schema that contains tables referring to system information.
static DataObject FRuleConvert(DataObject obj)
static DataObject ToDateTime(DataObject obj)
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