示例#1
0
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;
}
示例#2
0
/*
 * Reopens a connection after the server has closed it (possibly because of a timeout)
 */
gboolean
gda_ldap_rebind (GdaLdapConnection *cnc, GError **error)
{
	g_return_val_if_fail (GDA_IS_LDAP_CONNECTION (cnc), FALSE);
	gda_lockable_lock ((GdaLockable*) cnc); /* CNC LOCK */

	LdapConnectionData *cdata;
	cdata = (LdapConnectionData*) gda_virtual_connection_internal_get_provider_data (GDA_VIRTUAL_CONNECTION (cnc));
        if (!cdata) {
		gda_lockable_unlock ((GdaLockable*) cnc); /* CNC UNLOCK */
		g_warning ("cdata != NULL failed");
		return FALSE;
	}

	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);

	gpointer retval;
	gda_worker_do_job (worker, context, 0, &retval, NULL,
			   (GdaWorkerFunc) worker_gda_ldap_rebind, (gpointer) cdata, NULL, NULL, error);
	if (context)
		g_main_context_unref (context);

	gda_lockable_unlock ((GdaLockable*) cnc); /* CNC UNLOCK */

	gda_worker_unref (worker);

	return retval ? TRUE : FALSE;
}
示例#3
0
/*
 * Create a new filled #GdaRow object for the row at position @rownum, and put it into *prow.
 *
 * Each new #GdaRow created needs to be "given" to the #GdaDataSelect implementation using
 * gda_data_select_take_row() because backward iterating is not supported.
 */
static gboolean 
gda_oracle_recordset_fetch_random (GdaDataSelect *model, GdaRow **prow, gint rownum, GError **error)
{
	GdaOracleRecordset *imodel;
	OracleConnectionData *cdata;
	GdaConnection *cnc;

	imodel = GDA_ORACLE_RECORDSET (model);
	cnc = gda_data_select_get_connection (model);
	cdata = (OracleConnectionData*)	gda_connection_internal_get_provider_data_error (cnc, error);
	if (!cdata)
		return TRUE;

	if (imodel->priv->next_row_num >= rownum) {
		g_set_error (error, GDA_SERVER_PROVIDER_ERROR,
			     GDA_SERVER_PROVIDER_INTERNAL_ERROR, 
			     "%s", _("Requested row could not be found"));
		return TRUE;
	}
	for (*prow = fetch_next_oracle_row (imodel, TRUE, error);
	     *prow && (imodel->priv->next_row_num < rownum);
	     *prow = fetch_next_oracle_row (imodel, TRUE, error));

	return TRUE;
}
示例#4
0
/*
 * Unbinds the connection if possible (i.e. if cdata->keep_bound_count is 0)
 * This allows to avoid keeping the connection to the LDAP server if unused
 */
void
gda_ldap_may_unbind (GdaLdapConnection *cnc)
{
	gda_lockable_lock ((GdaLockable*) cnc); /* CNC LOCK */

	LdapConnectionData *cdata;
	cdata = (LdapConnectionData*) gda_virtual_connection_internal_get_provider_data (GDA_VIRTUAL_CONNECTION (cnc));
	if (!cdata || (cdata->keep_bound_count > 0)) {
		gda_lockable_unlock ((GdaLockable*) cnc); /* CNC UNLOCK */
		return;
	}

	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);

	gpointer retval;
	gda_worker_do_job (worker, context, 0, &retval, NULL,
			   (GdaWorkerFunc) worker_gda_ldap_may_unbind, (gpointer) cdata, NULL, NULL, NULL);
	if (context)
		g_main_context_unref (context);

	gda_lockable_unlock ((GdaLockable*) cnc); /* CNC UNLOCK */

	gda_worker_unref (worker);
}
示例#5
0
static void
gda_web_pstmt_dispose (GObject *object)
{
	GdaWebPStmt *pstmt = (GdaWebPStmt *) object;

	g_return_if_fail (GDA_IS_PSTMT (pstmt));
  GdaWebPStmtPrivate *priv = gda_web_pstmt_get_instance_private (pstmt);

	if (priv->pstmt_hash) {
    GdaConnection *cnc = NULL;
		WebConnectionData *cdata;
    cnc = g_weak_ref_get (&priv->cnc);
    if (cnc != NULL) {
		  cdata = (WebConnectionData*) gda_connection_internal_get_provider_data_error (cnc, NULL);
		  if (!cdata)
			  goto next;

		  /* send command to deallocate prepared statement */
		  xmlDocPtr doc;
		  xmlNodePtr root, cmdnode;
		  gchar *token;
		  doc = xmlNewDoc (BAD_CAST "1.0");
		  root = xmlNewNode (NULL, BAD_CAST "request");
		  xmlDocSetRootElement (doc, root);
		  token = _gda_web_compute_token (cdata);
		  xmlNewChild (root, NULL, BAD_CAST "token", BAD_CAST token);
		  g_free (token);
		  cmdnode = xmlNewChild (root, NULL, BAD_CAST "cmd", BAD_CAST "UNPREPARE");
		  xmlNewChild (cmdnode, NULL, BAD_CAST "preparehash", BAD_CAST priv->pstmt_hash);

		  xmlChar *cmde;
		  xmlDocPtr replydoc;
		  int size;
		  gchar status;

		  xmlDocDumpMemory (doc, &cmde, &size);
		  xmlFreeDoc (doc);
		  replydoc = _gda_web_send_message_to_frontend (cnc, cdata, MESSAGE_UNPREPARE, (gchar*) cmde,
							        cdata->key, &status);
		  xmlFree (cmde);
		  if (replydoc)
			  xmlFreeDoc (replydoc);
    }
		
	next:
		/* free memory */
		g_free (priv->pstmt_hash);
	}

	/* chain to parent class */
	G_OBJECT_CLASS (gda_web_pstmt_parent_class)->finalize (object);
}
示例#6
0
static GdaRow *
fetch_next_oracle_row (GdaOracleRecordset *model, G_GNUC_UNUSED gboolean do_store, GError **error)
{
	int result;
	GdaRow *prow = NULL;
	GdaOraclePStmt *ps = GDA_ORACLE_PSTMT (((GdaDataSelect*)model)->prep_stmt);
	OracleConnectionData *cdata;
	GdaConnection *cnc;

	cnc = gda_data_select_get_connection ((GdaDataSelect*) model);
	cdata = (OracleConnectionData*)	gda_connection_internal_get_provider_data_error (cnc, error);
	if (!cdata)
		return NULL;

	/* fetch row */
	if (cdata->major_version > 9)
		result = OCIStmtFetch2 (ps->hstmt,
					cdata->herr,
					(ub4) 1,
					(ub2) OCI_FETCH_NEXT,
					(sb4) 1,
					(ub4) OCI_DEFAULT);
	else
		result = OCIStmtFetch (ps->hstmt,
				       cdata->herr,
				       (ub4) 1,
				       (ub2) OCI_FETCH_NEXT,
				       (ub4) OCI_DEFAULT);
	if (result == OCI_NO_DATA) {
		GDA_DATA_SELECT (model)->advertized_nrows = model->priv->next_row_num;
		return NULL;
	}
	else {
		GdaConnectionEvent *event;
		if ((event = gda_oracle_check_result (result, cnc, cdata, OCI_HTYPE_ERROR,
						      _("Could not fetch next row")))) {
			/* set @error */
			g_set_error (error, GDA_SERVER_PROVIDER_ERROR, GDA_SERVER_PROVIDER_DATA_ERROR,
				     "%s", gda_connection_event_get_description (event));

			return NULL;
		}
	}

	prow = new_row ((GdaDataSelect*) model, cnc, ps);
	gda_data_select_take_row ((GdaDataSelect*) model, prow, model->priv->next_row_num);
	model->priv->next_row_num ++;

	return prow;
}
示例#7
0
/**
 * gdaprov_ldap_get_class_info:
 * @cnc: a #GdaLdapConnection (not %NULL)
 * @classname: the class name (not %NULL)
 *
 * Returns: the #GdaLdapClass for @classname, or %NULL
 */
GdaLdapClass *
gdaprov_ldap_get_class_info (GdaLdapConnection *cnc, const gchar *classname)
{
	g_return_val_if_fail (GDA_IS_LDAP_CONNECTION (cnc), NULL);
	g_return_val_if_fail (classname, NULL);

	gda_lockable_lock ((GdaLockable*) cnc); /* CNC LOCK */

	LdapConnectionData *cdata;
        cdata = (LdapConnectionData*) gda_virtual_connection_internal_get_provider_data (GDA_VIRTUAL_CONNECTION (cnc));
        if (!cdata) {
		gda_lockable_unlock ((GdaLockable*) cnc); /* CNC UNLOCK */
                return NULL;
	}

	if (cdata->classes_hash) {
		gda_lockable_unlock ((GdaLockable*) cnc); /* CNC UNLOCK */
		return g_hash_table_lookup (cdata->classes_hash, classname);
	}

	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);

	WorkerLdapClassInfoData data;
	data.cnc = cnc;
	data.cdata = cdata;
	data.classname = classname;

	gda_connection_increase_usage ((GdaConnection*) cnc); /* USAGE ++ */
	gpointer retval;
	gda_worker_do_job (worker, context, 0, &retval, NULL,
			   (GdaWorkerFunc) worker_gdaprov_ldap_get_class_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 (GdaLdapClass*) retval;
}
示例#8
0
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;
}
示例#9
0
GdaLdapEntry *
gdaprov_ldap_describe_entry (GdaLdapConnection *cnc, const gchar *dn, GError **error)
{
	g_return_val_if_fail (GDA_IS_LDAP_CONNECTION (cnc), NULL);
	g_return_val_if_fail (!dn || (dn && *dn), NULL);

	gda_lockable_lock ((GdaLockable*) cnc); /* CNC LOCK */

	LdapConnectionData *cdata;
        cdata = (LdapConnectionData*) gda_virtual_connection_internal_get_provider_data (GDA_VIRTUAL_CONNECTION (cnc));
        if (!cdata) {
		gda_lockable_unlock ((GdaLockable*) cnc); /* CNC UNLOCK */
                return NULL;
	}

	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);

	WorkerLdapDescrEntryData data;
	data.cnc = cnc;
	data.cdata = cdata;
	data.dn = dn;

	gda_connection_increase_usage ((GdaConnection*) cnc); /* USAGE ++ */
	gpointer retval;
	gda_worker_do_job (worker, context, 0, &retval, NULL,
			   (GdaWorkerFunc) worker_gdaprov_ldap_describe_entry, (gpointer) &data, NULL, NULL, error);
	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 (GdaLdapEntry*) retval;
}
示例#10
0
/**
 * 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;
}
示例#11
0
void
_gda_oracle_set_value (GValue *value, 
		       GdaOracleValue *ora_value,
		       GdaConnection *cnc)
{
	GdaTime gtime;
	GdaTimestamp timestamp;
	sb2 year;
	ub1 month;
	ub1 day;
	ub1 hour;
	ub1 min;
	ub1 sec;

	if (ora_value->indicator == -1) {
		gda_value_set_null (value);
		return;
	}

	gda_value_reset_with_type (value, ora_value->g_type);
	switch (ora_value->s_type) {
	case GDA_STYPE_INT:
		g_value_set_int (value, *((gint *) ora_value->value));
		break;
	case GDA_STYPE_STRING: {
		gchar *string_buffer, *tmp;
		
		string_buffer = (gchar *) ora_value->value;
		string_buffer [ora_value->rlen] = '\0';
		g_strchomp (string_buffer);
		//tmp = g_locale_to_utf8 (string_buffer, -1, NULL, NULL, NULL);
		//g_value_take_string (value, tmp);
		g_value_set_string (value, string_buffer);
		if (ora_value->use_callback) {
			g_free (string_buffer);
			ora_value->value = NULL;
		}
		break;
	}
	case GDA_STYPE_BOOLEAN:
		g_value_set_boolean (value, (*((gint *) ora_value->value)) ? TRUE: FALSE);
		break;
	case GDA_STYPE_DATE: {
		GDate *date;
		OCIDateGetDate ((CONST OCIDate *) ora_value->value,
				(sb2 *) &year,
				(ub1 *) &month,
				(ub1 *) &day);
		date = g_date_new_dmy (day, month, year);
		g_value_take_boxed (value, date);
		break;
	}
	case GDA_STYPE_TIME: {
		OCIDateGetTime ((CONST OCIDate *) ora_value->value,
				(ub1 *) &hour,
				(ub1 *) &min,
				(ub1 *) &sec);
		gtime.hour = hour;
		gtime.minute = min;
		gtime.second = sec;
		gda_value_set_time (value, &gtime);
		break;
	}
	case GDA_STYPE_TIMESTAMP: {
		OCIDateGetDate ((CONST OCIDate *) ora_value->value,
				(sb2 *) &year,
				(ub1 *) &month,
				(ub1 *) &day);
		OCIDateGetTime ((CONST OCIDate *) ora_value->value,
				(ub1 *) &hour,
				(ub1 *) &min,
				(ub1 *) &sec);
		timestamp.year = year;
		timestamp.month = month;
		timestamp.day = day;
		timestamp.hour = hour;
		timestamp.minute = min;
		timestamp.second = sec;
		timestamp.fraction = 0;
		timestamp.timezone = 0;
		gda_value_set_timestamp(value, &timestamp);
		break;
	}
	case GDA_STYPE_INT64:
		TO_IMPLEMENT; /* test that value fits in */
		g_value_set_int64 (value, atoll (ora_value->value));
		break;
	case GDA_STYPE_UINT64:
		TO_IMPLEMENT; /* test that value fits in */
		g_value_set_uint64 (value, atoll (ora_value->value));
		break;
	case GDA_STYPE_UINT:
		TO_IMPLEMENT; /* test that value fits in */
		g_value_set_uint (value, *((guint*) ora_value->value));
		break;
	case GDA_STYPE_FLOAT:
		g_value_set_float (value, *((gfloat*) ora_value->value));
		break;
	case GDA_STYPE_DOUBLE:
		g_value_set_double (value, *((gdouble*) ora_value->value));
		break;
	case GDA_STYPE_LONG:
		TO_IMPLEMENT;
		break;
	case GDA_STYPE_ULONG:
		TO_IMPLEMENT;
		break;
	case GDA_STYPE_NUMERIC: {
		GdaNumeric *numeric;
		gchar *tmp;
		g_assert (!ora_value->use_callback);
		
		tmp = g_malloc0 (ora_value->defined_size);
		memcpy (tmp, ora_value->value, ora_value->defined_size);
		tmp [ora_value->rlen] = '\0';
		g_strchomp (tmp);

		numeric = gda_numeric_new ();
		gda_numeric_set_from_string (numeric, tmp);
		g_free (tmp);
		gda_numeric_set_precision (numeric, ora_value->precision);
		gda_numeric_set_width (numeric, ora_value->scale);
		g_value_take_boxed (value, numeric);
		break;
	}
	case GDA_STYPE_BINARY: {
		GdaBinary *bin;

		bin = g_new0 (GdaBinary, 1);
		if (ora_value->use_callback) {		
			bin->data = ora_value->value;
			ora_value->value = NULL;
		}
		else {
			bin->data = g_new (guchar, ora_value->rlen);
			memcpy (bin->data, ora_value->value, ora_value->rlen);
		}
		bin->binary_length = ora_value->rlen;
		gda_value_take_binary (value, bin);
		break;
	}
	case GDA_STYPE_BLOB: {
		GdaBlob *blob;
		GdaBlobOp *op;
		OCILobLocator *lobloc;
		OracleConnectionData *cdata;
		gint result;

		/* REM: we need to make a "copy" of the lob locator to give to the GdaOracleblobOp object */
		cdata = (OracleConnectionData*) gda_connection_internal_get_provider_data_error (cnc, NULL);
		if (!cdata) {
			gda_connection_add_event_string (cnc, _("Invalid Oracle handle"));
			gda_value_set_null (value);
			return;
		}

		result = OCIDescriptorAlloc ((dvoid *) cdata->henv, (dvoid **) &lobloc, 
					     (ub4) gda_oracle_blob_type (ora_value->sql_type), (size_t) 0, (dvoid **) 0);
		if (gda_oracle_check_result (result, cnc, cdata, OCI_HTYPE_ERROR,
					     _("Could not allocate Lob locator"))) {
			gda_value_set_null (value);
			return;
		}

		result = OCILobAssign ((dvoid *) cdata->henv, (dvoid *) cdata->herr, ora_value->value, &lobloc);
		if (gda_oracle_check_result (result, cnc, cdata, OCI_HTYPE_ERROR,
					     _("Could not copy Lob locator"))) {
			gda_value_set_null (value);
			return;
		}

		blob = g_new0 (GdaBlob, 1);
		op = gda_oracle_blob_op_new (cnc, lobloc);
		gda_blob_set_op (blob, op);
		g_object_unref (op);

		gda_value_take_blob (value, blob);
		break;
	}
	case GDA_STYPE_CHAR: {
		TO_IMPLEMENT; /* test that value fits in */
		g_value_set_schar (value, *((gint8*) ora_value->value));
		break;
	}
	case GDA_STYPE_SHORT: {
		TO_IMPLEMENT; /* test that value fits in */
		gda_value_set_short (value, *((gint*) ora_value->value));
		break;
	}
	case GDA_STYPE_GTYPE:
		TO_IMPLEMENT;
		break;
	case GDA_STYPE_GEOMETRIC_POINT:
		TO_IMPLEMENT;
		break;
	case GDA_STYPE_NULL:
		gda_value_set_null (value);
		break;
	default:
		g_assert_not_reached ();
	}
}
示例#12
0
/*
 * the @ps struct is modified and transferred to the new data model created in
 * this function
 */
GdaDataModel *
gda_oracle_recordset_new (GdaConnection *cnc, GdaOraclePStmt *ps, GdaSet *exec_params,
			  GdaDataModelAccessFlags flags, GType *col_types)
{
	GdaOracleRecordset *model;
        OracleConnectionData *cdata;
        gint i;
	GdaDataModelAccessFlags rflags;

	gint nb_rows = -1;

        g_return_val_if_fail (GDA_IS_CONNECTION (cnc), NULL);
        g_return_val_if_fail (ps != NULL, NULL);

	cdata = (OracleConnectionData*) gda_connection_internal_get_provider_data_error (cnc, NULL);
	if (!cdata)
		return NULL;

	/* make sure @ps reports the correct number of columns using the API */
        if (_GDA_PSTMT (ps)->ncols < 0) {
		ub4 ncolumns;
		int result;
		
                /* get the number of columns in the result set */
                result = OCIAttrGet ((dvoid *) ps->hstmt,
                                     (ub4) OCI_HTYPE_STMT,
                                     (dvoid *) &ncolumns,
                                     (ub4 *) 0,
                                     (ub4) OCI_ATTR_PARAM_COUNT,
                                     cdata->herr);
                if (gda_oracle_check_result (result, cnc, cdata, OCI_HTYPE_ERROR,
                                             _("Could not get the number of columns in the result set")))
                        return NULL;
		
                _GDA_PSTMT (ps)->ncols = ncolumns;
	}

        /* completing @ps if not yet done */
        if (!_GDA_PSTMT (ps)->types && (_GDA_PSTMT (ps)->ncols > 0)) {
		/* create prepared statement's columns */
		GSList *list;
		GList *ora_values = NULL;

		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];
				}
			}
		}
		
		/* fill GdaColumn's data and define the GdaOracleValue structures */
		for (i=0, list = _GDA_PSTMT (ps)->tmpl_columns; 
		     i < GDA_PSTMT (ps)->ncols; 
		     i++, list = list->next) {
			GdaColumn *column;
			int result;
			GdaOracleValue *ora_value;
			gboolean use_callback = FALSE;

			ora_value = g_new0 (GdaOracleValue, 1);
			ora_values = g_list_prepend (ora_values, ora_value);

			/* parameter to get attributes */
			result = OCIParamGet (ps->hstmt,
					      OCI_HTYPE_STMT,
					      cdata->herr,
					      (dvoid **) &(ora_value->pard),
					      (ub4) i+1);
			if (gda_oracle_check_result (result, cnc, cdata, OCI_HTYPE_ERROR,
						     _("Could not get the Oracle parameter descripter in the result set"))) {
				g_list_foreach (ora_values, (GFunc) _gda_oracle_value_free, NULL);
				return NULL;
			}
			
			/* data size */
			result = OCIAttrGet ((dvoid *) (ora_value->pard),
					     OCI_DTYPE_PARAM,
					     &(ora_value->defined_size),
					     0,
					     (ub4) OCI_ATTR_DATA_SIZE,
					     cdata->herr);
			if (gda_oracle_check_result (result, cnc, cdata, OCI_HTYPE_ERROR,
						     _("Could not get the parameter defined size"))) {
				g_list_foreach (ora_values, (GFunc) _gda_oracle_value_free, NULL);
				return NULL;
			}
			ora_value->defined_size++;
			
			/* data type */
			result = OCIAttrGet ((dvoid *) (ora_value->pard),
					     OCI_DTYPE_PARAM,
					     &(ora_value->sql_type),
					     0,
					     OCI_ATTR_DATA_TYPE,
					     cdata->herr);
			if (gda_oracle_check_result (result, cnc, cdata, OCI_HTYPE_ERROR,
						     _("Could not get the parameter data type"))) {
				g_list_foreach (ora_values, (GFunc) _gda_oracle_value_free, NULL);
				return NULL;
			}

			result = OCIAttrGet ((dvoid *) (ora_value->pard),
					     OCI_DTYPE_PARAM,
					     &(ora_value->precision),
					     0,
					     OCI_ATTR_PRECISION,
					     cdata->herr);
			if (gda_oracle_check_result (result, cnc, cdata, OCI_HTYPE_ERROR,
						     _("Could not get the type's precision"))) {
				g_list_foreach (ora_values, (GFunc) _gda_oracle_value_free, NULL);
				return NULL;
			}

			result = OCIAttrGet ((dvoid *) (ora_value->pard),
					     OCI_DTYPE_PARAM,
					     &(ora_value->scale),
					     0,
					     OCI_ATTR_SCALE,
					     cdata->herr);
			if (gda_oracle_check_result (result, cnc, cdata, OCI_HTYPE_ERROR,
						     _("Could not get the type's scale"))) {
				g_list_foreach (ora_values, (GFunc) _gda_oracle_value_free, NULL);
				return NULL;
			}

			/* column's name */
			text *name;
			ub4 name_len;
			
			column = GDA_COLUMN (list->data);
			result = OCIAttrGet ((dvoid *) (ora_value->pard),
                                             (ub4) OCI_DTYPE_PARAM,
                                             (dvoid **) &name,
                                             (ub4 *) &name_len,
                                             (ub4) OCI_ATTR_NAME,
                                             (OCIError *) cdata->herr);
			if (gda_oracle_check_result (result, cnc, cdata, OCI_HTYPE_ERROR,
                                                     _("Could not get column name in the result set"))) {
				g_list_foreach (ora_values, (GFunc) _gda_oracle_value_free, NULL);
                                return NULL;
			}

			gchar *name_buffer;
			name_buffer = g_new (gchar, name_len + 1);
			memcpy (name_buffer, name, name_len);
                        name_buffer [name_len] = '\0';
			gda_column_set_name (column, name_buffer);
			gda_column_set_description (column, name_buffer);
			g_free (name_buffer);

			/* for data fetching  */
			if (_GDA_PSTMT (ps)->types [i] != GDA_TYPE_NULL)
				ora_value->sql_type = _g_type_to_oracle_sqltype (_GDA_PSTMT (ps)->types [i]);

			switch (ora_value->sql_type) {
			case SQLT_CHR: /* for G_TYPE_STRING => request SQLT_CHR */
			case SQLT_STR:
			case SQLT_VCS:
			case SQLT_RID:
			case SQLT_AVC:
			case SQLT_AFC:
				ora_value->sql_type = SQLT_CHR;
				if (ora_value->defined_size == 1)
					use_callback = TRUE;
				break;

			case SQLT_INT:
				ora_value->defined_size = sizeof (gint);
				break;

			case SQLT_FLT:
			case SQLT_BFLOAT:
				ora_value->defined_size = sizeof (gfloat);
				break;

			case SQLT_BDOUBLE:
				ora_value->defined_size = sizeof (gdouble);
				break;
								
			case SQLT_DAT: /* request OCIDate */
				ora_value->sql_type = SQLT_ODT;
				break;

			case SQLT_NUM: /* for GDA_TYPE_NUMERIC => request SQLT_CHR */
			case SQLT_VNU:
				ora_value->sql_type = SQLT_CHR;
				break;
				
			case SQLT_LBI:
			case SQLT_LVB:
			case SQLT_LVC:
			case SQLT_LNG:
			case SQLT_VBI:
			case SQLT_BIN:
				use_callback = TRUE;
				break;
			default:
				use_callback = TRUE;
				break;
			}
			
			if (_GDA_PSTMT (ps)->types [i] != GDA_TYPE_NULL)
				ora_value->g_type = _GDA_PSTMT (ps)->types [i];
			else
				ora_value->g_type = _oracle_sqltype_to_g_type (ora_value->sql_type, ora_value->precision, 
									       ora_value->scale);

			if (ora_value->g_type == GDA_TYPE_BLOB) {
				/* allocate a Lob locator */
				OCILobLocator *lob;
				
				result = OCIDescriptorAlloc ((dvoid *) cdata->henv, (dvoid **) &lob,
							     (ub4) gda_oracle_blob_type (ora_value->sql_type), 
							     (size_t) 0, (dvoid **) 0);
				if (gda_oracle_check_result (result, cnc, cdata, OCI_HTYPE_ERROR,
							     _("Could not allocate Lob locator"))) {
					g_list_foreach (ora_values, (GFunc) _gda_oracle_value_free, NULL);
					return NULL;
				}
				ora_value->value = lob;
				ora_value->defined_size = 0;
			}
			else if (use_callback) {
				ora_value->value = NULL;
				ora_value->defined_size = 33554432; /* 32M */
			}
			else
				ora_value->value = g_malloc0 (ora_value->defined_size);
			
			ora_value->s_type = gda_g_type_to_static_type (ora_value->g_type);
			if (_GDA_PSTMT (ps)->types [i] == GDA_TYPE_NULL)
				_GDA_PSTMT (ps)->types [i] = ora_value->g_type;
			gda_column_set_g_type (column, ora_value->g_type);

#ifdef GDA_DEBUG_NO
			g_print ("**COL type is %d, GType is %s, ORA defined size is %d%s\n",
				 ora_value->sql_type,
				 g_type_name (ora_value->g_type),
				 ora_value->defined_size - 1,
				 use_callback ? " using callback": "");
#endif

			ora_value->hdef = (OCIDefine *) 0;
			ora_value->indicator = 0;
			result = OCIDefineByPos ((OCIStmt *) ps->hstmt,
						 (OCIDefine **) &(ora_value->hdef),
						 (OCIError *) cdata->herr,
						 (ub4) i + 1,
						 ora_value->value,
						 ora_value->defined_size,
						 ora_value->sql_type,
						 (dvoid *) &(ora_value->indicator),
						 &(ora_value->rlen),
						 &(ora_value->rcode),
						 (ub4) (use_callback ? OCI_DYNAMIC_FETCH : OCI_DEFAULT));
			if (gda_oracle_check_result (result, cnc, cdata, OCI_HTYPE_ERROR,
						     _("Could not define by position"))) {
				OCIDescriptorFree ((dvoid *) ora_value->pard, OCI_DTYPE_PARAM);
				g_list_foreach (ora_values, (GFunc) _gda_oracle_value_free, NULL);
				return NULL;
			}

			if (use_callback) {
				result = OCIDefineDynamic ((OCIDefine *) (ora_value->hdef),
							   (OCIError *) (cdata->herr),
							   (dvoid*) (ora_value),
							   (OCICallbackDefine) ora_def_callback);
				if (gda_oracle_check_result (result, cnc, cdata, OCI_HTYPE_ERROR,
							     _("Could not define by position"))) {
					OCIDescriptorFree ((dvoid *) ora_value->pard, OCI_DTYPE_PARAM);
					g_list_foreach (ora_values, (GFunc) _gda_oracle_value_free, NULL);
					return NULL;
				}
			}

			ora_value->use_callback = use_callback;
		}

		ps->ora_values = g_list_reverse (ora_values);
        }

	/* determine access mode: RANDOM or CURSOR FORWARD are the only supported; if CURSOR BACKWARD
         * is requested, then we need RANDOM mode */
        if (flags & GDA_DATA_MODEL_ACCESS_RANDOM)
                rflags = GDA_DATA_MODEL_ACCESS_RANDOM;
        else if (flags & GDA_DATA_MODEL_ACCESS_CURSOR_BACKWARD)
                rflags = GDA_DATA_MODEL_ACCESS_RANDOM;
        else
                rflags = GDA_DATA_MODEL_ACCESS_CURSOR_FORWARD;

	ub4 prefetch;
	prefetch = (ub4) (100);
	OCIAttrSet (ps->hstmt, OCI_HTYPE_STMT,
		    &prefetch, 0,
		    OCI_ATTR_PREFETCH_ROWS, cdata->herr);

	/* create data model */
        model = g_object_new (GDA_TYPE_ORACLE_RECORDSET, 
			      "connection", cnc,
			      "prepared-stmt", ps, 
			      "model-usage", rflags, 
			      "exec-params", exec_params, NULL);
	GDA_DATA_SELECT (model)->advertized_nrows = nb_rows;
	
        return GDA_DATA_MODEL (model);
}
示例#13
0
static GdaRow *
fetch_next_sqlite_row (GdaSqliteRecordset *model, gboolean do_store, GError **error)
{
	int rc;
	SqliteConnectionData *cdata;
	GdaSqlitePStmt *ps;
	GdaRow *prow = NULL;
	GdaConnection *cnc;
	glong length;

	cnc = gda_data_select_get_connection ((GdaDataSelect*) model);
	cdata = (SqliteConnectionData*) gda_connection_internal_get_provider_data_error (cnc, error);
	if (!cdata)
		return NULL;
	ps = GDA_SQLITE_PSTMT (GDA_DATA_SELECT (model)->prep_stmt);

	virt_cnc_set_working_obj (gda_data_select_get_connection ((GdaDataSelect*) model), model);

	if (model->priv->empty_forced)
		rc = SQLITE_DONE;
	else		
		rc = SQLITE3_CALL (sqlite3_step) (ps->sqlite_stmt);
	switch (rc) {
	case  SQLITE_ROW: {
		gint col, real_col;
		prow = gda_row_new (_GDA_PSTMT (ps)->ncols);
		for (col = 0; col < _GDA_PSTMT (ps)->ncols; col++) {
			GValue *value;
			GType type = _GDA_PSTMT (ps)->types [col];
			
			real_col = col + ps->nb_rowid_columns;

			if (type == GDA_TYPE_NULL) {
				type = fuzzy_get_gtype (cdata, ps, col);
				if (type == GDA_TYPE_BLOB) {
					/* extra check: make sure we have a rowid for this blob, or fallback to binary */
					if (ps->rowid_hash) {
						gint oidcol = 0;
						const char *ctable;
						ctable = SQLITE3_CALL (sqlite3_column_name) (ps->sqlite_stmt, real_col);
						if (ctable)
							oidcol = GPOINTER_TO_INT (g_hash_table_lookup (ps->rowid_hash,
												       ctable));
						if (oidcol == 0) {
							ctable = SQLITE3_CALL (sqlite3_column_table_name) (ps->sqlite_stmt, real_col);
							if (ctable)
								oidcol = GPOINTER_TO_INT (g_hash_table_lookup (ps->rowid_hash, 
													       ctable));
						}
						if (oidcol == 0)
							type = GDA_TYPE_BINARY;
					}
					else
						type = GDA_TYPE_BINARY;
				}
				if (type != GDA_TYPE_NULL) {
					GdaColumn *column;
					
					_GDA_PSTMT (ps)->types [col] = type;
					column = gda_data_model_describe_column (GDA_DATA_MODEL (model), col);
					gda_column_set_g_type (column, type);
					column = (GdaColumn *) g_slist_nth_data (_GDA_PSTMT (ps)->tmpl_columns, col);
					gda_column_set_g_type (column, type);
				}
			}
			
			/* fill GValue */
			value = gda_row_get_value (prow, col);
			GError *may_error;
			may_error = (GError*) SQLITE3_CALL (sqlite3_column_blob) (ps->sqlite_stmt, real_col);
			if (may_error && g_hash_table_lookup (error_blobs_hash, may_error)) {
				/*g_print ("Row invalidated: [%s]\n", may_error->message);*/
				gda_row_invalidate_value_e (prow, value, may_error);
				g_hash_table_remove (error_blobs_hash, may_error);
			}
			else if (SQLITE3_CALL (sqlite3_column_text) (ps->sqlite_stmt, real_col) == NULL) {
				/* we have a NULL value */
				gda_value_set_null (value);
			}
			else {
				gda_value_reset_with_type (value, type);
				
				if (type == GDA_TYPE_NULL)
					;
				else if (type == G_TYPE_INT) {
					gint64 i;
					i = SQLITE3_CALL (sqlite3_column_int64) (ps->sqlite_stmt, real_col);
					if ((i > G_MAXINT) || (i < G_MININT)) {
						GError *lerror = NULL;
						g_set_error (&lerror, GDA_SERVER_PROVIDER_ERROR,
							     GDA_SERVER_PROVIDER_DATA_ERROR,
							     "%s", _("Integer value is too big"));
						gda_row_invalidate_value_e (prow, value, lerror);
					}
					else
						g_value_set_int (value, (gint) i);
				}
				else if (type == G_TYPE_UINT) {
					guint64 i;
					i = (gint64) SQLITE3_CALL (sqlite3_column_int64) (ps->sqlite_stmt, real_col);
					if (i > G_MAXUINT) {
						GError *lerror = NULL;
						g_set_error (&lerror, GDA_SERVER_PROVIDER_ERROR,
							     GDA_SERVER_PROVIDER_DATA_ERROR,
							     "%s", _("Integer value is too big"));
						gda_row_invalidate_value_e (prow, value, lerror);
					}
					else
						g_value_set_uint (value, (gint) i);
				}
				else if (type == G_TYPE_INT64)
					g_value_set_int64 (value, SQLITE3_CALL (sqlite3_column_int64) (ps->sqlite_stmt, real_col));
				else if (type == G_TYPE_UINT64)
					g_value_set_uint64 (value, (guint64) SQLITE3_CALL (sqlite3_column_int64) (ps->sqlite_stmt,
												   real_col));
				else if (type == G_TYPE_DOUBLE)
					g_value_set_double (value, SQLITE3_CALL (sqlite3_column_double) (ps->sqlite_stmt,
											  real_col));
				else if (type == G_TYPE_STRING)
					g_value_set_string (value, (gchar *) SQLITE3_CALL (sqlite3_column_text) (ps->sqlite_stmt,
												  real_col));
				else if (type == GDA_TYPE_BINARY) {
					GdaBinary *bin;
					
					bin = gda_binary_new ();
					length = SQLITE3_CALL (sqlite3_column_bytes) (ps->sqlite_stmt, real_col);
					if (length > 0) {
						gda_binary_set_data (bin, SQLITE3_CALL (sqlite3_column_blob) (ps->sqlite_stmt, /* Flawfinder: ignore */
												       real_col), length);
					}
					gda_value_take_binary (value, bin);
				}
				else if (type == GDA_TYPE_BLOB) {
					GdaBlobOp *bop = NULL;
					gint oidcol = 0;

					if (ps->rowid_hash) {
						const char *ctable;
						ctable = SQLITE3_CALL (sqlite3_column_name) (ps->sqlite_stmt, real_col);
						if (ctable)
							oidcol = GPOINTER_TO_INT (g_hash_table_lookup (ps->rowid_hash,
												       ctable));
						if (oidcol == 0) {
							ctable = SQLITE3_CALL (sqlite3_column_table_name) (ps->sqlite_stmt, real_col);
							if (ctable)
								oidcol = GPOINTER_TO_INT (g_hash_table_lookup (ps->rowid_hash, 
													       ctable));
						}
					}
					if (oidcol != 0) {
						gint64 rowid;
						rowid = SQLITE3_CALL (sqlite3_column_int64) (ps->sqlite_stmt, oidcol - 1); /* remove 1
													       because it was added in the first place */
						bop = _gda_sqlite_blob_op_new (cnc,
									       SQLITE3_CALL (sqlite3_column_database_name) (ps->sqlite_stmt, 
													    real_col),
									       SQLITE3_CALL (sqlite3_column_table_name) (ps->sqlite_stmt,
													 real_col),
									       SQLITE3_CALL (sqlite3_column_origin_name) (ps->sqlite_stmt,
													  real_col),
									      rowid);
					}
					if (!bop) {
						GError *lerror = NULL;
						g_set_error (&lerror, GDA_SERVER_PROVIDER_ERROR,
							     GDA_SERVER_PROVIDER_DATA_ERROR,
							     "%s", _("Unable to open BLOB"));
						gda_row_invalidate_value_e (prow, value, lerror);
					}
					else {
						GdaBlob *blob;
						blob = gda_blob_new ();
						gda_blob_set_op (blob, bop);
						g_object_unref (bop);
						gda_value_take_blob (value, blob);
					}
				}
				else if (type == G_TYPE_BOOLEAN)
					g_value_set_boolean (value, SQLITE3_CALL (sqlite3_column_int) (ps->sqlite_stmt, real_col) == 0 ? FALSE : TRUE);
				else if (type == G_TYPE_DATE) {
					GDate date;
					if (!gda_parse_iso8601_date (&date, 
								     (gchar *) SQLITE3_CALL (sqlite3_column_text) (ps->sqlite_stmt, 
												    real_col))) {
						GError *lerror = NULL;
						g_set_error (&lerror, GDA_SERVER_PROVIDER_ERROR,
							     GDA_SERVER_PROVIDER_DATA_ERROR,
							     _("Invalid date '%s' (date format should be YYYY-MM-DD)"), 
							     (gchar *) SQLITE3_CALL (sqlite3_column_text) (ps->sqlite_stmt, real_col));
						gda_row_invalidate_value_e (prow, value, lerror);
					}
					else
						g_value_set_boxed (value, &date);
				}
				else if (type == GDA_TYPE_TIME) {
					GdaTime timegda;
					if (!gda_parse_iso8601_time (&timegda, 
								     (gchar *) SQLITE3_CALL (sqlite3_column_text) (ps->sqlite_stmt, 
												    real_col))) {
						GError *lerror = NULL;
						g_set_error (&lerror, GDA_SERVER_PROVIDER_ERROR,
							     GDA_SERVER_PROVIDER_DATA_ERROR,
							     _("Invalid time '%s' (time format should be HH:MM:SS[.ms])"), 
							     (gchar *) SQLITE3_CALL (sqlite3_column_text) (ps->sqlite_stmt, real_col));
						gda_row_invalidate_value_e (prow, value, lerror);
					}
					else {
						if (timegda.timezone == GDA_TIMEZONE_INVALID)
							timegda.timezone = 0; /* set to GMT */
						gda_value_set_time (value, &timegda);
					}
				}
				else if (type == GDA_TYPE_TIMESTAMP) {
					GdaTimestamp timestamp;
					if (!gda_parse_iso8601_timestamp (&timestamp, 
									  (gchar *) SQLITE3_CALL (sqlite3_column_text) (ps->sqlite_stmt,
													 real_col))) {
						GError *lerror = NULL;
						g_set_error (&lerror, GDA_SERVER_PROVIDER_ERROR,
							     GDA_SERVER_PROVIDER_DATA_ERROR,
							     _("Invalid timestamp '%s' (format should be YYYY-MM-DD HH:MM:SS[.ms])"), 
							     (gchar *) SQLITE3_CALL (sqlite3_column_text) (ps->sqlite_stmt, real_col));
						gda_row_invalidate_value_e (prow, value, lerror);
					}
					else {
						if (timestamp.timezone == GDA_TIMEZONE_INVALID)
							timestamp.timezone = 0; /* set to GMT */
						gda_value_set_timestamp (value, &timestamp);
					}
				}
				else if (type == G_TYPE_CHAR) {
					gint64 i;
					i = (gint64) SQLITE3_CALL (sqlite3_column_int64) (ps->sqlite_stmt, real_col);
					if ((i > G_MAXINT8) || (i < G_MININT8)) {
						GError *lerror = NULL;
						g_set_error (&lerror, GDA_SERVER_PROVIDER_ERROR,
							     GDA_SERVER_PROVIDER_DATA_ERROR,
							     "%s", _("Integer value is too big"));
						gda_row_invalidate_value_e (prow, value, lerror);
					}
					else
						g_value_set_schar (value, (gchar) i);
				}
				else if (type == G_TYPE_UCHAR) {
					gint64 i;
					i = (gint64) SQLITE3_CALL (sqlite3_column_int64) (ps->sqlite_stmt, real_col);
					if ((i > G_MAXUINT8) || (i < 0)) {
						GError *lerror = NULL;
						g_set_error (&lerror, GDA_SERVER_PROVIDER_ERROR,
							     GDA_SERVER_PROVIDER_DATA_ERROR,
							     "%s", _("Integer value is too big"));
						gda_row_invalidate_value_e (prow, value, lerror);
					}
					else
						g_value_set_uchar (value, (guchar) i);
				}
				else if (type == GDA_TYPE_SHORT) {
					gint64 i;
					i = (gint64) SQLITE3_CALL (sqlite3_column_int64) (ps->sqlite_stmt, real_col);
					if ((i > G_MAXSHORT) || (i < G_MINSHORT)) {
						GError *lerror = NULL;
						g_set_error (&lerror, GDA_SERVER_PROVIDER_ERROR,
							     GDA_SERVER_PROVIDER_DATA_ERROR,
							     "%s", _("Integer value is too big"));
						gda_row_invalidate_value_e (prow, value, lerror);
					}
					else
						gda_value_set_short (value, (guchar) i);
				}
				else if (type == GDA_TYPE_USHORT) {
					gint64 i;
					i = (gint64) SQLITE3_CALL (sqlite3_column_int64) (ps->sqlite_stmt, real_col);
					if ((i > G_MAXUSHORT) || (i < 0)) {
						GError *lerror = NULL;
						g_set_error (&lerror, GDA_SERVER_PROVIDER_ERROR,
							     GDA_SERVER_PROVIDER_DATA_ERROR,
							     "%s", _("Integer value is too big"));
						gda_row_invalidate_value_e (prow, value, lerror);
					}
					else
						gda_value_set_ushort (value, (guchar) i);
				}
				else {
					GError *lerror = NULL;
					g_set_error (&lerror, GDA_SERVER_PROVIDER_ERROR,
						     GDA_SERVER_PROVIDER_DATA_ERROR,
						     "Unhandled type '%s' in SQLite recordset",
						     gda_g_type_to_string (_GDA_PSTMT (ps)->types [col]));
					gda_row_invalidate_value_e (prow, value, lerror);
				}
			}
		}
		
		if (do_store) {
			/* insert row */
			gda_data_select_take_row (GDA_DATA_SELECT (model), prow, model->priv->next_row_num);
		}
		model->priv->next_row_num ++;
		break;
	}
	case SQLITE_BUSY:
		/* nothing to do */
		break;
	case SQLITE_DONE:
		GDA_DATA_SELECT (model)->advertized_nrows = model->priv->next_row_num;
		SQLITE3_CALL (sqlite3_reset) (ps->sqlite_stmt);
		break;
	case SQLITE_READONLY:
	case SQLITE_MISUSE:
		g_set_error (error, GDA_SERVER_PROVIDER_ERROR,
			     GDA_SERVER_PROVIDER_INTERNAL_ERROR, 
			      "%s", _("SQLite provider fatal internal error"));
		break;
	case SQLITE_ERROR:
	default: {
		GError *lerror = NULL;
		SQLITE3_CALL (sqlite3_reset) (ps->sqlite_stmt);
		if (rc == SQLITE_IOERR_TRUNCATE)
			g_set_error (&lerror, GDA_DATA_MODEL_ERROR,
				     GDA_DATA_MODEL_TRUNCATED_ERROR, "%s", _("Truncated data"));
		else
			g_set_error (&lerror, GDA_SERVER_PROVIDER_ERROR,
				     GDA_SERVER_PROVIDER_INTERNAL_ERROR, 
				     "%s", SQLITE3_CALL (sqlite3_errmsg) (cdata->connection));
		gda_data_select_add_exception (GDA_DATA_SELECT (model), lerror);
		if (rc == SQLITE_ERROR)
			g_propagate_error (error, g_error_copy (lerror));
		GDA_DATA_SELECT (model)->advertized_nrows = model->priv->next_row_num;
		break;
	}
	}

	virt_cnc_set_working_obj (gda_data_select_get_connection ((GdaDataSelect*) model), NULL);

	return prow;
}
示例#14
0
/*
 * the @ps struct is modified and transferred to the new data model created in
 * this function
 */
GdaDataModel *
_gda_sqlite_recordset_new (GdaConnection *cnc, GdaSqlitePStmt *ps, GdaSet *exec_params,
			   GdaDataModelAccessFlags flags, GType *col_types, gboolean force_empty)
{
	GdaSqliteRecordset *model;
        SqliteConnectionData *cdata;
        gint i;
	GdaDataModelAccessFlags rflags;

        g_return_val_if_fail (GDA_IS_CONNECTION (cnc), NULL);
        g_return_val_if_fail (ps != NULL, NULL);

	cdata = (SqliteConnectionData*) gda_connection_internal_get_provider_data_error (cnc, NULL);
	if (!cdata)
		return NULL;

        if (!cdata->types_hash)
                _gda_sqlite_compute_types_hash (cdata);

        /* make sure @ps reports the correct number of columns */
	if (_GDA_PSTMT (ps)->ncols < 0)
		_GDA_PSTMT (ps)->ncols = SQLITE3_CALL (sqlite3_column_count) (ps->sqlite_stmt) -
			ps->nb_rowid_columns;

        /* completing ps */
	g_assert (! ps->stmt_used);
        ps->stmt_used = TRUE;
        if (!_GDA_PSTMT (ps)->types && (_GDA_PSTMT (ps)->ncols > 0)) {
		/* create prepared statement's columns */
		GSList *list;
		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);
					else 
						_GDA_PSTMT (ps)->types [i] = col_types [i];
				}
			}
		}
		
		/* fill GdaColumn's data */
		for (i=0, list = _GDA_PSTMT (ps)->tmpl_columns; 
		     i < GDA_PSTMT (ps)->ncols; 
		     i++, list = list->next) {
			GdaColumn *column;
			gint real_col = i + ps->nb_rowid_columns;
			
			column = GDA_COLUMN (list->data);
			gda_column_set_description (column, SQLITE3_CALL (sqlite3_column_name) (ps->sqlite_stmt, real_col));
			gda_column_set_name (column, SQLITE3_CALL (sqlite3_column_name) (ps->sqlite_stmt, real_col));
			gda_column_set_dbms_type (column, SQLITE3_CALL (sqlite3_column_decltype) (ps->sqlite_stmt, real_col));
			if (_GDA_PSTMT (ps)->types [i] != GDA_TYPE_NULL)
				gda_column_set_g_type (column, _GDA_PSTMT (ps)->types [i]);
		}
        }

	/* determine access mode: RANDOM or CURSOR FORWARD are the only supported; if CURSOR BACKWARD
	 * is requested, then we need RANDOM mode */
	if (flags & GDA_DATA_MODEL_ACCESS_RANDOM)
		rflags = GDA_DATA_MODEL_ACCESS_RANDOM;
	else if (flags & GDA_DATA_MODEL_ACCESS_CURSOR_BACKWARD)
		rflags = GDA_DATA_MODEL_ACCESS_RANDOM;
	else
		rflags = GDA_DATA_MODEL_ACCESS_CURSOR_FORWARD;

	/* create data model */
        model = g_object_new (GDA_TYPE_SQLITE_RECORDSET,
			      "connection", cnc,
			      "prepared-stmt", ps, "model-usage", rflags, 
			      "exec-params", exec_params, 
			      "auto-reset", force_empty, NULL);
	gboolean is_virt;
	is_virt = GDA_IS_VCONNECTION_DATA_MODEL (cnc) ? TRUE : FALSE;
	if (is_virt) {
		/* steal the lock */
		_gda_vconnection_change_working_obj ((GdaVconnectionDataModel*) cnc, (GObject*) model);
		_gda_vconnection_set_working_obj ((GdaVconnectionDataModel*) cnc, NULL);
	}

        /* fill the data model */
        read_rows_to_init_col_types (model);

        return GDA_DATA_MODEL (model);
}
示例#15
0
gchar *
gda_postgres_render_CREATE_USER (GdaServerProvider *provider, GdaConnection *cnc, 
				 GdaServerOperation *op, G_GNUC_UNUSED GError **error)
{
	GString *string;
	const GValue *value;
	gchar *sql = NULL;
	gchar *tmp;
	gboolean with = FALSE, first, use_role = TRUE;
	gint nrows, i;
	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 ("CREATE ROLE ");
	else
		string = g_string_new ("CREATE USER ");

	tmp = gda_server_operation_get_sql_identifier_at (op, cnc, provider, "/USER_DEF_P/USER_NAME", error);
	if (!tmp) {
		g_string_free (string, TRUE);
		return NULL;
	}

	g_string_append (string, tmp);
	g_free (tmp);

	value = gda_server_operation_get_value_at (op, "/USER_DEF_P/PASSWORD");
	if (value && G_VALUE_HOLDS (value, G_TYPE_STRING) &&
	    g_value_get_string (value) && (*g_value_get_string (value))) {
		GdaDataHandler *dh;
		const GValue *value2;

		g_string_append (string, " WITH");
		with = TRUE;

		value2 = gda_server_operation_get_value_at (op, "/USER_DEF_P/PASSWORD_ENCRYPTED");
		if (value2 && G_VALUE_HOLDS (value2, G_TYPE_BOOLEAN) && g_value_get_boolean (value2))
			g_string_append (string, " ENCRYPTED");

		g_string_append (string, " PASSWORD ");
		dh = gda_server_provider_get_data_handler_g_type (provider, cnc, G_TYPE_STRING);
		if (!dh)
			dh = gda_data_handler_get_default (G_TYPE_STRING);

		tmp = gda_data_handler_get_sql_from_value (dh, value);
		g_string_append (string, tmp);
		g_free (tmp);
	}

	value = gda_server_operation_get_value_at (op, "/USER_DEF_P/UID");
	if (value && G_VALUE_HOLDS (value, G_TYPE_UINT)) {
		if (!with) {
			g_string_append (string, " WITH");
			with = TRUE;
		}
		g_string_append_printf (string, "SYSID %u", g_value_get_uint (value));
	}

	value = gda_server_operation_get_value_at (op, "/USER_DEF_P/CAP_SUPERUSER");
	if (value && G_VALUE_HOLDS (value, G_TYPE_BOOLEAN) && g_value_get_boolean (value)) {
		if (!with) {
			g_string_append (string, " WITH");
			with = TRUE;
		}
		g_string_append (string, " SUPERUSER");
	}

	value = gda_server_operation_get_value_at (op, "/USER_DEF_P/CAP_CREATEDB");
	if (value && G_VALUE_HOLDS (value, G_TYPE_BOOLEAN) && g_value_get_boolean (value)) {
		if (!with) {
			g_string_append (string, " WITH");
			with = TRUE;
		}
		g_string_append (string, " CREATEDB");
	}

	value = gda_server_operation_get_value_at (op, "/USER_DEF_P/CAP_CREATEROLE");
	if (value && G_VALUE_HOLDS (value, G_TYPE_BOOLEAN) && g_value_get_boolean (value)) {
		if (!with) {
			g_string_append (string, " WITH");
			with = TRUE;
		}
		g_string_append (string, " CREATEROLE");
	}

	value = gda_server_operation_get_value_at (op, "/USER_DEF_P/CAP_CREATEUSER");
	if (value && G_VALUE_HOLDS (value, G_TYPE_BOOLEAN) && g_value_get_boolean (value)) {
		if (!with) {
			g_string_append (string, " WITH");
			with = TRUE;
		}
		g_string_append (string, " CREATEUSER");
	}

	value = gda_server_operation_get_value_at (op, "/USER_DEF_P/CAP_INHERIT");
	if (value && G_VALUE_HOLDS (value, G_TYPE_BOOLEAN) && g_value_get_boolean (value)) {
		if (!with) {
			g_string_append (string, " WITH");
			with = TRUE;
		}
		g_string_append (string, " INHERIT");
	}
	else {
		if (!with) {
			g_string_append (string, " WITH");
			with = TRUE;
		}
		g_string_append (string, " NOINHERIT");
	}

	value = gda_server_operation_get_value_at (op, "/USER_DEF_P/CAP_LOGIN");
	if (value && G_VALUE_HOLDS (value, G_TYPE_BOOLEAN) && g_value_get_boolean (value)) {
		g_string_append (string, " LOGIN");
		value = gda_server_operation_get_value_at (op, "/USER_DEF_P/CNX_LIMIT");
		if (value && G_VALUE_HOLDS (value, G_TYPE_INT))
			g_string_append_printf (string, " CONNECTION LIMIT %d",
						g_value_get_int (value));
	}

	
	nrows = gda_server_operation_get_sequence_size (op, "/GROUPS_S");
	for (first  = TRUE, i = 0; i < nrows; i++) {
		gchar *name;
		if (use_role)
			name = gda_server_operation_get_sql_identifier_at (op, cnc, provider, "/GROUPS_S/%d/ROLE",
									   error, i);
		else
			name = gda_server_operation_get_sql_identifier_at (op, cnc, provider, "/GROUPS_S/%d/USER",
									   error, i);

		if (name) {
			if (first) {
				first = FALSE;
				if (use_role)
					g_string_append (string, " IN ROLE ");
				else
					g_string_append (string, " IN GROUP ");
			}
			else
				g_string_append (string, ", ");

			g_string_append (string, name);
			g_free (name);
		}
		else {
			g_string_free (string, TRUE);
			return NULL;
		}
	}

	nrows = gda_server_operation_get_sequence_size (op, "/ROLES_S");
	for (first  = TRUE, i = 0; i < nrows; i++) {
		gchar *name;
		name = gda_server_operation_get_sql_identifier_at (op, cnc, provider, "/ROLES_S/%d/ROLE", error, i);
		if (name) {
			if (first) {
				first = FALSE;
				g_string_append (string, " ROLE ");
			}
			else
				g_string_append (string, ", ");

			g_string_append (string, name);
			g_free (name);
		}
		else {
			g_string_free (string, TRUE);
			return NULL;
		}
	}

	nrows = gda_server_operation_get_sequence_size (op, "/ADMINS_S");
	for (first  = TRUE, i = 0; i < nrows; i++) {
		gchar *name;
		name = gda_server_operation_get_sql_identifier_at (op, cnc, provider, "/ADMINS_S/%d/ROLE", error, i);
		if (name) {
			if (first) {
				first = FALSE;
				g_string_append (string, " ADMIN ");
			}
			else
				g_string_append (string, ", ");

			g_string_append (string, name);
			g_free (name);
		}
		else {
			g_string_free (string, TRUE);
			return NULL;
		}
	}
	
	value = gda_server_operation_get_value_at (op, "/USER_DEF_P/VALIDITY");
	if (value && G_VALUE_HOLDS (value, GDA_TYPE_TIMESTAMP)) {
		if (value) {
			GdaDataHandler *dh;
			if (!with) {
				g_string_append (string, " WITH");
				with = TRUE;
			}
			dh = gda_server_provider_get_data_handler_g_type (provider, cnc, GDA_TYPE_TIMESTAMP);
			if (!dh)
				dh = gda_data_handler_get_default (GDA_TYPE_TIMESTAMP);
			
			g_string_append (string, " VALID UNTIL ");
			tmp = gda_data_handler_get_sql_from_value (dh, value);
			g_string_append (string, tmp);
			g_free (tmp);
		}
	}

	sql = string->str;
	g_string_free (string, FALSE);

	return sql;
}
示例#16
0
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);
}
示例#17
0
/*
 * 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);
}
示例#18
0
GdaBlobOp *
_gda_sqlite_blob_op_new (GdaConnection *cnc,
			 const gchar *db_name, const gchar *table_name,
			 const gchar *column_name, sqlite3_int64 rowid)
{
	GdaSqliteBlobOp *bop = NULL;
	int rc;
	sqlite3_blob *sblob;
	gchar *db, *table;
	gboolean free_strings = TRUE;
	gboolean transaction_started = FALSE;

	g_return_val_if_fail (GDA_IS_CONNECTION (cnc), NULL);
	g_return_val_if_fail (table_name, NULL);
	g_return_val_if_fail (column_name, NULL);
	g_return_val_if_fail (GDA_IS_SQLITE_PROVIDER (gda_connection_get_provider (cnc)), NULL);
  GdaSqliteBlobOpPrivate *priv = gda_sqlite_blob_op_get_instance_private (bop);

	if (db_name) {
		db = (gchar *) db_name;
		table = (gchar *) table_name;
		free_strings = FALSE;
	}
	else if (! _split_identifier_string (g_strdup (table_name), &db, &table))
		return NULL;

	SqliteConnectionData *cdata;
	cdata = (SqliteConnectionData*) gda_connection_internal_get_provider_data_error (cnc, NULL);
	if (!cdata ||
	    ! _gda_sqlite_check_transaction_started (cnc, &transaction_started, NULL))
		return NULL;

	GdaSqliteProvider *prov = GDA_SQLITE_PROVIDER (gda_connection_get_provider (cnc));

	rc = SQLITE3_CALL (prov, sqlite3_blob_open) (cdata->connection,
	                                       db ? db : "main",
	                                       table, column_name, rowid,
	                                       1, /* Read & Write */
	                                       &(sblob));
	if (rc != SQLITE_OK) {
#ifdef GDA_DEBUG_NO
		g_print ("ERROR: %s\n", SQLITE3_CALL (prov, sqlite3_errmsg) (cdata->connection));
#endif
		if (transaction_started)
			gda_connection_rollback_transaction (cnc, NULL, NULL);
		goto out;
	}

	bop = g_object_new (GDA_TYPE_SQLITE_BLOB_OP, "connection", cnc, NULL);
	priv->sblob = sblob;
	g_weak_ref_set (&priv->provider, prov);
#ifdef GDA_DEBUG_NO
	g_print ("OPENED blob %p\n", bop);
#endif

 out:
	if (free_strings) {
		g_free (db);
		g_free (table);
	}
	return (GdaBlobOp*) bop;
}