18 using System.Collections.Generic;
20 using System.Linq.Expressions;
28 namespace Deveel.Data.Routines {
33 container =
new Container(Rules.Default.WithResolveIEnumerableAsLazyEnumerable());
41 public abstract string SchemaName {
get; }
47 protected abstract void OnInit();
50 var parentName = name.
Parent;
51 if (parentName == null)
57 protected void Register(
FunctionInfo functionInfo, Func<InvokeContext, InvokeResult> body, Func<InvokeContext, SqlType> returnType) {
61 protected void Register(Func<IFunctionConfiguration, IFunctionConfiguration> config) {
66 config(configuration);
68 var functionInfos = configuration.FunctionInfo;
69 foreach (var functionInfo
in functionInfos) {
70 Register(functionInfo, configuration.ExecuteFunc, configuration.ReturnTypeFunc);
76 throw new ArgumentNullException(
"function");
78 var functionName =
function.FullName.FullName.ToUpperInvariant();
79 container.RegisterInstance(
function, serviceKey: functionName,reuse:Reuse.Singleton);
83 return ResolveFunction(request, query);
90 !name.ParentName.Equals(SchemaName))
93 var functionName = name.FullName.ToUpperInvariant();
94 var functions = container.ResolveMany<
IFunction>(serviceKey:functionName).ToArrayOrSelf();
95 if (functions.Length == 0)
97 if (functions.Length == 1)
100 return functions.FirstOrDefault(x => x.RoutineInfo.MatchesInvoke(invoke, query));
103 #region DelegateFunction
110 : base(functionInfo) {
111 this.functionBody = functionBody;
112 this.returnType = returnType;
116 return functionBody(context);
120 if (returnType == null)
123 return returnType(context);
129 #region FunctionConfiguration
133 private readonly Dictionary<string, RoutineParameter>
parameters;
137 this.provider = provider;
138 parameters =
new Dictionary<string, RoutineParameter>();
144 public Func<InvokeContext, SqlType> ReturnTypeFunc {
get;
private set; }
146 public Func<InvokeContext, InvokeResult> ExecuteFunc {
get;
private set; }
150 var result =
new List<FunctionInfo> {
new FunctionInfo(FunctionName, parameters.Values.ToArray()) };
151 if (aliases != null && aliases.Count > 0)
152 result.AddRange(aliases.Select(name =>
new FunctionInfo(name, parameters.Values.ToArray())));
154 return result.ToArray();
161 get {
return parameters.Values.ToArray(); }
165 return parameters.ContainsKey(name);
169 return parameters.Values.Any(x => x.IsUnbounded);
174 throw new ArgumentNullException(
"name");
178 if (!provider.SchemaName.Equals(parent))
179 throw new ArgumentException(
String.Format(
180 "The parent name ({0}) is not valid in this provider schema context ({1})", parent, provider.SchemaName));
193 throw new ArgumentNullException(
"alias");
195 if (FunctionName == null)
196 throw new ArgumentException(
"The function has no name configured and cannot be aliased.");
200 if (!provider.SchemaName.Equals(parent))
201 throw new ArgumentException();
204 aliases =
new List<ObjectName>();
213 if (config != null) {
216 var param = paramConfig.AsParameter();
218 if (
String.IsNullOrEmpty(param.Name))
219 throw new InvalidOperationException(
"A parameter must define a name.");
221 parameters.Add(param.Name, param);
228 ReturnTypeFunc = returns;
233 ExecuteFunc = execute;
238 get {
return provider; }
244 #region FunctionParemeterConfiguration
254 this.configuration = configuration;
261 if (
String.IsNullOrEmpty(name))
262 throw new ArgumentNullException(
"name");
264 if (configuration.HasParameter(name))
265 throw new ArgumentException(
String.Format(
"A parameter with name '{0}' was already configured for the function", name),
"name");
267 parameterName = name;
274 throw new ArgumentNullException(
"type");
282 if (configuration.HasUnboundedParameter())
283 throw new ArgumentException(
"An unbounded parameter is already configured");
300 GC.SuppressFinalize(
this);
303 protected virtual void Dispose(
bool disposing) {
305 if (container != null)
Provides some helper functions for resolving and creating SqlType instances that are primitive to the...
DelegateFunction(FunctionInfo functionInfo, Func< InvokeContext, InvokeResult > functionBody, Func< InvokeContext, SqlType > returnType)
readonly FunctionConfiguration configuration
List< ObjectName > aliases
The system uses instances of this interface to resolve routines given a user invocation.
IFunctionConfiguration WithParameter(Action< IFunctionParameterConfiguration > config)
Defines a routine that is a function, that means it returns a value after its execution.
A long string in the system.
A system routine that returns a value at the end of its execution.
bool HasUnboundedParameter()
void Register(Func< IFunctionConfiguration, IFunctionConfiguration > config)
override InvokeResult Execute(InvokeContext context)
Executes the function and provides a result.
IFunctionConfiguration OfType(FunctionType functionType)
IFunctionParameterConfiguration OfType(SqlType type)
void Register(IFunction function)
Describes the name of an object within a database.
The contract to define a program routine that can interact with database objects. ...
readonly Dictionary< string, RoutineParameter > parameters
readonly Func< InvokeContext, InvokeResult > functionBody
FunctionConfiguration(FunctionProvider provider)
virtual void Dispose(bool disposing)
RoutineParameter AsParameter()
virtual ObjectName NormalizeName(ObjectName name)
IFunctionConfiguration ReturnsType(Func< InvokeContext, SqlType > returns)
readonly Func< InvokeContext, SqlType > returnType
IFunctionParameterConfiguration Unbounded(bool flag)
static NumericType Numeric()
IFunctionParameterConfiguration Unbounded(bool flag)
FunctionParameterConfiguration(FunctionConfiguration configuration)
Represents the result of the execution of a routine.
The information about the invocation of a routine, including the full name and arguments (as SqlExpre...
FunctionType
The different type of a function.
Defines the properties of a specific SQL Type and handles the values compatible.
void Register(FunctionInfo functionInfo, Func< InvokeContext, InvokeResult > body, Func< InvokeContext, SqlType > returnType)
bool HasParameter(string name)
The function signature information that are used to resolve a function within a context.
IFunctionConfiguration WithAlias(ObjectName alias)
IFunctionParameterConfiguration Named(string name)
ObjectName Parent
Gets the parent reference of the current one, if any or null if none.
IFunction ResolveFunction(Invoke invoke, IQuery query)
ParameterAttributes attributes
readonly FunctionProvider provider
ObjectName RoutineName
Gets the fully qualified name of the routine to invoke.
IRoutine ResolveRoutine(Invoke request, IQuery query)
Resolves a routine that matches the given invocation within the context provided. ...
IFunctionConfiguration Named(ObjectName name)
override SqlType ReturnType(InvokeContext context)
Resolves the function return type against the given context.
IFunctionConfiguration WhenExecute(Func< InvokeContext, InvokeResult > execute)