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