1 /*
2  * Copyright (C) 2008 Murray Cumming <murrayc@murrayc.com>
3  * Copyright (C) 2008 - 2011 Vivien Malerba <malerba@gnome-db.org>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
18  * Boston, MA  02110-1301, USA.
19  */
20 
21 #include <glib/gi18n-lib.h>
22 #include "gda-jdbc-util.h"
23 
24 extern JavaVM *_jdbc_provider_java_vm;
25 
26 /**
27  * _gda_jdbc_make_error
28  *
29  * warning: STEALS @sql_state and @error.
30  * Create a new #GdaConnectionEvent object and "adds" it to @cnc
31  *
32  * Returns: a new GdaConnectionEvent which must not be unrefed()
33  */
34 GdaConnectionEvent *
_gda_jdbc_make_error(GdaConnection * cnc,gint error_code,gchar * sql_state,GError * error)35 _gda_jdbc_make_error (GdaConnection *cnc, gint error_code, gchar *sql_state, GError *error)
36 {
37 	GdaConnectionEvent *error_ev;
38         GdaConnectionEventCode gda_code = GDA_CONNECTION_EVENT_CODE_UNKNOWN;
39         GdaTransactionStatus *trans;
40 
41         error_ev = GDA_CONNECTION_EVENT (g_object_new (GDA_TYPE_CONNECTION_EVENT, "type",
42 						       (gint) GDA_CONNECTION_EVENT_ERROR, NULL));
43 	if (error) {
44 		gda_connection_event_set_description (error_ev,
45 						      error->message ? error->message : _("No detail"));
46 		g_error_free (error);
47 	}
48 	gda_connection_event_set_sqlstate (error_ev, sql_state);
49 	g_free (sql_state);
50 	gda_connection_event_set_code (error_ev, error_code);
51 	gda_connection_event_set_gda_code (error_ev, gda_code);
52         gda_connection_event_set_source (error_ev, "gda-jdbc");
53         gda_connection_add_event (cnc, error_ev);
54 
55         /* change the transaction status if there is a problem */
56         trans = gda_connection_get_transaction_status (cnc);
57         if (trans) {
58 		/*
59                 if ((PQtransactionStatus (pconn) == PQTRANS_INERROR) &&
60                     (trans->state != GDA_TRANSACTION_STATUS_STATE_FAILED))
61                         gda_connection_internal_change_transaction_state (cnc,
62                                                                           GDA_TRANSACTION_STATUS_STATE_FAILED);
63 		*/
64         }
65         return error_ev;
66 }
67 
68 /**
69  * _gda_jdbc_get_jenv
70  * @out_needs_detach: SHOULD NOT BE NULL
71  *
72  * Returns: a JNIEnv or %NULL if an error occurred
73  */
74 JNIEnv *
_gda_jdbc_get_jenv(gboolean * out_needs_detach,GError ** error)75 _gda_jdbc_get_jenv (gboolean *out_needs_detach, GError **error)
76 {
77 	jint atres;
78 	JNIEnv *env;
79 
80 	*out_needs_detach = FALSE;
81 	atres = (*_jdbc_provider_java_vm)->GetEnv (_jdbc_provider_java_vm, (void**) &env, JNI_VERSION_1_2);
82 	if (atres == JNI_EDETACHED) {
83 		if ((*_jdbc_provider_java_vm)->AttachCurrentThread (_jdbc_provider_java_vm, (void**) &env, NULL) < 0)
84 			g_set_error (error, GDA_SERVER_PROVIDER_ERROR,
85 				     GDA_SERVER_PROVIDER_INTERNAL_ERROR,
86 				     "%s", "Could not attach JAVA virtual machine's current thread");
87 		else
88 			*out_needs_detach = TRUE;
89 	}
90 	else if (atres == JNI_EVERSION)
91 		g_set_error (error, GDA_SERVER_PROVIDER_ERROR,
92 			     GDA_SERVER_PROVIDER_INTERNAL_ERROR,
93 			     "%s", "Could not attach JAVA virtual machine's current thread");
94 	return env;
95 }
96 
97 void
_gda_jdbc_release_jenv(gboolean needs_detach)98 _gda_jdbc_release_jenv (gboolean needs_detach)
99 {
100 	if (needs_detach)
101 		(*_jdbc_provider_java_vm)->DetachCurrentThread (_jdbc_provider_java_vm);
102 }
103 
104 /*
105  * converts a GType to an INT identifier used to communicate types with JDBC. The corresponding
106  * decoding method on the JAVA side is GdaJValue.proto_type_to_jvalue()
107  *
108  * Any new type added here must also be added to the GdaJValue.proto_type_to_jvalue() method
109  */
110 int
_gda_jdbc_gtype_to_proto_type(GType type)111 _gda_jdbc_gtype_to_proto_type (GType type)
112 {
113 	if (type == G_TYPE_STRING)
114 		return 1;
115 	else if (type == G_TYPE_INT)
116 		return 2;
117 	else if (type == G_TYPE_CHAR)
118 		return 3;
119 	else if (type == G_TYPE_DOUBLE)
120 		return 4;
121 	else if (type == G_TYPE_FLOAT)
122 		return 5;
123 	else if (type == G_TYPE_BOOLEAN)
124 		return 6;
125 	else if (type == G_TYPE_DATE)
126 		return 7;
127 	else if (type == GDA_TYPE_TIME)
128 		return 8;
129 	else if (type == GDA_TYPE_TIMESTAMP)
130 		return 9;
131 	else if (type == GDA_TYPE_BINARY)
132 		return 10;
133 	else if (type == GDA_TYPE_BLOB)
134 		return 11;
135 	else if (type == G_TYPE_INT64)
136 		return 12;
137 	else if (type == GDA_TYPE_SHORT)
138 		return 13;
139 	else if (type == GDA_TYPE_NUMERIC)
140 		return 14;
141 	else
142 		return 0; /* GDA_TYPE_NULL */
143 }
144