1 // NpgsqlCommandBuilder.cs
4 // Pedro Martínez Juliá (yoros@wanadoo.es)
6 // Copyright (C) 2003 Pedro Martínez Juliá
8 // Permission is hereby granted, free of charge, to any person obtaining
9 // a copy of this software and associated documentation files (the
10 // "Software"), to deal in the Software without restriction, including
11 // without limitation the rights to use, copy, modify, merge, publish,
12 // distribute, sublicense, and/or sell copies of the Software, and to
13 // permit persons to whom the Software is furnished to do so, subject to
14 // the following conditions:
16 // The above copyright notice and this permission notice shall be
17 // included in all copies or substantial portions of the Software.
19 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
23 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
24 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
25 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 using System.Data.Common;
31 using System.ComponentModel;
36 public sealed class NpgsqlCommandBuilder : Component
39 bool disposed = false;
42 private NpgsqlDataAdapter data_adapter;
43 private NpgsqlCommand insert_command;
44 private NpgsqlCommand update_command;
45 private NpgsqlCommand delete_command;
47 private string table_name = String.Empty;
49 public NpgsqlCommandBuilder ()
52 public NpgsqlCommandBuilder (NpgsqlDataAdapter adapter)
54 DataAdapter = adapter;
55 adapter.RowUpdating += new NpgsqlRowUpdatingEventHandler(OnRowUpdating);
58 public NpgsqlDataAdapter DataAdapter {
65 if (data_adapter != null)
67 throw new InvalidOperationException ("DataAdapter is already set");
70 string select_text = data_adapter.SelectCommand.CommandText;
71 string[] words = select_text.Split(new char [] {' '});
72 bool from_found = false;
73 for (int i = 0; i < words.Length; i++)
75 if (from_found && (words[i] != String.Empty))
77 table_name = words[i];
80 if (words[i].ToLower() == "from")
88 private void OnRowUpdating(Object sender, NpgsqlRowUpdatingEventArgs value) {
89 switch (value.StatementType)
91 case StatementType.Insert:
92 value.Command = GetInsertCommand(value.Row);
94 case StatementType.Update:
95 value.Command = GetUpdateCommand(value.Row);
97 case StatementType.Delete:
98 value.Command = GetDeleteCommand(value.Row);
102 DataColumnMappingCollection columnMappings = value.TableMapping.ColumnMappings;
103 foreach (IDataParameter parameter in value.Command.Parameters)
106 string dsColumnName = parameter.SourceColumn;
107 if (columnMappings.Contains(parameter.SourceColumn))
109 DataColumnMapping mapping = columnMappings[parameter.SourceColumn];
112 dsColumnName = mapping.DataSetColumn;
116 DataRowVersion rowVersion = DataRowVersion.Default;
117 if (value.StatementType == StatementType.Update)
118 rowVersion = parameter.SourceVersion;
119 if (value.StatementType == StatementType.Delete)
120 rowVersion = DataRowVersion.Original;
121 parameter.Value = value.Row [dsColumnName, rowVersion];
123 value.Row.AcceptChanges ();
126 public string QuotePrefix {
135 public string QuoteSuffix {
144 public static void DeriveParameters (NpgsqlCommand command)
147 public NpgsqlCommand GetInsertCommand (DataRow row)
149 if (insert_command == null)
153 for (int i = 0; i < row.Table.Columns.Count; i++)
155 DataColumn column = row.Table.Columns[i];
161 fields += column.ColumnName;
162 values += ":param_" + column.ColumnName;
164 if (table_name == String.Empty)
166 table_name = row.Table.TableName;
168 NpgsqlCommand cmdaux = new NpgsqlCommand("insert into " + table_name + " (" + fields + ") values (" + values + ")", data_adapter.SelectCommand.Connection);
169 foreach (DataColumn column in row.Table.Columns)
171 NpgsqlParameter aux = new NpgsqlParameter("param_" + column.ColumnName, row[column]);
172 aux.Direction = ParameterDirection.Input;
173 aux.SourceColumn = column.ColumnName;
174 cmdaux.Parameters.Add(aux);
176 insert_command = cmdaux;
178 return insert_command;
181 public NpgsqlCommand GetUpdateCommand (DataRow row)
183 if (update_command == null)
187 for (int i = 0; i < row.Table.Columns.Count; i++)
194 DataColumn column = row.Table.Columns[i];
195 sets += String.Format("{0} = :s_param_{0}", column.ColumnName);
196 wheres += String.Format("(({0} is null) or ({0} = :w_param_{0}))", column.ColumnName);
198 if (table_name == String.Empty)
200 table_name = row.Table.TableName;
202 NpgsqlCommand cmdaux = new NpgsqlCommand("update " + table_name + " set " + sets + " where ( " + wheres + " )", data_adapter.SelectCommand.Connection);
203 foreach (DataColumn column in row.Table.Columns)
205 NpgsqlParameter aux = new NpgsqlParameter("s_param_" + column.ColumnName, row[column]);
206 aux.Direction = ParameterDirection.Input;
207 aux.SourceColumn = column.ColumnName;
208 aux.SourceVersion = DataRowVersion.Current;
209 cmdaux.Parameters.Add(aux);
211 foreach (DataColumn column in row.Table.Columns)
213 NpgsqlParameter aux = new NpgsqlParameter("w_param_" + column.ColumnName, row[column]);
214 aux.Direction = ParameterDirection.Input;
215 aux.SourceColumn = column.ColumnName;
216 aux.SourceVersion = DataRowVersion.Original;
217 cmdaux.Parameters.Add(aux);
219 update_command = cmdaux;
222 return update_command;
225 public NpgsqlCommand GetDeleteCommand (DataRow row)
227 if (delete_command == null)
230 for (int i = 0; i < row.Table.Columns.Count; i++)
232 DataColumn column = row.Table.Columns[i];
237 wheres += String.Format("(({0} is null) or ({0} = :param_{0}))", column.ColumnName);
239 if (table_name == String.Empty)
241 table_name = row.Table.TableName;
243 NpgsqlCommand cmdaux = new NpgsqlCommand("delete from " + table_name + " where ( " + wheres + " )", data_adapter.SelectCommand.Connection);
244 foreach (DataColumn column in row.Table.Columns)
246 NpgsqlParameter aux = new NpgsqlParameter("param_" + column.ColumnName, row[column,DataRowVersion.Original]);
247 aux.Direction = ParameterDirection.Input;
248 aux.SourceColumn = column.ColumnName;
249 aux.SourceVersion = DataRowVersion.Original;
250 cmdaux.Parameters.Add(aux);
252 delete_command = cmdaux;
254 return delete_command;
257 public void RefreshSchema ()
259 insert_command = null;
260 update_command = null;
261 delete_command = null;
264 protected override void Dispose (bool disposing)
270 if (insert_command != null)
272 insert_command.Dispose();
274 if (update_command != null)
276 update_command.Dispose();
278 if (delete_command != null)
280 delete_command.Dispose();
286 /*~NpgsqlCommandBuilder ()