/* * Blob read request */ static glong gda_web_blob_op_read (GdaBlobOp *op, GdaBlob *blob, glong offset, glong size) { GdaWebBlobOp *bop; GdaBinary *bin; g_return_val_if_fail (GDA_IS_WEB_BLOB_OP (op), -1); bop = GDA_WEB_BLOB_OP (op); g_return_val_if_fail (bop->priv, -1); g_return_val_if_fail (GDA_IS_CONNECTION (bop->priv->cnc), -1); if (offset >= G_MAXINT) return -1; g_return_val_if_fail (blob, -1); bin = (GdaBinary *) blob; if (bin->data) g_free (bin->data); bin->data = g_new0 (guchar, size); bin->binary_length = 0; /* fetch blob data using C API into bin->data, and set bin->binary_length */ TO_IMPLEMENT; return bin->binary_length; }
int main(int argc, char *argv[]) { const gchar* connection_string = "HOST=localhost;USER=murrayc;PASSWORD=yourpasswordhere;DATABASE=template1"; GdaClient *client = 0; GdaConnection *con = 0; gda_init ("glom-gda-test", NULL, argc, argv); /* 3. Create a gda client */ client = gda_client_new (); /* 4. Open the connection */ con = gda_client_open_connection_from_string (client, "PostgreSQL", connection_string, 0); if (!GDA_IS_CONNECTION (con)) { g_print ("** ERROR: could not open connection.\n"); /* This cannot work because it needs a working connection: get_errors (con); */ return 0; } gboolean created = gda_connection_create_database(con, "glomtest"); if(!created) { g_print("** Error: gda_connection_create_database failed.\n"); get_errors(con); } gda_connection_close (con); g_object_unref (G_OBJECT (client)); g_print ("** Connection successfully opened, database created, and connection closed.\n"); return 0; }
/** * gda_xa_transaction_register_connection: * @xa_trans: a #GdaXaTransaction object * @cnc: the connection to add to @xa_trans * @branch: the branch qualifier * @error: (allow-none): a place to store errors, or %NULL * * Registers @cnc to be used by @xa_trans to create a distributed transaction. * * Note: any #GdaConnection object can only be registered with at most one #GdaXaTransaction object; also * some connections may not be registered at all with a #GdaXaTransaction object because the database * provider being used does not support it. * * Returns: %TRUE if no error occurred */ gboolean gda_xa_transaction_register_connection (GdaXaTransaction *xa_trans, GdaConnection *cnc, const gchar *branch, GError **error) { GdaBinary *bin; g_return_val_if_fail (GDA_IS_XA_TRANSACTION (xa_trans), FALSE); g_return_val_if_fail (GDA_IS_CONNECTION (cnc), FALSE); g_return_val_if_fail (branch && *branch, FALSE); if (strlen (branch) >= 64) { g_set_error (error, GDA_XA_TRANSACTION_ERROR, GDA_XA_TRANSACTION_CONNECTION_BRANCH_LENGTH_ERROR, "%s", _("Connection branch cannot exceed 63 bytes")); return FALSE; } const GdaBinary *ebranch = g_hash_table_lookup (xa_trans->priv->cnc_hash, cnc); if (ebranch) { bin = g_new0 (GdaBinary, 1); bin->data = (guchar*) g_strdup (branch); bin->binary_length = strlen (branch) + 1; g_hash_table_insert (xa_trans->priv->cnc_hash, cnc, bin); return TRUE; } /* check that @cnc is not already registered with another GdaXaTransaction object */ if (g_object_get_data (G_OBJECT (cnc), "_gda_xa_transaction")) { g_set_error (error, GDA_XA_TRANSACTION_ERROR, GDA_XA_TRANSACTION_ALREADY_REGISTERED_ERROR, "%s", _("Connection already registered with another GdaXaTransaction object")); return FALSE; } /* check that connection supports distributed transaction, only ONE connection in @xa_trans is allowed * to not support them */ GdaServerProvider *prov; prov = gda_connection_get_provider (cnc); if (!gda_server_provider_supports_feature (prov, cnc, GDA_CONNECTION_FEATURE_XA_TRANSACTIONS)) { /* if another connection does not support distributed transaction, then there is an error */ if (xa_trans->priv->non_xa_cnc) { g_set_error (error, GDA_XA_TRANSACTION_ERROR, GDA_XA_TRANSACTION_DTP_NOT_SUPPORTED_ERROR, "%s", _("Connection does not support distributed transaction")); return FALSE; } else xa_trans->priv->non_xa_cnc = cnc; } bin = g_new0 (GdaBinary, 1); bin->data = (guchar*) g_strdup (branch); bin->binary_length = strlen (branch) + 1; xa_trans->priv->cnc_list = g_list_prepend (xa_trans->priv->cnc_list, cnc); g_hash_table_insert (xa_trans->priv->cnc_hash, cnc, bin); g_object_ref (cnc); g_object_set_data (G_OBJECT (cnc), "_gda_xa_transaction", xa_trans); return TRUE; }
/* * Removes any #GdaServerProviderHandlerInfo associated to @cnc */ void _gda_server_provider_handlers_clear_for_cnc (GdaServerProvider *prov, GdaConnection *cnc) { g_return_if_fail (GDA_IS_SERVER_PROVIDER (prov)); g_return_if_fail (GDA_IS_CONNECTION (cnc)); g_hash_table_foreach_remove (prov->priv->data_handlers, (GHRFunc) handlers_clear_for_cnc_fh, cnc); }
GdaConnectionEvent * _gda_firebird_make_error (GdaConnection *cnc, const gint statement_type) { FirebirdConnectionData *cdata; GdaConnectionEvent *error_ev; g_return_val_if_fail (GDA_IS_CONNECTION (cnc), NULL); cdata = (FirebirdConnectionData*) gda_connection_internal_get_provider_data_error (cnc, NULL); if (!cdata) return NULL; error_ev = gda_connection_point_available_event (cnc, GDA_CONNECTION_EVENT_ERROR); gda_connection_event_set_code (error_ev, isc_sqlcode (cdata->status)); ISC_SCHAR *description; const ISC_STATUS *p = cdata->status; description = g_new0 (ISC_SCHAR, 512); fb_interpret (description, 511, &p); g_print ("MAKE_ERROR [%s]\n", description); gda_connection_event_set_source (error_ev, "[GDA Firebird]"); gda_connection_event_set_description (error_ev, description); gda_connection_add_event (cnc, error_ev); g_free (description); return error_ev; }
/** * gda_report_engine_declare_object * @engine: a #GdaReportEngine object * @object: a #GObject to declare * @obj_name: the name to give to @object within @engine * * Declares an object which will be used in @engine, referenced by the @obj_name name. * * @object must be of a supported types, that it must be a #GdaConnection, #GdaStatement or #GdaHolder object. */ void gda_report_engine_declare_object (GdaReportEngine *engine, GObject *object, const gchar *obj_name) { gchar prefix, *real_name; GObject *current_obj; g_return_if_fail (GDA_IS_REPORT_ENGINE (engine)); g_return_if_fail (engine->priv); g_return_if_fail (G_IS_OBJECT (object)); g_return_if_fail (obj_name); if (GDA_IS_STATEMENT (object)) prefix = 'S'; else if (GDA_IS_CONNECTION (object)) prefix = 'C'; else if (GDA_IS_HOLDER (object)) prefix = 'H'; else { g_warning (_("Object type '%s' cannot be declared in this context"), G_OBJECT_TYPE_NAME (object)); return; } real_name = g_strdup_printf ("%c%s", prefix, obj_name); current_obj = g_hash_table_lookup (engine->priv->objects, real_name); if (current_obj) { if (current_obj != object) g_warning (_("An object with the '%s' name has already been declared"), obj_name); } else { /*g_print ("%s(): declared %p as %s\n", __FUNCTION__, object, real_name);*/ g_hash_table_insert (engine->priv->objects, real_name, object); g_object_ref (object); } }
/** * gda_tree_mgr_schemas_new: * @cnc: a #GdaConnection object * * Creates a new #GdaTreeManager object which will add one tree node for each database schema found * in @cnc. * * Returns: (transfer full): a new #GdaTreeManager object * * Since: 4.2 */ GdaTreeManager* gda_tree_mgr_schemas_new (GdaConnection *cnc) { GdaTreeMgrSchemas *mgr; g_return_val_if_fail (GDA_IS_CONNECTION (cnc), NULL); mgr = (GdaTreeMgrSchemas*) g_object_new (GDA_TYPE_TREE_MGR_SCHEMAS, "connection", cnc, NULL); return (GdaTreeManager*) mgr; }
/** * gda_tree_mgr_columns_new: * @cnc: a #GdaConnection object * @schema: a schema name * @table_name: the name of the table * * Creates a new #GdaTreeManager object which will add one tree node for each * column in the table named @table_name in the @schema schema. * * Returns: (transfer full): a new #GdaTreeManager object * * Since: 4.2 */ GdaTreeManager* gda_tree_mgr_columns_new (GdaConnection *cnc, const gchar *schema, const gchar *table_name) { GdaTreeMgrColumns *mgr; g_return_val_if_fail (GDA_IS_CONNECTION (cnc), NULL); mgr = (GdaTreeMgrColumns*) g_object_new (GDA_TYPE_TREE_MGR_COLUMNS, "connection", cnc, "schema", schema, "table-name", table_name, NULL); return (GdaTreeManager*) mgr; }
GdaBlobOp * gda_web_blob_op_new (GdaConnection *cnc) { GdaWebBlobOp *bop; g_return_val_if_fail (GDA_IS_CONNECTION (cnc), NULL); bop = g_object_new (GDA_TYPE_WEB_BLOB_OP, "connection", cnc, NULL); bop->priv->cnc = cnc; return GDA_BLOB_OP (bop); }
GdaBlobOp * gda_mysql_blob_op_new (GdaConnection *cnc) { GdaMysqlBlobOp *pgop; g_return_val_if_fail (GDA_IS_CONNECTION (cnc), NULL); pgop = g_object_new (GDA_TYPE_MYSQL_BLOB_OP, "connection", cnc, NULL); pgop->priv->cnc = cnc; return GDA_BLOB_OP (pgop); }
GdaBlobOp * gda_oracle_blob_op_new (GdaConnection *cnc, OCILobLocator *lobloc) { GdaOracleBlobOp *bop; g_return_val_if_fail (GDA_IS_CONNECTION (cnc), NULL); bop = g_object_new (GDA_TYPE_ORACLE_BLOB_OP, "connection", cnc, NULL); bop->priv->cnc = cnc; return GDA_BLOB_OP (bop); }
/* * Get length request */ static glong gda_oracle_blob_op_get_length (GdaBlobOp *op) { GdaOracleBlobOp *bop; g_return_val_if_fail (GDA_IS_ORACLE_BLOB_OP (op), -1); bop = GDA_ORACLE_BLOB_OP (op); g_return_val_if_fail (bop->priv, -1); g_return_val_if_fail (GDA_IS_CONNECTION (bop->priv->cnc), -1); TO_IMPLEMENT; return -1; }
/** * gda_tree_mgr_select_new: * @cnc: a #GdaConnection object * @stmt: a #GdaStatement object representing a SELECT statement * @params: a #GdaSet object representing fixed parameters which are to be used when executing @stmt * * Creates a new #GdaTreeMgrSelect object which will add one tree node for each row in * the #GdaDataModel resulting from the execution of @stmt. * * Returns: (transfer full): a new #GdaTreeManager object * * Since: 4.2 */ GdaTreeManager* gda_tree_mgr_select_new (GdaConnection *cnc, GdaStatement *stmt, GdaSet *params) { g_return_val_if_fail (GDA_IS_CONNECTION (cnc), NULL); g_return_val_if_fail (GDA_IS_STATEMENT (stmt), NULL); g_return_val_if_fail (gda_statement_get_statement_type (stmt) == GDA_SQL_STATEMENT_SELECT, NULL); g_return_val_if_fail (!params || GDA_IS_SET (params), NULL); return (GdaTreeManager*) g_object_new (GDA_TYPE_TREE_MGR_SELECT, "connection", cnc, "statement", stmt, "params", params, NULL); }
/* * Get length request */ static glong gda_mysql_blob_op_get_length (GdaBlobOp *op) { GdaMysqlBlobOp *pgop; g_return_val_if_fail (GDA_IS_MYSQL_BLOB_OP (op), -1); pgop = GDA_MYSQL_BLOB_OP (op); g_return_val_if_fail (pgop->priv, -1); g_return_val_if_fail (GDA_IS_CONNECTION (pgop->priv->cnc), -1); TO_IMPLEMENT; return -1; }
/* * Get length request */ static glong gda_web_blob_op_get_length (GdaBlobOp *op) { GdaWebBlobOp *bop; g_return_val_if_fail (GDA_IS_WEB_BLOB_OP (op), -1); bop = GDA_WEB_BLOB_OP (op); g_return_val_if_fail (bop->priv, -1); g_return_val_if_fail (GDA_IS_CONNECTION (bop->priv->cnc), -1); TO_IMPLEMENT; return -1; }
/** * midgard_connection_close: * @self: #MidgardConnection instance * * Closes connection to underlying storage. * All private and public data remains unchanged, so connection might be reopened at any time. * After closing connection, 'disconnected' signal is emitted. * * Since: 10.05.1 */ void midgard_connection_close (MidgardConnection *self) { g_return_if_fail (self != NULL); if (!self->priv->connection || (!GDA_IS_CONNECTION (self->priv->connection))) return; gda_connection_close_no_warning (self->priv->connection); g_signal_emit (self, MIDGARD_CONNECTION_GET_CLASS (self)->signal_id_disconnected, 0); return; }
/* * Blob write request */ static glong gda_web_blob_op_write (GdaBlobOp *op, GdaBlob *blob, G_GNUC_UNUSED glong offset) { GdaWebBlobOp *bop; GdaBinary *bin; glong nbwritten = -1; g_return_val_if_fail (GDA_IS_WEB_BLOB_OP (op), -1); bop = GDA_WEB_BLOB_OP (op); g_return_val_if_fail (bop->priv, -1); g_return_val_if_fail (GDA_IS_CONNECTION (bop->priv->cnc), -1); g_return_val_if_fail (blob, -1); if (blob->op && (blob->op != op)) { /* use data through blob->op */ #define buf_size 16384 gint nread = 0; GdaBlob *tmpblob = g_new0 (GdaBlob, 1); gda_blob_set_op (tmpblob, blob->op); nbwritten = 0; for (nread = gda_blob_op_read (tmpblob->op, tmpblob, nbwritten, buf_size); nread > 0; nread = gda_blob_op_read (tmpblob->op, tmpblob, nbwritten, buf_size)) { glong tmp_written; tmp_written = -1; TO_IMPLEMENT; if (tmp_written < 0) { /* treat error */ gda_blob_free ((gpointer) tmpblob); return -1; } nbwritten += tmp_written; if (nread < buf_size) /* nothing more to read */ break; } gda_blob_free ((gpointer) tmpblob); } else { /* write blob using bin->data and bin->binary_length */ bin = (GdaBinary *) blob; g_warning("bin not used. length=%ld", bin->binary_length); /* Avoids a compiler warning. */ nbwritten = -1; TO_IMPLEMENT; } return nbwritten; }
/* * Blob write request */ static glong gda_oracle_blob_op_write (GdaBlobOp *op, GdaBlob *blob, glong offset) { GdaOracleBlobOp *bop; glong nbwritten = -1; g_return_val_if_fail (GDA_IS_ORACLE_BLOB_OP (op), -1); bop = GDA_ORACLE_BLOB_OP (op); g_return_val_if_fail (bop->priv, -1); g_return_val_if_fail (GDA_IS_CONNECTION (bop->priv->cnc), -1); g_return_val_if_fail (blob, -1); if (blob->op && (blob->op != op)) { /* use data through blob->op */ #define buf_size 16384 gint nread = 0; GdaBlob *tmpblob = g_new0 (GdaBlob, 1); gda_blob_set_op (tmpblob, blob->op); nbwritten = 0; for (nread = gda_blob_op_read (tmpblob->op, tmpblob, nbwritten, buf_size); nread > 0; nread = gda_blob_op_read (tmpblob->op, tmpblob, nbwritten, buf_size)) { glong tmp_written; tmp_written = -1; TO_IMPLEMENT; if (tmp_written < 0) { /* treat error */ gda_blob_free ((gpointer) tmpblob); return -1; } nbwritten += tmp_written; if (nread < buf_size) /* nothing more to read */ break; } gda_blob_free ((gpointer) tmpblob); } else { /* write blob using bin->data and bin->binary_length */ GdaBinary *bin; bin = (GdaBinary *) blob; nbwritten = -1; TO_IMPLEMENT; } return nbwritten; }
/** * gda_xa_transaction_unregister_connection: * @xa_trans: a #GdaXaTransaction object * @cnc: the connection to add to @xa_trans * * Unregisters @cnc to be used by @xa_trans to create a distributed transaction. This is * the opposite of gda_xa_transaction_register_connection(). */ void gda_xa_transaction_unregister_connection (GdaXaTransaction *xa_trans, GdaConnection *cnc) { g_return_if_fail (GDA_IS_XA_TRANSACTION (xa_trans)); g_return_if_fail (GDA_IS_CONNECTION (cnc)); if (!g_list_find (xa_trans->priv->cnc_list, cnc)) { g_warning (_("Cannot unregister connection not registered with GdaXaTransaction object")); return; } xa_trans->priv->cnc_list = g_list_remove (xa_trans->priv->cnc_list, cnc); g_hash_table_remove (xa_trans->priv->cnc_hash, cnc); g_object_set_data (G_OBJECT (cnc), "_gda_xa_transaction", NULL); g_object_unref (cnc); }
/* * _gda_oracle_handle_error * This function is used for checking the result of an OCI * call. The result itself is the return value, and we * need the GdaConnection and OracleConnectionData to do * our thing. The type is OCI_HTYPE_ENV or OCI_HTYPE_ERROR * as described for OCIErrorGet. * * The return value is true if there is no error, or false otherwise * * If the return value is OCI_SUCCESS or OCI_SUCCESS_WITH_INFO, * we return TRUE. Otherwise, if it is OCI_ERROR, try to get the * Oracle error message using _gda_oracle_make_error. Otherwise, * make an error using the given message. */ GdaConnectionEvent * _gda_oracle_handle_error (gint result, GdaConnection *cnc, OracleConnectionData *cdata, ub4 type, const gchar *msg, const gchar *file, gint line) { GdaConnectionEvent *error = NULL; g_return_val_if_fail (GDA_IS_CONNECTION (cnc), FALSE); switch (result) { case OCI_SUCCESS: case OCI_SUCCESS_WITH_INFO: return NULL; case OCI_ERROR: switch(type) { case OCI_HTYPE_ERROR: error = _gda_oracle_make_error (cnc, cdata->herr, type, file, line); gda_connection_add_event (cnc, error); break; case OCI_HTYPE_ENV: error = _gda_oracle_make_error (cnc, cdata->henv, type, file, line); if (error) gda_connection_add_event (cnc, error); break; default: if (error) error = gda_connection_add_event_string (cnc, msg); gda_connection_add_event (cnc, error); break; } break; case OCI_NO_DATA: g_warning ("Internal implementation error: OCI_NO_DATA not handled!\n"); break; case OCI_INVALID_HANDLE: g_warning ("Internal error: Invalid handle!"); default: error = gda_connection_add_event_string (cnc, msg); } #ifdef GDA_DEBUG if (error) g_print ("HANDLED error: %s\n", gda_connection_event_get_description (error)); #endif return error; }
/* * Server version request */ static const gchar * gda_ldap_provider_get_server_version (GdaServerProvider *provider, GdaConnection *cnc) { LdapConnectionData *cdata; g_return_val_if_fail (GDA_IS_CONNECTION (cnc), NULL); g_return_val_if_fail (gda_connection_get_provider (cnc) == provider, NULL); cdata = (LdapConnectionData*) gda_virtual_connection_internal_get_provider_data (GDA_VIRTUAL_CONNECTION (cnc)); if (!cdata) return FALSE; if (! cdata->server_version) { /* FIXME: don't know how to get information about the LDAP server! */ } return cdata->server_version; }
gchar * gda_postgres_render_DROP_USER (GdaServerProvider *provider, GdaConnection *cnc, GdaServerOperation *op, G_GNUC_UNUSED GError **error) { GString *string; const GValue *value; gchar *sql = NULL; gchar *tmp; gboolean use_role = TRUE; PostgresConnectionData *cdata = NULL; if (cnc) { g_return_val_if_fail (GDA_IS_CONNECTION (cnc), FALSE); g_return_val_if_fail (gda_connection_get_provider (cnc) == provider, FALSE); cdata = (PostgresConnectionData*) gda_connection_internal_get_provider_data_error (cnc, error); } if (cdata && (cdata->reuseable->version_float < 8.1)) use_role = FALSE; if (use_role) string = g_string_new ("DROP ROLE "); else string = g_string_new ("DROP USER "); value = gda_server_operation_get_value_at (op, "/USER_DESC_P/USER_IFEXISTS"); if (value && G_VALUE_HOLDS (value, G_TYPE_BOOLEAN) && g_value_get_boolean (value)) g_string_append (string, " IF EXISTS"); tmp = gda_server_operation_get_sql_identifier_at (op, cnc, provider, "/USER_DESC_P/USER_NAME", error); if (!tmp) { g_string_free (string, TRUE); return NULL; } g_string_append_c (string, ' '); g_string_append (string, tmp); g_free (tmp); sql = string->str; g_string_free (string, FALSE); return sql; }
/* * Blob write request */ static glong gda_mysql_blob_op_write (GdaBlobOp *op, GdaBlob *blob, G_GNUC_UNUSED glong offset) { GdaMysqlBlobOp *pgop; /* GdaBinary *bin; */ g_return_val_if_fail (GDA_IS_MYSQL_BLOB_OP (op), -1); pgop = GDA_MYSQL_BLOB_OP (op); g_return_val_if_fail (pgop->priv, -1); g_return_val_if_fail (GDA_IS_CONNECTION (pgop->priv->cnc), -1); g_return_val_if_fail (blob, -1); /* write blob using bin->data and bin->binary_length */ /* bin = (GdaBinary *) blob; */ TO_IMPLEMENT; return -1; }
/* * Creates the structure of the database pointed by @cnc, as specified in @schema_file * */ gboolean test_cnc_setup_db_structure (GdaConnection *cnc, const gchar *schema_file, GError **error) { GdaDDLCreator *ddl; g_return_val_if_fail (GDA_IS_CONNECTION (cnc), FALSE); ddl = gda_ddl_creator_new (); if (!gda_ddl_creator_set_dest_from_file (ddl, schema_file, error)) { g_object_unref (ddl); return FALSE; } gda_ddl_creator_set_connection (ddl, cnc); if (!gda_ddl_creator_execute (ddl, error)) { g_object_unref (ddl); return FALSE; } g_object_unref (ddl); return TRUE; }
/* * Close connection request * * In this function, the following _must_ be done: * - Actually close the connection to the database using @cnc's associated LdapConnectionData structure * - Free the LdapConnectionData structure and its contents * * Returns: TRUE if no error occurred, or FALSE otherwise (and an ERROR connection event must be added to @cnc) */ static gboolean gda_ldap_provider_close_connection (GdaServerProvider *provider, GdaConnection *cnc) { LdapConnectionData *cdata; g_return_val_if_fail (GDA_IS_CONNECTION (cnc), FALSE); g_return_val_if_fail (gda_connection_get_provider (cnc) == provider, FALSE); /* Close the connection using the C API */ cdata = (LdapConnectionData*) gda_virtual_connection_internal_get_provider_data (GDA_VIRTUAL_CONNECTION (cnc)); if (!cdata) return FALSE; if (cdata->handle) { ldap_unbind_ext (cdata->handle, NULL, NULL); cdata->handle = NULL; } GdaServerProviderBase *fset; fset = gda_server_provider_get_impl_functions_for_class (parent_class, GDA_SERVER_PROVIDER_FUNCTIONS_BASE); return fset->close_connection (provider, cnc); }
static const gchar * sql_get_last_error (GdaConnection *connection) { GList *list; GdaConnectionEvent *error; const gchar *error_txt; g_return_val_if_fail (GDA_IS_CONNECTION (connection), _("Can't connect to database server")); list = (GList *) gda_connection_get_events (connection); if (list == NULL) { return _("No errors reported."); } error = (GdaConnectionEvent *) g_list_last (list)->data; /* FIXME: Poor user, she won't get localized messages */ error_txt = gda_connection_event_get_description (error); return error_txt; }
/** * gda_server_provider_handler_find: * @prov: a #GdaServerProvider * @cnc: (allow-none): a #GdaConnection * @g_type: a #GType * @dbms_type: (allow-none): a database type * * Reserved to database provider's implementations: get the #GdaDataHandler associated to @prov * for connection @cnc. You probably want to use gda_server_provider_get_data_handler_g_type(). * * Returns: (transfer none): the requested #GdaDataHandler, or %NULL if none found */ GdaDataHandler * gda_server_provider_handler_find (GdaServerProvider *prov, GdaConnection *cnc, GType g_type, const gchar *dbms_type) { g_return_val_if_fail (GDA_IS_SERVER_PROVIDER (prov), NULL); if (cnc) g_return_val_if_fail (GDA_IS_CONNECTION (cnc), NULL); GdaDataHandler *dh; GdaServerProviderHandlerInfo info; info.cnc = cnc; info.g_type = g_type; info.dbms_type = (gchar *) dbms_type; dh = g_hash_table_lookup (prov->priv->data_handlers, &info); if (!dh) { /* try without the connection specification */ info.cnc = NULL; dh = g_hash_table_lookup (prov->priv->data_handlers, &info); } return dh; }
/** * gda_ldap_get_attr_info: * @cnc: a #GdaLdapConnection * @cdata: * @attribute: * * Returns: (transfer none): the #LdapAttribute for @attribute, or %NULL */ LdapAttribute * gda_ldap_get_attr_info (GdaLdapConnection *cnc, LdapConnectionData *cdata, const gchar *attribute) { g_return_val_if_fail (GDA_IS_CONNECTION (cnc), NULL); if (! attribute || !cdata) return NULL; gda_lockable_lock ((GdaLockable*) cnc); /* CNC LOCK */ GdaServerProviderConnectionData *pcdata; pcdata = gda_connection_internal_get_provider_data_error ((GdaConnection*) cnc, NULL); GdaWorker *worker; worker = gda_worker_ref (gda_connection_internal_get_worker (pcdata)); GMainContext *context; context = gda_server_provider_get_real_main_context ((GdaConnection *) cnc); WorkerLdapAttrInfoData data; data.cnc = cnc; data.cdata = cdata; data.attribute = attribute; gda_connection_increase_usage ((GdaConnection*) cnc); /* USAGE ++ */ gpointer retval; gda_worker_do_job (worker, context, 0, &retval, NULL, (GdaWorkerFunc) worker_gda_ldap_get_attr_info, (gpointer) &data, NULL, NULL, NULL); if (context) g_main_context_unref (context); gda_connection_decrease_usage ((GdaConnection*) cnc); /* USAGE -- */ gda_lockable_unlock ((GdaLockable*) cnc); /* CNC UNLOCK */ gda_worker_unref (worker); return (LdapAttribute*) retval; }
/* * the @ps struct is modified and transferred to the new data model created in * this function * * See MySQL's documentation "C API Prepared Statement Type Codes": * http://docs.oracle.com/cd/E17952_01/refman-5.5-en/c-api-prepared-statement-type-codes.html */ GdaDataModel * gda_mysql_recordset_new (GdaConnection *cnc, GdaMysqlPStmt *ps, GdaSet *exec_params, GdaDataModelAccessFlags flags, GType *col_types) { GdaMysqlRecordset *model; MysqlConnectionData *cdata; gint i; GdaDataModelAccessFlags rflags; g_return_val_if_fail (GDA_IS_CONNECTION (cnc), NULL); g_return_val_if_fail (ps != NULL, NULL); cdata = (MysqlConnectionData*) gda_connection_internal_get_provider_data_error (cnc, NULL); if (!cdata) return NULL; g_assert (ps->mysql_stmt); /* make sure @ps reports the correct number of columns using the API*/ if (_GDA_PSTMT (ps)->ncols < 0) _GDA_PSTMT(ps)->ncols = mysql_stmt_field_count (ps->mysql_stmt); /* completing @ps if not yet done */ g_assert (! ps->stmt_used); ps->stmt_used = TRUE; if (!_GDA_PSTMT (ps)->types && (_GDA_PSTMT (ps)->ncols > 0)) { /* create prepared statement's columns */ for (i = 0; i < _GDA_PSTMT (ps)->ncols; i++) _GDA_PSTMT (ps)->tmpl_columns = g_slist_prepend (_GDA_PSTMT (ps)->tmpl_columns, gda_column_new ()); _GDA_PSTMT (ps)->tmpl_columns = g_slist_reverse (_GDA_PSTMT (ps)->tmpl_columns); /* create prepared statement's types, all types are initialized to GDA_TYPE_NULL */ _GDA_PSTMT (ps)->types = g_new (GType, _GDA_PSTMT (ps)->ncols); for (i = 0; i < _GDA_PSTMT (ps)->ncols; i++) _GDA_PSTMT (ps)->types [i] = GDA_TYPE_NULL; if (col_types) { for (i = 0; ; i++) { if (col_types [i] > 0) { if (col_types [i] == G_TYPE_NONE) break; if (i >= _GDA_PSTMT (ps)->ncols) { g_warning (_("Column %d out of range (0-%d), ignoring its specified type"), i, _GDA_PSTMT (ps)->ncols - 1); break; } else _GDA_PSTMT (ps)->types [i] = col_types [i]; } } } } /* get rid of old bound result if any */ if (ps->mysql_bind_result) { gint i; for (i = 0; i < ((GdaPStmt *) ps)->ncols; ++i) { g_free (ps->mysql_bind_result[i].buffer); g_free (ps->mysql_bind_result[i].is_null); g_free (ps->mysql_bind_result[i].length); } g_free (ps->mysql_bind_result); ps->mysql_bind_result = NULL; } /* fill bind result */ MYSQL_RES *mysql_res = mysql_stmt_result_metadata (ps->mysql_stmt); MYSQL_FIELD *mysql_fields = mysql_fetch_fields (mysql_res); MYSQL_BIND *mysql_bind_result = g_new0 (MYSQL_BIND, GDA_PSTMT (ps)->ncols); GSList *list; for (i=0, list = _GDA_PSTMT (ps)->tmpl_columns; i < GDA_PSTMT (ps)->ncols; i++, list = list->next) { GdaColumn *column = GDA_COLUMN (list->data); /* use C API to set columns' information using gda_column_set_*() */ MYSQL_FIELD *field = &mysql_fields[i]; GType gtype = _GDA_PSTMT(ps)->types[i]; if (gtype == GDA_TYPE_NULL) { gtype = _gda_mysql_type_to_gda (cdata, field->type, field->charsetnr); _GDA_PSTMT(ps)->types[i] = gtype; } gda_column_set_g_type (column, gtype); gda_column_set_name (column, field->name); gda_column_set_description (column, field->name); /* binding results with types */ mysql_bind_result[i].buffer_type = field->type; mysql_bind_result[i].is_unsigned = field->flags & UNSIGNED_FLAG ? TRUE : FALSE; mysql_bind_result[i].is_null = g_malloc0 (sizeof (my_bool)); switch (mysql_bind_result[i].buffer_type) { case MYSQL_TYPE_TINY: mysql_bind_result[i].buffer = g_malloc0 (sizeof (signed char)); break; case MYSQL_TYPE_SHORT: mysql_bind_result[i].buffer = g_malloc0 (sizeof (short int)); break; case MYSQL_TYPE_INT24: case MYSQL_TYPE_LONG: case MYSQL_TYPE_YEAR: mysql_bind_result[i].buffer = g_malloc0 (sizeof (int)); break; case MYSQL_TYPE_LONGLONG: mysql_bind_result[i].buffer = g_malloc0 (sizeof (long long)); break; case MYSQL_TYPE_NULL: break; case MYSQL_TYPE_TIME: case MYSQL_TYPE_DATE: case MYSQL_TYPE_DATETIME: case MYSQL_TYPE_TIMESTAMP: mysql_bind_result[i].buffer = g_malloc0 (sizeof (MYSQL_TIME)); break; case MYSQL_TYPE_FLOAT: case MYSQL_TYPE_DOUBLE: mysql_bind_result[i].buffer = g_malloc0 (sizeof (double)); break; case MYSQL_TYPE_STRING: case MYSQL_TYPE_VAR_STRING: case MYSQL_TYPE_BLOB: case MYSQL_TYPE_TINY_BLOB: case MYSQL_TYPE_MEDIUM_BLOB: case MYSQL_TYPE_LONG_BLOB: case MYSQL_TYPE_DECIMAL: case MYSQL_TYPE_NEWDECIMAL: case MYSQL_TYPE_BIT: mysql_bind_result[i].buffer = g_malloc0 (field->max_length + 1); mysql_bind_result[i].buffer_length = field->max_length + 1; mysql_bind_result[i].length = g_malloc0 (sizeof (unsigned long)); break; default: g_warning (_("Invalid column bind data type. %d\n"), mysql_bind_result[i].buffer_type); } /*g_print ("%s(): NAME=%s, TYPE=%d, GTYPE=%s, unsigned: %d\n", __FUNCTION__, field->name, field->type, g_type_name (gtype), field->flags & UNSIGNED_FLAG);*/ } if (mysql_stmt_bind_result (ps->mysql_stmt, mysql_bind_result)) { g_warning ("mysql_stmt_bind_result failed: %s\n", mysql_stmt_error (ps->mysql_stmt)); } mysql_free_result (mysql_res); ps->mysql_bind_result = mysql_bind_result; /* determine access mode: RANDOM or CURSOR FORWARD are the only supported */ if (flags & GDA_DATA_MODEL_ACCESS_RANDOM) rflags = GDA_DATA_MODEL_ACCESS_RANDOM; else rflags = GDA_DATA_MODEL_ACCESS_CURSOR_FORWARD; /* create data model */ model = g_object_new (GDA_TYPE_MYSQL_RECORDSET, "connection", cnc, "prepared-stmt", ps, "model-usage", rflags, "exec-params", exec_params, NULL); model->priv->cnc = cnc; g_object_ref (G_OBJECT(cnc)); model->priv->mysql_stmt = ps->mysql_stmt; ((GdaDataSelect *) model)->advertized_nrows = mysql_stmt_affected_rows (ps->mysql_stmt); return GDA_DATA_MODEL (model); }
GdaDataModel * gda_mysql_recordset_new_direct (GdaConnection *cnc, GdaDataModelAccessFlags flags, GType *col_types) { GdaMysqlRecordset *model; MysqlConnectionData *cdata; gint i; GdaDataModelAccessFlags rflags; GSList *columns = NULL; g_return_val_if_fail (GDA_IS_CONNECTION (cnc), NULL); cdata = (MysqlConnectionData*) gda_connection_internal_get_provider_data_error (cnc, NULL); if (!cdata) return NULL; /* determine access mode: RANDOM or CURSOR FORWARD are the only supported */ if (flags & GDA_DATA_MODEL_ACCESS_RANDOM) rflags = GDA_DATA_MODEL_ACCESS_RANDOM; else rflags = GDA_DATA_MODEL_ACCESS_CURSOR_FORWARD; /* create data model */ model = g_object_new (GDA_TYPE_MYSQL_RECORDSET, "connection", cnc, "model-usage", rflags, NULL); model->priv->cnc = cnc; g_object_ref (G_OBJECT(cnc)); /* columns & types */ model->priv->ncols = mysql_field_count (cdata->mysql); model->priv->types = g_new0 (GType, model->priv->ncols); /* create columns */ for (i = 0; i < model->priv->ncols; i++) columns = g_slist_prepend (columns, gda_column_new ()); columns = g_slist_reverse (columns); if (col_types) { for (i = 0; ; i++) { if (col_types [i] > 0) { if (col_types [i] == G_TYPE_NONE) break; if (i >= model->priv->ncols) { g_warning (_("Column %d out of range (0-%d), ignoring its specified type"), i, model->priv->ncols - 1); break; } else model->priv->types [i] = col_types [i]; } } } /* fill bind result */ MYSQL_RES *mysql_res = mysql_store_result (cdata->mysql); MYSQL_FIELD *mysql_fields = mysql_fetch_fields (mysql_res); GSList *list; ((GdaDataSelect *) model)->advertized_nrows = mysql_affected_rows (cdata->mysql); for (i=0, list = columns; i < model->priv->ncols; i++, list = list->next) { GdaColumn *column = GDA_COLUMN (list->data); /* use C API to set columns' information using gda_column_set_*() */ MYSQL_FIELD *field = &mysql_fields[i]; GType gtype = model->priv->types [i]; if (gtype == GDA_TYPE_NULL) { gtype = _gda_mysql_type_to_gda (cdata, field->type, field->charsetnr); model->priv->types [i] = gtype; } gda_column_set_g_type (column, gtype); gda_column_set_name (column, field->name); gda_column_set_description (column, field->name); } gda_data_select_set_columns (GDA_DATA_SELECT (model), columns); /* load ALL data */ MYSQL_ROW mysql_row; gint rownum; GdaServerProvider *prov; prov = gda_connection_get_provider (cnc); for (mysql_row = mysql_fetch_row (mysql_res), rownum = 0; mysql_row; mysql_row = mysql_fetch_row (mysql_res), rownum++) { GdaRow *row = gda_row_new (model->priv->ncols); gint col; for (col = 0; col < model->priv->ncols; col++) { gint i = col; GValue *value = gda_row_get_value (row, i); GType type = model->priv->types[i]; char *data = mysql_row[i]; if (!data || (type == GDA_TYPE_NULL)) continue; gda_value_reset_with_type (value, type); if (type == G_TYPE_STRING) g_value_set_string (value, data); else { GdaDataHandler *dh; gboolean valueset = FALSE; dh = gda_server_provider_get_data_handler_g_type (prov, cnc, type); if (dh) { GValue *tmpvalue; tmpvalue = gda_data_handler_get_value_from_str (dh, data, type); if (tmpvalue) { *value = *tmpvalue; g_free (tmpvalue); valueset = TRUE; } } if (!valueset) gda_row_invalidate_value (row, value); } } gda_data_select_take_row ((GdaDataSelect*) model, row, rownum); } mysql_free_result (mysql_res); return GDA_DATA_MODEL (model); }