1/* $Id: connection.hg,v 1.35 2006/11/30 06:58:55 murrayc Exp $ */
2// -*- C++ -*- //
3
4/* connection.h
5 *
6 * Copyright 2003 libgdamm Development Team
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free
20 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#include <libgdamm/transactionstatus.h>
24#include <libgdamm/connectionevent.h>
25#include <libgdamm/datamodel.h>
26#include <libgdamm/statement.h>
27#include <libgdamm/sqlbuilder.h>
28#include <libgdamm/sqlparser.h>
29#include <libgdamm/serveroperation.h>
30#include <libgdamm/serverprovider.h> //For ServerProviderError, sometimes thrown by *execute*().
31#include <libgdamm/value.h>
32
33_DEFS(libgdamm,libgda)
34_PINCLUDE(glibmm/private/object_p.h)
35
36namespace Gnome
37{
38
39namespace Gda
40{
41
42class ServerProvider;
43class MetaStore;
44typedef GdaServerProviderInfo ServerProviderInfo;
45
46/** Exception class for Gda connection errors.
47 */
48_WRAP_GERROR(ConnectionError, GdaConnectionError, GDA_CONNECTION_ERROR)
49
50_WRAP_ENUM(ConnectionOptions, GdaConnectionOptions)
51_WRAP_ENUM(ConnectionMetaType, GdaConnectionMetaType)
52
53/** Manages a connection to a data source.
54 * This class offers access to all operations involving an opened connection to a database.
55 * Connection objects are obtained via the Client class.
56 *
57 * Once obtained, applications can use a Connection to execute commands, run transactions, and get information about all
58 * objects stored in the underlying database.
59 *
60 * @ingroup Connections
61 */
62class Connection : public Glib::Object
63{
64  _CLASS_GOBJECT(Connection, GdaConnection, GDA_CONNECTION, Glib::Object, GObject)
65protected:
66
67  _CTOR_DEFAULT
68  _CUSTOM_DTOR()
69
70public:
71  _WRAP_CREATE()
72
73  _WRAP_METHOD(static Glib::RefPtr<Connection> create_from_string(const Glib::ustring& provider_name, const Glib::ustring& cnc_string, const Glib::ustring& auth_string = Glib::ustring(), ConnectionOptions options = CONNECTION_OPTIONS_NONE), gda_connection_new_from_string, errthrow)
74
75  /* This throws an error which we don't want to do in a constructor */
76  _WRAP_METHOD_DOCS_ONLY(gda_connection_open_from_string)
77  static Glib::RefPtr<Connection> open_from_string(const Glib::ustring& provider_name,
78                                                    const Glib::ustring& cnc_string,
79                                                    const Glib::ustring& auth_string = Glib::ustring(),
80                                                    ConnectionOptions options = CONNECTION_OPTIONS_NONE);
81
82  _WRAP_METHOD(bool open(), gda_connection_open, errthrow)
83
84  /** Closes the connection to the underlying data source, but first emits the "conn_to_close" signal.
85   */
86  void close();
87  _IGNORE(gda_connection_close, gda_connection_close_no_warning)
88
89  _IGNORE(gda_connection_internal_transaction_started, gda_connection_internal_savepoint_added,
90          gda_connection_internal_treat_sql, gda_connection_internal_transaction_rolledback,
91          gda_connection_internal_savepoint_removed, gda_connection_internal_transaction_committed,
92          gda_connection_internal_savepoint_rolledback, gda_connection_execute_command,
93          gda_connection_internal_sql_executed, gda_connection_internal_change_transaction_state,
94          gda_connection_internal_statement_executed, gda_connection_internal_get_provider_data,
95          gda_connection_internal_set_provider_data, gda_connection_add_prepared_statement,
96          gda_connection_del_prepared_statement, gda_connection_get_prepared_statement)
97
98  _WRAP_METHOD(bool is_opened() const, gda_connection_is_opened)
99
100  _WRAP_METHOD(ConnectionOptions get_options() const, gda_connection_get_options)
101
102  _WRAP_METHOD(Glib::ustring get_dsn() const, gda_connection_get_dsn)
103  _WRAP_METHOD(Glib::ustring get_cnc_string() const, gda_connection_get_cnc_string)
104
105  _IGNORE(gda_connection_point_available_event, gda_connection_add_event, gda_connection_add_event_string, gda_connection_clear_events_list)
106
107  _WRAP_METHOD(void clear_events_list(), gda_connection_clear_events_list)
108
109  _WRAP_METHOD_DOCS_ONLY(gda_connection_statement_execute)
110  Glib::RefPtr<Glib::Object> statement_execute(const Glib::RefPtr<const Statement>& stmt, const Glib::RefPtr<const Set>& params, StatementModelUsage model_usage, Glib::RefPtr<const Set>& last_insert_row);
111
112//TODO: Documentation:
113  Glib::RefPtr<Glib::Object> statement_execute(const Glib::RefPtr<const Statement>& stmt, StatementModelUsage model_usage = STATEMENT_MODEL_RANDOM_ACCESS);
114
115
116  Glib::RefPtr<Glib::Object> statement_execute(const Glib::ustring& sql, StatementModelUsage model_usage = STATEMENT_MODEL_RANDOM_ACCESS);
117
118  //_WRAP_METHOD(Glib::RefPtr<DataModel> statement_execute_select(const Glib::RefPtr<const Statement>& stmt, const Glib::RefPtr<const Set>& params), gda_connection_statement_execute_select, errthrow)
119  _IGNORE(gda_connection_statement_execute_select) //We instead create a version that can take an optional usage parameter too.
120
121#m4 _CONVERSION(`const std::vector<GType>&', `GType*', `const_cast<GType*>(Glib::ArrayHandler<GType>::vector_to_array($3).data())')
122  _WRAP_METHOD(Glib::RefPtr<DataModel> statement_execute_select(const Glib::RefPtr<const Statement>& stmt, const Glib::RefPtr<const Set>& params, StatementModelUsage model_usage, const std::vector<GType>& col_types), gda_connection_statement_execute_select_full, errthrow)
123  _IGNORE(gda_connection_statement_execute_select_fullv)
124
125//This custom-written method has more optional methods than gda_connection_execute_select_command().
126//TODO: Documentation:
127  Glib::RefPtr<DataModel> statement_execute_select(const Glib::RefPtr<const Statement>& stmt, StatementModelUsage model_usage = STATEMENT_MODEL_RANDOM_ACCESS);
128  Glib::RefPtr<DataModel> statement_execute_select(const Glib::ustring& sql, StatementModelUsage model_usage = STATEMENT_MODEL_RANDOM_ACCESS);
129
130//This custom-written method has more optional methods than gda_connection_execute_select_command().
131//TODO: Documentation:
132  Glib::RefPtr<DataModel> statement_execute_select(const Glib::RefPtr<const Statement>& stmt, const Glib::RefPtr<const Set>& params, StatementModelUsage model_usage = STATEMENT_MODEL_RANDOM_ACCESS);
133  Glib::RefPtr<DataModel> statement_execute_select(const Glib::ustring& sql, const Glib::RefPtr<const Set>& params, StatementModelUsage model_usage = STATEMENT_MODEL_RANDOM_ACCESS);
134  _IGNORE(gda_connection_execute_select_command)
135
136
137//TODO: Documentation:
138//Note that we add the prefix _builder() because overloading on different RefPtr<> types seems to be ambiguous.
139  Glib::RefPtr<DataModel> statement_execute_select_builder(const Glib::RefPtr<const SqlBuilder>& stmt, StatementModelUsage model_usage = STATEMENT_MODEL_RANDOM_ACCESS);
140
141//TODO: Documentation:
142//Note that we add the prefix _builder() because overloading on different RefPtr<> types seems to be ambiguous.
143  Glib::RefPtr<DataModel> statement_execute_select_builder(const Glib::RefPtr<const SqlBuilder>& stmt, const Glib::RefPtr<const Set>& params, StatementModelUsage model_usage = STATEMENT_MODEL_RANDOM_ACCESS);
144
145
146  _WRAP_METHOD_DOCS_ONLY(gda_connection_statement_execute_non_select)
147//TODO: Documentation:
148//TODO: It's not nice that these two method overloads differ only by the constness of the set.
149  int statement_execute_non_select(const Glib::RefPtr<const Statement>& stmt, const Glib::RefPtr<const Set>& params, Glib::RefPtr<const Set>& last_insert_row);
150
151//TODO: Documentation:
152  int statement_execute_non_select(const Glib::RefPtr<const Statement>& stmt, const Glib::RefPtr<const Set>& params);
153
154//TODO: Documentation:
155  int statement_execute_non_select(const Glib::RefPtr<const Statement>& stmt);
156
157  _WRAP_METHOD(int statement_execute_non_select(const Glib::ustring& sql), gda_connection_execute_non_select_command, errthrow)
158
159//TODO: Documentation:
160  int statement_execute_non_select_builder(const Glib::RefPtr<const SqlBuilder>& builder);
161
162//TODO: Documentation:
163  int statement_execute_non_select_builder(const Glib::RefPtr<const SqlBuilder>& builder, const Glib::RefPtr<const Set>& params);
164
165  _WRAP_METHOD(guint async_statement_execute(const Glib::RefPtr<const Statement>& stmt, const Glib::RefPtr<const Set>& params, StatementModelUsage model_usage, const std::vector<GType>& col_types, bool need_last_insert_row = false), gda_connection_async_statement_execute, errthrow)
166
167  //TODO: Wrap the last_insert_row parameter properly and add an overload without it:
168  _WRAP_METHOD(Glib::RefPtr<Glib::Object> async_fetch_result(guint task_id, GdaSet **last_insert_row), gda_connection_async_fetch_result, errthrow)
169  _WRAP_METHOD(bool async_cancel(guint task_id), gda_connection_async_cancel, errthrow)
170
171//TODO: #m4 _CONVERSION(`GSList*',`std::vector<Glib::Object>',`$2(Glib::SListHandler<Glib::RefPtr<const Statement> >::slist_to_vector((GSList*)$3, Glib::OWNERSHIP_DEEP))')
172//  _WRAP_METHOD(std::vector<Glib::Object> repetitive_statement_execute(GdaRepetitiveStatement *rstmt, StatementModelUsage model_usage, const std::vector<GType>& col_types, gboolean stop_on_error = true), gda_connection_repetitive_statement_execute, errthrow)
173
174  //Note that we do not add a non-const version of this because the documentation says that it should not be modified:
175  _WRAP_METHOD(Glib::RefPtr<const TransactionStatus> get_transaction_status() const, gda_connection_get_transaction_status, errthrow, refreturn)
176
177  _WRAP_METHOD(bool begin_transaction(const Glib::ustring& name, TransactionIsolation level), gda_connection_begin_transaction, errthrow)
178  _WRAP_METHOD(bool commit_transaction(const Glib::ustring& name), gda_connection_commit_transaction, errthrow)
179  _WRAP_METHOD(bool rollback_transaction(const Glib::ustring& name), gda_connection_rollback_transaction, errthrow)
180
181  _WRAP_METHOD(bool add_savepoint(const Glib::ustring& name), gda_connection_add_savepoint, errthrow)
182  _WRAP_METHOD(bool rollback_savepoint(const Glib::ustring& name), gda_connection_rollback_savepoint, errthrow)
183  _WRAP_METHOD(bool delete_savepoint(const Glib::ustring& name), gda_connection_delete_savepoint, errthrow)
184
185
186   //Use a special conversion here, because we should not own any part of the returned GList,
187   //according to the documentation for gda_connection_get_events(),
188   //and because we need to unconst the GList.:
189   #m4 _CONVERSION(`const GList*',`std::vector< Glib::RefPtr<ConnectionEvent> >',`$2(Glib::ListHandler< Glib::RefPtr<ConnectionEvent> >::list_to_vector(const_cast<GList*>($3), Glib::OWNERSHIP_NONE))')
190   #m4 _CONVERSION(`const GList*',`std::vector< Glib::RefPtr<const ConnectionEvent> >',`$2(Glib::ListHandler< Glib::RefPtr<const ConnectionEvent> >::list_to_vector(const_cast<GList*>($3), Glib::OWNERSHIP_NONE))')
191
192  _WRAP_METHOD(std::vector< Glib::RefPtr<ConnectionEvent> > get_events(), gda_connection_get_events)
193  _WRAP_METHOD(std::vector< Glib::RefPtr<const ConnectionEvent> > get_events() const, gda_connection_get_events)
194
195#m4 _CONVERSION(`const std::vector<Glib::ustring>&', `GSList*',`Glib::SListHandler<Glib::ustring>::vector_to_slist($3).data()')
196#m4 _CONVERSION(`const std::vector<Value>&', `GSList*',`Glib::SListHandler<Value, ValueTraits>::vector_to_slist($3).data()')
197  _WRAP_METHOD(bool insert_row_into_table(const Glib::ustring& table, const std::vector<Glib::ustring>& col_names, const std::vector<Value>& values), gda_connection_insert_row_into_table_v, errthrow)
198  _IGNORE(gda_connection_insert_row_into_table)
199
200  _WRAP_METHOD(bool update_row_in_table(const Glib::ustring& table, const Glib::ustring& condition_column_name, const Value& condition_value, const std::vector<Glib::ustring>& col_names, const std::vector<Value>& values), gda_connection_update_row_in_table_v, errthrow)
201
202  _WRAP_METHOD(bool delete_row_from_table(const Glib::ustring& table, const Glib::ustring& condition_column_name, const Value& condition_value), gda_connection_delete_row_from_table, errthrow)
203  _IGNORE(gda_connection_update_row_in_table)
204
205  _WRAP_METHOD(Glib::ustring value_to_sql_string(const Value& from) const, gda_connection_value_to_sql_string)
206
207  _WRAP_METHOD(bool supports_feature(ConnectionFeature feature) const, gda_connection_supports_feature)
208
209  _WRAP_METHOD(Glib::ustring get_authentication() const, gda_connection_get_authentication)
210
211  //TODO: Wrap the GdaSet** output parameter:
212  //_WRAP_METHOD(Glib::RefPtr<Statement> parse_sql_string(const Glib::ustring& sql, GdaSet** params), gda_connection_parse_sql_string, errthrow)
213
214  /** This helps to parse a SQL string.
215   *
216   * @param sql An SQL command to parse.
217   * @result A Statement representing the SQL command or an empty RefPtr if an error occurred.
218   */
219  Glib::RefPtr<Statement> parse_sql_string(const Glib::ustring& sql);
220  _IGNORE(gda_connection_parse_sql_string)
221
222  _WRAP_METHOD(Glib::RefPtr<SqlParser> create_parser(), gda_connection_create_parser)
223
224  _WRAP_METHOD(Glib::ustring get_provider_name() const, gda_connection_get_provider_name)
225
226  /** Update the full meta store information.
227   *
228   * Note that this may take some time for big databases
229   * @return <tt>true</tt> if no error occurred.
230   */
231  bool update_meta_store();
232
233  /** Update the meta store information @a id
234   *
235   * This can speed up the update of the meta store if you only need a
236   * specific information
237   * @param id An id for the information to update (see http://library.gnome.org/devel/libgda/unstable/information_schema.html)
238   * @return <tt>true</tt> if no error occurred.
239   */
240  bool update_meta_store(const Glib::ustring& id);
241  _IGNORE(gda_connection_update_meta_store)
242
243  /** Update the meta store information for the table named @a table_name
244   *
245   * This can speed up the update of the meta store if you only need the information
246   * for a specific table
247   * @param table_name Name of the table where the information is needed
248   * @param schema_name Name of the schema @table_name is in, or "" to update
249   * all tables with the given name. As with update_meta_store_table_names(),
250   * specifying a non-empty schema_name speeds up the operation, just not as
251   * significantly as with update_meta_store_table_names() because the
252   * operation itself is already pretty quick.
253   * @return <tt>true</tt> if no error occurred.
254   */
255  bool update_meta_store_table(const Glib::ustring& table_name, const Glib::ustring& schema_name = Glib::ustring());
256
257  /** Update the meta store information for the table names.
258   *
259   * This can speed up the update of the meta store if you only need the list of table names.
260   *
261   * @param schema_name Name of the schema whose tables to update, or "" to
262   * update all tables. For example, for postgresql this function takes a
263   * considerable amount of time when doing this. If you don't need
264   * information about internal postgresql tables, then you can speed up the
265   * process by only updating the tables for the "public" schema.
266   * Unfortunately, schema names are not common between different database
267   * systems.
268   * @return <tt>true</tt> if no error occurred.
269   */
270  bool update_meta_store_table_names(const Glib::ustring& schema_name = Glib::ustring());
271
272  /** Update the meta store information for the data types.
273   *
274   * This can speed up the update of the meta store if you only need the data types.
275   *
276   * @return <tt>true</tt> if no error occurred.
277   */
278  bool update_meta_store_data_types();
279
280  _WRAP_METHOD(bool statement_prepare(const Glib::RefPtr<const Statement>& stmt), gda_connection_statement_prepare, errthrow)
281
282
283  #m4 _CONVERSION(`const std::vector< Glib::RefPtr<Holder> >&',`GList*',`Glib::ListHandler< Glib::RefPtr<Holder> >::vector_to_list($3).data()')
284  _WRAP_METHOD(Glib::RefPtr<DataModel> get_meta_store_data(ConnectionMetaType meta_type, const std::vector< Glib::RefPtr<Holder> >& filters), gda_connection_get_meta_store_data_v, errthrow)
285  _IGNORE(gda_connection_get_meta_store_data)
286
287  Glib::RefPtr<DataModel> get_meta_store_data(ConnectionMetaType meta_type);
288
289  _WRAP_METHOD(Glib::RefPtr<MetaStore> get_meta_store(), gda_connection_get_meta_store, refreturn)
290  _WRAP_METHOD(Glib::RefPtr<const MetaStore> get_meta_store() const, gda_connection_get_meta_store, constversion)
291
292  #m4 _CONVERSION(`GSList*',`std::vector< Glib::RefPtr<Glib::Object> >',`$2(Glib::SListHandler< Glib::RefPtr<Glib::Object > >::slist_to_vector($3, Glib::OWNERSHIP_SHALLOW))')
293  _WRAP_METHOD(std::vector< Glib::RefPtr<Glib::Object> > batch_execute(const Glib::RefPtr<Batch>& batch, const Glib::RefPtr<const Set>& params, StatementModelUsage model_usage), gda_connection_batch_execute, errthrow)
294
295  _WRAP_METHOD(Glib::RefPtr<ServerOperation> create_operation(ServerOperationType type, const Glib::RefPtr<const Set>& options), gda_connection_create_operation, errthrow)
296  _WRAP_METHOD(bool perform_operation(const Glib::RefPtr<ServerOperation>& op), gda_connection_perform_operation, errthrow)
297
298  _WRAP_METHOD(Glib::RefPtr<ServerProvider> get_provider(), gda_connection_get_provider, refreturn)
299  _WRAP_METHOD(Glib::RefPtr<const ServerProvider> get_provider() const, gda_connection_get_provider, refreturn)
300
301  _WRAP_METHOD(Glib::ustring quote_sql_identifier(const Glib::ustring& id) const, gda_connection_quote_sql_identifier)
302
303  _WRAP_METHOD_DOCS_ONLY(gda_connection_statement_to_sql)
304
305  //TODO: What errors does this really throw? Document that in libgda.
306  //TODO: Add an overload without the params_used.
307  /** Renders a Statement as a SQL statement string, adapted to the SQL dialect used by the connection.
308   *
309   * @param stmt A Statement object.
310   * @param A Set object (which can be obtained using Statement::get_parameters()).
311   * @param flags SQL rendering flags, as StatementSqlFlag OR'ed values
312   * @param params_used A place to store the list of individual Holder objects within @a params which have been used.
313   * @throws ConnectionError
314   */
315  Glib::ustring statement_to_sql(const Glib::RefPtr<const Statement>& stmt, const Glib::RefPtr<const Set>& params, StatementSqlFlag flags, std::vector< Glib::RefPtr<Holder> >& params_used) const;
316
317  /** Renders a Statement as a SQL statement string, adapted to the SQL dialect used by the connection.
318   *
319   * @param stmt A Statement object.
320   * @param A Set object (which can be obtained using Statement::get_parameters()).
321   * @param flags SQL rendering flags, as StatementSqlFlag OR'ed values
322   * @throws ConnectionError
323   */
324  Glib::ustring statement_to_sql(const Glib::RefPtr<const Statement>& stmt, const Glib::RefPtr<const Set>& params, StatementSqlFlag flags = STATEMENT_SQL_PARAMS_AS_VALUES) const;
325
326  /** Renders a Statement as a SQL statement string, adapted to the SQL dialect used by the connection.
327   *
328   * @param stmt A Statement object..
329   * @param flags SQL rendering flags, as StatementSqlFlag OR'ed values
330   * @throws ConnectionError
331   */
332  Glib::ustring statement_to_sql(const Glib::RefPtr<const Statement>& stmt, StatementSqlFlag flags = STATEMENT_SQL_PARAMS_AS_VALUES) const;
333
334
335  _IGNORE(gda_connection_internal_reset_transaction_status)
336
337  #m4 _CONVERSION(`GdaConnectionEvent*',`const Glib::RefPtr<ConnectionEvent>&',Glib::wrap($3, true))
338  _WRAP_SIGNAL(void error(const Glib::RefPtr<ConnectionEvent>& error), "error")
339
340  _WRAP_SIGNAL(void conn_opened(), "conn_opened")
341  _WRAP_SIGNAL(void conn_to_close(), "conn_to_close")
342  _WRAP_SIGNAL(void conn_closed(), "conn_closed")
343  _WRAP_SIGNAL(void dsn_changed(), "dsn_changed")
344  _WRAP_SIGNAL(void transaction_status_changed(), "transaction_status_changed")
345
346  _WRAP_PROPERTY("provider", Glib::RefPtr<ServerProvider>)
347  _WRAP_PROPERTY("auth-string", Glib::ustring)
348  _WRAP_PROPERTY("cnc-string", Glib::ustring)
349  _WRAP_PROPERTY("dsn", Glib::ustring)
350  _WRAP_PROPERTY("meta-store", Glib::RefPtr<MetaStore>)
351  _WRAP_PROPERTY("options", ConnectionOptions)
352  _WRAP_PROPERTY("is-wrapper", bool)
353  _WRAP_PROPERTY("monitor-wrapped-in-mainloop", bool)
354  //We ignore the thread-owner property because it is strange and should only be used (well, modified) by provider implementations.
355  _WRAP_PROPERTY("events-history-size", int)
356};
357
358} // namespace Gda
359} // namespace Gnome
360