DeveelDB  20151217
complete SQL database system, primarly developed for .NET/Mono frameworks
RoutineManager.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.Text;
20 
21 using Deveel.Data;
22 using Deveel.Data.Sql;
24 using Deveel.Data.Sql.Tables;
26 using Deveel.Data.Types;
27 
28 namespace Deveel.Data.Routines {
30  private const string ProcedureType = "procedure";
31  private const string ExternalProcedureType = "ext_procedure";
32  private const string FunctionType = "function";
33  private const string ExtrernalFunctionType = "ext_function";
34 
36 
37  public RoutineManager(ITransaction transaction) {
38  if (transaction == null)
39  throw new ArgumentNullException("transaction");
40 
41  this.transaction = transaction;
42  }
43 
44  private ITable FindEntry(Table table, ObjectName routineName) {
45  var schemav = table.GetResolvedColumnName(0);
46  var namev = table.GetResolvedColumnName(1);
47 
48  using (var session = new SystemSession(transaction)) {
49  using (var context = session.CreateQuery()) {
50  var t = table.SimpleSelect(context, namev, SqlExpressionType.Equal,
52  t = t.ExhaustiveSelect(context,
55 
56  // This should be at most 1 row in size
57  if (t.RowCount > 1)
58  throw new Exception("Assert failed: multiple procedure names for " + routineName);
59 
60  // Return the entries found.
61  return t;
62  }
63  }
64  }
65 
66  public void Dispose() {
67  transaction = null;
68  }
69 
71  get { return DbObjectType.Routine; }
72  }
73 
74  public void Create() {
75  // SYSTEM.ROUTINE
76  var tableInfo = new TableInfo(SystemSchema.RoutineTableName);
77  tableInfo.AddColumn("schema", PrimitiveTypes.String());
78  tableInfo.AddColumn("name", PrimitiveTypes.String());
79  tableInfo.AddColumn("type", PrimitiveTypes.String());
80  tableInfo.AddColumn("location", PrimitiveTypes.String());
81  tableInfo.AddColumn("return_type", PrimitiveTypes.String());
82  tableInfo.AddColumn("username", PrimitiveTypes.String());
83  transaction.CreateTable(tableInfo);
84 
85  // SYSTEM.ROUTINE_PARAM
87  tableInfo.AddColumn("schema", PrimitiveTypes.String());
88  tableInfo.AddColumn("name", PrimitiveTypes.String());
89  tableInfo.AddColumn("arg_name", PrimitiveTypes.String());
90  tableInfo.AddColumn("arg_type", PrimitiveTypes.String());
91  tableInfo.AddColumn("in_out", PrimitiveTypes.String());
92  tableInfo.AddColumn("offset", PrimitiveTypes.Integer());
93  transaction.CreateTable(tableInfo);
94 
95  var fkCol = new[] {"routine_schema", "routine_name"};
96  var refCol = new[] {"schema", "name"};
97  const ForeignKeyAction onUpdate = ForeignKeyAction.NoAction;
98  const ForeignKeyAction onDelete = ForeignKeyAction.Cascade;
99 
100  transaction.AddForeignKey(SystemSchema.RoutineParameterTableName, fkCol, SystemSchema.RoutineTableName, refCol,
101  onDelete, onUpdate, "ROUTINE_PARAMS_FK");
102  }
103 
105  if (objInfo == null)
106  throw new ArgumentNullException("objInfo");
107 
108  var routineInfo = objInfo as RoutineInfo;
109  if (routineInfo == null)
110  throw new ArgumentException();
111 
112  CreateRoutine(routineInfo);
113  }
114 
115  public void CreateRoutine(RoutineInfo routineInfo) {
116  throw new NotImplementedException();
117  }
118 
120  return RoutineExists(objName);
121  }
122 
124  return RoutineExists(objName);
125  }
126 
127  public bool RoutineExists(ObjectName objName) {
128  // TODO: implement
129  return false;
130  }
131 
133  return GetRoutine(objName);
134  }
135 
136  public IRoutine GetRoutine(ObjectName routineName) {
137  // TODO: implement!
138  return null;
139  }
140 
142  var routineInfo = objInfo as RoutineInfo;
143  if (routineInfo == null)
144  throw new ArgumentException();
145 
146  return AlterRoutine(routineInfo);
147  }
148 
150  return DropRoutine(objName);
151  }
152 
153  public bool AlterRoutine(RoutineInfo routineInfo) {
154  // TODO: implement
155  return false;
156  }
157 
158  public bool DropRoutine(ObjectName objName) {
159  // TODO: implement
160  return false;
161  }
162 
163  public ObjectName ResolveName(ObjectName objName, bool ignoreCase) {
164  throw new NotImplementedException();
165  }
166 
167  public IRoutine ResolveRoutine(Invoke request, IQuery context) {
168  // TODO: implement
169  return null;
170  }
171 
172  #region RoutinesTableContainer
173 
176  : base(transaction, SystemSchema.RoutineTableName) {
177  }
178 
179  private static TableInfo CreateTableInfo(string schema, string name) {
180  // Create the TableInfo that describes this entry
181  var info = new TableInfo(new ObjectName(new ObjectName(schema), name));
182 
183  // Add column definitions
184  info.AddColumn("type", PrimitiveTypes.String());
185  info.AddColumn("location", PrimitiveTypes.String());
186  info.AddColumn("return_type", PrimitiveTypes.String());
187  info.AddColumn("param_args", PrimitiveTypes.String());
188  info.AddColumn("owner", PrimitiveTypes.String());
189 
190  return info.AsReadOnly();
191  }
192 
193  public override TableInfo GetTableInfo(int offset) {
194  var tableName = GetTableName(offset);
195  if (tableName == null)
196  throw new ArgumentOutOfRangeException("offset");
197 
198  return CreateTableInfo(tableName.ParentName, tableName.Name);
199  }
200 
201  public override string GetTableType(int offset) {
202  var table = GetTable(offset);
203  if (table == null)
204  throw new ArgumentOutOfRangeException("offset");
205 
206  var typeString = table.GetValue(0, 0).Value.ToString();
207  if (String.Equals(typeString, FunctionType, StringComparison.OrdinalIgnoreCase) ||
208  String.Equals(typeString, ExternalProcedureType, StringComparison.OrdinalIgnoreCase))
209  return TableTypes.Function;
210 
211  if (String.Equals(typeString, ProcedureType, StringComparison.OrdinalIgnoreCase) ||
212  String.Equals(typeString, ExternalProcedureType, StringComparison.OrdinalIgnoreCase))
213  return TableTypes.Procedure;
214 
215  throw new InvalidOperationException(String.Format("The type {0} is invalid as routine table type.", typeString));
216  }
217 
218  public override ITable GetTable(int offset) {
219  var table = Transaction.GetTable(SystemSchema.RoutineTableName);
220  var rowE = table.GetEnumerator();
221  int p = 0;
222  int i;
223  int rowI = -1;
224  while (rowE.MoveNext()) {
225  i = rowE.Current.RowId.RowNumber;
226  if (p == offset) {
227  rowI = i;
228  } else {
229  ++p;
230  }
231  }
232 
233  if (p != offset)
234  throw new ArgumentOutOfRangeException("offset");
235 
236  string schema = table.GetValue(rowI, 0).Value.ToString();
237  string name = table.GetValue(rowI, 1).Value.ToString();
238 
239  var paramTypes = GetParameterTypes(schema, name);
240 
241  var tableInfo = CreateTableInfo(schema, name);
242  var type = table.GetValue(rowI, 2);
243  var location = table.GetValue(rowI, 3);
244  var returnType = table.GetValue(rowI, 4);
245  var owner = table.GetValue(rowI, 5);
246 
247  return new RoutineTable(Transaction.Database.Context, tableInfo) {
248  Type = type,
249  Location = location,
250  ReturnType = returnType,
251  ParameterTypes = paramTypes,
252  Owner = owner
253  };
254  }
255 
256  private DataObject GetParameterTypes(string schema, string name) {
257  var table = Transaction.GetTable(SystemSchema.RoutineParameterTableName);
258  var rows = table.SelectRowsEqual(1, DataObject.String(name), 0, DataObject.String(schema));
259  var types = new List<string>();
260 
261  foreach (var rowIndex in rows) {
262  var argName = table.GetValue(rowIndex, 1);
263  var argType = table.GetValue(rowIndex, 2);
264  var inOut = table.GetValue(rowIndex, 3);
265 
266  var paramString = BuildParameterString(argName, argType, inOut);
267 
268  types.Add(paramString);
269  }
270 
271  var args = String.Join(", ", types.ToArray());
272  return DataObject.String(args);
273  }
274 
275  private string BuildParameterString(DataObject argName, DataObject argType, DataObject inOut) {
276  var sb = new StringBuilder();
277  sb.Append(argName.ToString());
278  sb.Append(" ");
279  sb.Append(argType.ToString());
280 
281  if (!inOut.IsNull)
282  sb.Append(" ")
283  .Append(inOut.Value);
284 
285  return sb.ToString();
286  }
287 
288  #region RoutineTable
289 
291  private readonly TableInfo tableInfo;
292 
293  public RoutineTable(IDatabaseContext dbContext, TableInfo tableInfo)
294  : base(dbContext) {
295  this.tableInfo = tableInfo;
296  }
297 
298  public override TableInfo TableInfo {
299  get { return tableInfo; }
300  }
301 
302  public DataObject Type { get; set; }
303 
304  public DataObject Location { get; set; }
305 
306  public DataObject ReturnType { get; set; }
307 
308  public DataObject ParameterTypes { get; set; }
309 
310  public DataObject Owner { get; set; }
311 
312  public override int RowCount {
313  get { return 1; }
314  }
315 
316  public override DataObject GetValue(long rowNumber, int columnOffset) {
317  if (rowNumber < 0 || rowNumber >= 1)
318  throw new ArgumentOutOfRangeException("rowNumber");
319 
320  switch (columnOffset) {
321  case 0:
322  return Type;
323  case 1:
324  return Location;
325  case 2:
326  return ReturnType;
327  case 3:
328  return ParameterTypes;
329  case 4:
330  return Owner;
331  default:
332  throw new ArgumentOutOfRangeException("columnOffset");
333  }
334  }
335  }
336 
337  #endregion
338  }
339 
340  #endregion
341  }
342 }
Provides some helper functions for resolving and creating SqlType instances that are primitive to the...
The system uses instances of this interface to resolve routines given a user invocation.
bool IsNull
Gets a value that indicates if this object is materialized as null.
Definition: DataObject.cs:91
bool AlterObject(IObjectInfo objInfo)
Modifies an existing object managed, identified by IObjectInfo.FullName component of the given specif...
bool DropObject(ObjectName objName)
Deletes a database object handled by this manager from the system.
Defines the contract to access the data contained into a table of a database.
Definition: ITable.cs:40
ITable FindEntry(Table table, ObjectName routineName)
A long string in the system.
The context of a single database within a system.
override DataObject GetValue(long rowNumber, int columnOffset)
Gets a single cell within the table that is located at the given column offset and row...
The system implementation of a transaction model that handles isolated operations within a database c...
Definition: Transaction.cs:35
const string Procedure
Definition: TableTypes.cs:30
bool RealObjectExists(ObjectName objName)
Checks if an object really exists in the system.
IDatabase ITransaction. Database
Definition: Transaction.cs:105
const string Function
Definition: TableTypes.cs:31
bool AlterRoutine(RoutineInfo routineInfo)
static TableInfo CreateTableInfo(string schema, string name)
Represents a database object, such as a table, a trigger, a type or a column.
Definition: IDbObject.cs:24
IRoutine ResolveRoutine(Invoke request, IQuery context)
Resolves a routine that matches the given invocation within the context provided. ...
static SqlBinaryExpression Equal(SqlExpression left, SqlExpression right)
Describes the name of an object within a database.
Definition: ObjectName.cs:44
The contract to define a program routine that can interact with database objects. ...
Definition: IRoutine.cs:26
ISqlObject Value
Gets the underlined value that is handled.
Definition: DataObject.cs:84
static DataObject String(string s)
Definition: DataObject.cs:592
override string GetTableType(int offset)
Gets the type of the table at the given offset.
SqlExpressionType
All the possible type of SqlExpression supported
ObjectName ResolveName(ObjectName objName, bool ignoreCase)
Normalizes the input object name using the case sensitivity specified.
override ITable GetTable(int offset)
Gets the table contained at the given offset within the context.
virtual ObjectName GetResolvedColumnName(int column)
Definition: Table.cs:101
ForeignKeyAction
Enumerates the foreign key referential trigger actions.
DataObject GetParameterTypes(string schema, string name)
new IDatabaseContext Context
Gets the context that contains this database.
Definition: IDatabase.cs:50
A user-defined TYPE that holds complex objects in a database column.
static readonly ObjectName RoutineTableName
void CreateObject(IObjectInfo objInfo)
Create a new object of the ObjectType given the specifications given.
Provides the constant names of the types of tables in a database system.
Definition: TableTypes.cs:24
string BuildParameterString(DataObject argName, DataObject argType, DataObject inOut)
void CreateRoutine(RoutineInfo routineInfo)
Represents a dynamic object that encapsulates a defined SqlType and a compatible constant ISqlObject ...
Definition: DataObject.cs:35
bool DropRoutine(ObjectName objName)
The information about the invocation of a routine, including the full name and arguments (as SqlExpre...
Definition: Invoke.cs:30
FunctionType
The different type of a function.
Definition: FunctionType.cs:25
IRoutine GetRoutine(ObjectName routineName)
Provides utilities and properties for handling the SYSTEN schema of a database.
Definition: SystemSchema.cs:37
bool RoutineExists(ObjectName objName)
DbObjectType ObjectType
Gets the type of objects managed by this instance.
string Name
Gets the name of the object being referenced.
Definition: ObjectName.cs:108
static SqlReferenceExpression Reference(ObjectName objectName)
RoutineTable(IDatabaseContext dbContext, TableInfo tableInfo)
IDbObject GetObject(ObjectName objName)
Gets a database object managed by this manager.
bool ObjectExists(ObjectName objName)
Checks if an object identified by the given name is managed by this instance.
Defines the metadata for a routine that are used to resolve within a context.
Definition: RoutineInfo.cs:28
override TableInfo GetTableInfo(int offset)
Gets the information of the table at the given offset in this container.
Defines the base class for instances that represent SQL expression tree nodes.
Defines the contract for the business managers of database objects of a given type.
static SqlConstantExpression Constant(object value)
void Create()
Initializes the manager into the underlying system.
The simplest implementation of a transaction.
Definition: ITransaction.cs:30
DbObjectType
The kind of objects that can be handled by a database system and its managers
Definition: DbObjectType.cs:27
Defines the metadata properties of a table existing within a database.
Definition: TableInfo.cs:41
ProcedureType
The form of a database stored PROCEDURE.
static readonly ObjectName RoutineParameterTableName
RoutineManager(ITransaction transaction)