DeveelDB  20151217
complete SQL database system, primarly developed for .NET/Mono frameworks
InsertStatement.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.Linq;
20 
21 using Deveel.Data;
24 using Deveel.Data.Sql.Tables;
25 
26 namespace Deveel.Data.Sql.Statements {
28  public InsertStatement(string tableName, IEnumerable<string> columnNames, IEnumerable<SqlExpression[]> values) {
29  if (columnNames == null)
30  throw new ArgumentNullException("columnNames");
31  if (values == null)
32  throw new ArgumentNullException("values");
33  if (String.IsNullOrEmpty(tableName))
34  throw new ArgumentNullException("tableName");
35 
36  TableName = tableName;
37  ColumnNames = columnNames;
38  Values = values;
39  }
40 
41  public string TableName { get; private set; }
42 
43  public IEnumerable<string> ColumnNames { get; private set; }
44 
45  public IEnumerable<SqlExpression[]> Values { get; private set; }
46 
48  var tableName = context.Query.ResolveTableName(TableName);
49 
50  var table = context.Query.GetTable(tableName);
51  if (table == null)
52  throw new InvalidOperationException();
53 
54  if (Values.Any(x => x.OfType<SqlQueryExpression>().Any()))
55  throw new InvalidOperationException("Cannot set a value from a query.");
56 
57  var columnInfos = new List<ColumnInfo>();
58  foreach (var name in ColumnNames) {
59  var columnName = ObjectName.Parse(name);
60  var colIndex = table.FindColumn(columnName);
61  if (colIndex < 0)
62  throw new InvalidOperationException(String.Format("Cannot find column '{0}' in table '{1}'", columnName, table.FullName));
63 
64  columnInfos.Add(table.TableInfo[colIndex]);
65  }
66 
67  var assignments = new List<SqlAssignExpression[]>();
68 
69  foreach (var valueSet in Values) {
70  var valueAssign = new SqlAssignExpression[valueSet.Length];
71 
72  for (int i = 0; i < valueSet.Length; i++) {
73  var columnInfo = columnInfos[i];
74 
75  var value = valueSet[i];
76  if (value != null) {
77  // TODO: Deference columns with a preparer
78  }
79 
80  if (value != null) {
81  var expReturnType = value.ReturnType(context, null);
82  if (!columnInfo.ColumnType.IsComparable(expReturnType))
83  throw new InvalidOperationException();
84  }
85 
86  valueAssign[i] = SqlExpression.Assign(SqlExpression.Reference(columnInfo.FullColumnName), value);
87  }
88 
89  assignments.Add(valueAssign);
90  }
91 
92  return new Prepared(tableName, assignments);
93  }
94 
95  #region Prepared
96 
97  [Serializable]
99  internal Prepared(ObjectName tableName, IList<SqlAssignExpression[]> assignments) {
100  TableName = tableName;
101  Assignments = assignments;
102  }
103 
104  private Prepared(ObjectData data) {
105  TableName = data.GetValue<ObjectName>("TableName");
106  int setCount = data.GetInt32("SetCount");
107  var assignmenets = new SqlAssignExpression[setCount][];
108  for (int i = 0; i < setCount; i++) {
109  assignmenets[i] = data.GetValue<SqlAssignExpression[]>(String.Format("Assign[{0}]", i));
110  }
111 
112  Assignments = assignmenets;
113  }
114 
115  public ObjectName TableName { get; private set; }
116 
117  public IList<SqlAssignExpression[]> Assignments { get; private set; }
118 
119  protected override void GetData(SerializeData data) {
120  data.SetValue("TableName", TableName);
121 
122  int setCount = Assignments.Count;
123  data.SetValue("SetCount", setCount);
124 
125  for (int i = 0; i < setCount; i++) {
126  var set = Assignments[i];
127  data.SetValue(String.Format("Assign[{0}]", i), set);
128  }
129  }
130 
131  protected override void ExecuteStatement(ExecutionContext context) {
132  var insertCount = context.Request.Query.InsertIntoTable(TableName, Assignments);
133  context.SetResult(insertCount);
134  }
135  }
136 
137  #endregion
138 
139  #region PreparedSerializer
140 
141  //internal class PreparedSerializer : ObjectBinarySerializer<Prepared> {
142  // public override void Serialize(Prepared obj, BinaryWriter writer) {
143  // ObjectName.Serialize(obj.TableName, writer);
144 
145  // var setListCount = obj.Assignments.Count;
146  // writer.Write(setListCount);
147 
148  // for (int i = 0; i < setListCount; i++) {
149  // var set = obj.Assignments[i];
150  // var setCount = set.Length;
151 
152  // writer.Write(setCount);
153 
154  // for (int j = 0; j < setCount; j++) {
155  // SqlExpression.Serialize(obj.Assignments[i][j], writer);
156  // }
157  // }
158  // }
159 
160  // public override Prepared Deserialize(BinaryReader reader) {
161  // var tableName = ObjectName.Deserialize(reader);
162 
163  // var listCount = reader.ReadInt32();
164 
165  // var setList = new List<SqlAssignExpression[]>(listCount);
166 
167  // for (int i = 0; i < listCount; i++) {
168  // var setCount = reader.ReadInt32();
169 
170  // var exps = new SqlAssignExpression[setCount];
171 
172  // for (int j = 0; j < setCount; j++) {
173  // exps[j] = (SqlAssignExpression) SqlExpression.Deserialize(reader);
174  // }
175 
176  // setList.Add(exps);
177  // }
178 
179  // return new Prepared(tableName, setList);
180  // }
181  //}
182 
183  #endregion
184  }
185 }
override void ExecuteStatement(ExecutionContext context)
static ObjectName Parse(string s)
Parses the given string into a ObjectName object.
Definition: ObjectName.cs:139
InsertStatement(string tableName, IEnumerable< string > columnNames, IEnumerable< SqlExpression[]> values)
void SetValue(string key, Type type, object value)
Describes the name of an object within a database.
Definition: ObjectName.cs:44
static SqlAssignExpression Assign(SqlExpression reference, SqlExpression valueExpression)
Represents the foundation class of SQL statements to be executed.
Definition: SqlStatement.cs:32
static SqlBinaryExpression Add(SqlExpression left, SqlExpression right)
Prepared(ObjectName tableName, IList< SqlAssignExpression[]> assignments)
static SqlBinaryExpression Any(SqlExpression left, SqlExpressionType anyType, SqlExpression right)
static SqlReferenceExpression Reference(ObjectName objectName)
Defines the base class for instances that represent SQL expression tree nodes.