1 /*
2  * Copyright (C) 2010 Robert Ancell <robert.ancell@canonical.com>
3  * Copyright (C) 2010 - 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 <libgda/libgda.h>
23 #include "gda-symbols-util.h"
24 
25 Sqlite3ApiRoutines *s3r = NULL;
26 
27 
28 
29 static GModule *
30 find_sqlite_in_dir (const gchar *dir_name, const gchar *name_part)
31 {
32 	GDir *dir;
33 	GError *err = NULL;
34 	const gchar *name;
35 	GModule *handle = NULL;
36 
37 #ifdef GDA_DEBUG_NO
38 	g_print ("Looking for '%s' in %s\n", name_part, dir_name);
39 #endif
40 	dir = g_dir_open (dir_name, 0, &err);
41 	if (err) {
42 		gda_log_error (err->message);
43 		g_error_free (err);
44 		return FALSE;
45 	}
46 
47 	while ((name = g_dir_read_name (dir))) {
48 		const gchar *ptr1, *ptr2;
49 		ptr1 = g_strrstr (name, "." G_MODULE_SUFFIX);
50 		if (! ptr1)
51 			continue;
52 		ptr2 = g_strrstr (name, name_part);
53 		if (!ptr2)
54 			continue;
55 		if (ptr1 < ptr2)
56 			continue;
57 
58 		gchar *path;
59 
60 		path = g_build_path (G_DIR_SEPARATOR_S, dir_name, name, NULL);
61 		handle = g_module_open (path, G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL);
62 		g_free (path);
63 		if (!handle) {
64 			/*g_warning (_("Error: %s"), g_module_error ());*/
65 			continue;
66 		}
67 
68 		gpointer func;
69 		if (g_module_symbol (handle, "sqlite3_open", &func)) {
70 #ifdef GDA_DEBUG_NO
71 			path = g_build_path (G_DIR_SEPARATOR_S, dir_name, name, NULL);
72 			g_print ("'%s' found as: '%s'\n", name_part, path);
73 			g_free (path);
74 #endif
75 			break;
76 		}
77 		else {
78 			g_module_close (handle);
79 			handle = NULL;
80 		}
81 
82 	}
83 	/* free memory */
84 	g_dir_close (dir);
85 	return handle;
86 }
87 
88 GModule *
89 find_sqlite_library (const gchar *name_part)
90 {
91 	GModule *handle = NULL;
92 	const gchar *env;
93 
94 	/* first use the compile time SEARCH_LIB_PATH */
95 	if (SEARCH_LIB_PATH) {
96 		gchar **array;
97 		gint i;
98 		array = g_strsplit (SEARCH_LIB_PATH, ":", 0);
99 		for (i = 0; array[i]; i++) {
100 			handle = find_sqlite_in_dir (array [i], name_part);
101 			if (handle)
102 				break;
103 		}
104 		g_strfreev (array);
105 		if (handle)
106 			return handle;
107 	}
108 
109 	/* then try by 'normal' shared library finding */
110 	handle = g_module_open (name_part, G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL);
111 	if (handle) {
112 		gpointer func;
113 		if (g_module_symbol (handle, "sqlite3_open", &func)) {
114 #ifdef GDA_DEBUG_NO
115 			g_print ("'%s' found using default shared library finding\n", name_part);
116 #endif
117 			return handle;
118 		}
119 
120 		g_module_close (handle);
121 		handle = NULL;
122 	}
123 
124 	/* lastly, use LD_LIBRARY_PATH */
125 	env = g_getenv ("LD_LIBRARY_PATH");
126 	if (env) {
127 		gchar **array;
128 		gint i;
129 		array = g_strsplit (env, ":", 0);
130 		for (i = 0; array[i]; i++) {
131 			handle = find_sqlite_in_dir (array [i], name_part);
132 			if (handle)
133 				break;
134 		}
135 		g_strfreev (array);
136 		if (handle)
137 			return handle;
138 	}
139 
140 	return NULL;
141 }
142 
143 void
144 load_symbols (GModule *module)
145 {
146 	g_assert (module);
147 	s3r = g_new (Sqlite3ApiRoutines, 1);
148 
149 	if (! g_module_symbol (module, "sqlite3_bind_blob", (gpointer*) &(s3r->sqlite3_bind_blob)))
150 		goto onerror;
151 	if (! g_module_symbol (module, "sqlite3_bind_double", (gpointer*) &(s3r->sqlite3_bind_double)))
152 		goto onerror;
153 	if (! g_module_symbol (module, "sqlite3_bind_int", (gpointer*) &(s3r->sqlite3_bind_int)))
154 		goto onerror;
155 	if (! g_module_symbol (module, "sqlite3_bind_int64", (gpointer*) &(s3r->sqlite3_bind_int64)))
156 		goto onerror;
157 	if (! g_module_symbol (module, "sqlite3_bind_null", (gpointer*) &(s3r->sqlite3_bind_null)))
158 		goto onerror;
159 	if (! g_module_symbol (module, "sqlite3_bind_text", (gpointer*) &(s3r->sqlite3_bind_text)))
160 		goto onerror;
161 	if (! g_module_symbol (module, "sqlite3_bind_zeroblob", (gpointer*) &(s3r->sqlite3_bind_zeroblob)))
162 		goto onerror;
163 	if (! g_module_symbol (module, "sqlite3_blob_bytes", (gpointer*) &(s3r->sqlite3_blob_bytes)))
164 		goto onerror;
165 	if (! g_module_symbol (module, "sqlite3_blob_close", (gpointer*) &(s3r->sqlite3_blob_close)))
166 		goto onerror;
167 	if (! g_module_symbol (module, "sqlite3_blob_open", (gpointer*) &(s3r->sqlite3_blob_open)))
168 		goto onerror;
169 	if (! g_module_symbol (module, "sqlite3_blob_read", (gpointer*) &(s3r->sqlite3_blob_read)))
170 		goto onerror;
171 	if (! g_module_symbol (module, "sqlite3_blob_write", (gpointer*) &(s3r->sqlite3_blob_write)))
172 		goto onerror;
173 	if (! g_module_symbol (module, "sqlite3_busy_timeout", (gpointer*) &(s3r->sqlite3_busy_timeout)))
174 		goto onerror;
175 	if (! g_module_symbol (module, "sqlite3_changes", (gpointer*) &(s3r->sqlite3_changes)))
176 		goto onerror;
177 	if (! g_module_symbol (module, "sqlite3_clear_bindings", (gpointer*) &(s3r->sqlite3_clear_bindings)))
178 		goto onerror;
179 	if (! g_module_symbol (module, "sqlite3_close", (gpointer*) &(s3r->sqlite3_close)))
180 		goto onerror;
181 	if (! g_module_symbol (module, "sqlite3_column_blob", (gpointer*) &(s3r->sqlite3_column_blob)))
182 		goto onerror;
183 	if (! g_module_symbol (module, "sqlite3_column_bytes", (gpointer*) &(s3r->sqlite3_column_bytes)))
184 		goto onerror;
185 	if (! g_module_symbol (module, "sqlite3_column_count", (gpointer*) &(s3r->sqlite3_column_count)))
186 		goto onerror;
187 	if (! g_module_symbol (module, "sqlite3_column_database_name", (gpointer*) &(s3r->sqlite3_column_database_name)))
188 		goto onerror;
189 	if (! g_module_symbol (module, "sqlite3_column_decltype", (gpointer*) &(s3r->sqlite3_column_decltype)))
190 		goto onerror;
191 	if (! g_module_symbol (module, "sqlite3_column_double", (gpointer*) &(s3r->sqlite3_column_double)))
192 		goto onerror;
193 	if (! g_module_symbol (module, "sqlite3_column_int", (gpointer*) &(s3r->sqlite3_column_int)))
194 		goto onerror;
195 	if (! g_module_symbol (module, "sqlite3_column_int64", (gpointer*) &(s3r->sqlite3_column_int64)))
196 		goto onerror;
197 	if (! g_module_symbol (module, "sqlite3_column_name", (gpointer*) &(s3r->sqlite3_column_name)))
198 		goto onerror;
199 	if (! g_module_symbol (module, "sqlite3_column_origin_name", (gpointer*) &(s3r->sqlite3_column_origin_name)))
200 		goto onerror;
201 	if (! g_module_symbol (module, "sqlite3_column_table_name", (gpointer*) &(s3r->sqlite3_column_table_name)))
202 		goto onerror;
203 	if (! g_module_symbol (module, "sqlite3_column_text", (gpointer*) &(s3r->sqlite3_column_text)))
204 		goto onerror;
205 	if (! g_module_symbol (module, "sqlite3_column_type", (gpointer*) &(s3r->sqlite3_column_type)))
206 		goto onerror;
207 	if (! g_module_symbol (module, "sqlite3_config", (gpointer*) &(s3r->sqlite3_config)))
208 		goto onerror;
209 	if (! g_module_symbol (module, "sqlite3_create_function", (gpointer*) &(s3r->sqlite3_create_function)))
210 		goto onerror;
211 	if (! g_module_symbol (module, "sqlite3_create_module", (gpointer*) &(s3r->sqlite3_create_module)))
212 		goto onerror;
213 	if (! g_module_symbol (module, "sqlite3_db_handle", (gpointer*) &(s3r->sqlite3_db_handle)))
214 		goto onerror;
215 	if (! g_module_symbol (module, "sqlite3_declare_vtab", (gpointer*) &(s3r->sqlite3_declare_vtab)))
216 		goto onerror;
217 	if (! g_module_symbol (module, "sqlite3_errcode", (gpointer*) &(s3r->sqlite3_errcode)))
218 		goto onerror;
219 	if (! g_module_symbol (module, "sqlite3_errmsg", (gpointer*) &(s3r->sqlite3_errmsg)))
220 		goto onerror;
221 	if (! g_module_symbol (module, "sqlite3_exec", (gpointer*) &(s3r->sqlite3_exec)))
222 		goto onerror;
223 	if (! g_module_symbol (module, "sqlite3_extended_result_codes", (gpointer*) &(s3r->sqlite3_extended_result_codes)))
224 		goto onerror;
225 	if (! g_module_symbol (module, "sqlite3_finalize", (gpointer*) &(s3r->sqlite3_finalize)))
226 		goto onerror;
227 	if (! g_module_symbol (module, "sqlite3_free", (gpointer*) &(s3r->sqlite3_free)))
228 		goto onerror;
229 	if (! g_module_symbol (module, "sqlite3_free_table", (gpointer*) &(s3r->sqlite3_free_table)))
230 		goto onerror;
231 	if (! g_module_symbol (module, "sqlite3_get_table", (gpointer*) &(s3r->sqlite3_get_table)))
232 		goto onerror;
233 	if (! g_module_symbol (module, "sqlite3_last_insert_rowid", (gpointer*) &(s3r->sqlite3_last_insert_rowid)))
234 		goto onerror;
235 	if (! g_module_symbol (module, "sqlite3_malloc", (gpointer*) &(s3r->sqlite3_malloc)))
236 		goto onerror;
237 	if (! g_module_symbol (module, "sqlite3_mprintf", (gpointer*) &(s3r->sqlite3_mprintf)))
238 		goto onerror;
239 	if (! g_module_symbol (module, "sqlite3_open", (gpointer*) &(s3r->sqlite3_open)))
240 		goto onerror;
241 	if (! g_module_symbol (module, "sqlite3_prepare", (gpointer*) &(s3r->sqlite3_prepare)))
242 		goto onerror;
243 	if (! g_module_symbol (module, "sqlite3_prepare_v2", (gpointer*) &(s3r->sqlite3_prepare_v2)))
244 		goto onerror;
245 	if (! g_module_symbol (module, "sqlite3_reset", (gpointer*) &(s3r->sqlite3_reset)))
246 		goto onerror;
247 	if (! g_module_symbol (module, "sqlite3_result_blob", (gpointer*) &(s3r->sqlite3_result_blob)))
248 		goto onerror;
249 	if (! g_module_symbol (module, "sqlite3_result_double", (gpointer*) &(s3r->sqlite3_result_double)))
250 		goto onerror;
251 	if (! g_module_symbol (module, "sqlite3_result_error", (gpointer*) &(s3r->sqlite3_result_error)))
252 		goto onerror;
253 	if (! g_module_symbol (module, "sqlite3_result_int", (gpointer*) &(s3r->sqlite3_result_int)))
254 		goto onerror;
255 	if (! g_module_symbol (module, "sqlite3_result_int64", (gpointer*) &(s3r->sqlite3_result_int64)))
256 		goto onerror;
257 	if (! g_module_symbol (module, "sqlite3_result_null", (gpointer*) &(s3r->sqlite3_result_null)))
258 		goto onerror;
259 	if (! g_module_symbol (module, "sqlite3_result_text", (gpointer*) &(s3r->sqlite3_result_text)))
260 		goto onerror;
261 	if (! g_module_symbol (module, "sqlite3_step", (gpointer*) &(s3r->sqlite3_step)))
262 		goto onerror;
263 	if (! g_module_symbol (module, "sqlite3_table_column_metadata", (gpointer*) &(s3r->sqlite3_table_column_metadata)))
264 		goto onerror;
265 	if (! g_module_symbol (module, "sqlite3_threadsafe", (gpointer*) &(s3r->sqlite3_threadsafe)))
266 		goto onerror;
267 	if (! g_module_symbol (module, "sqlite3_value_blob", (gpointer*) &(s3r->sqlite3_value_blob)))
268 		goto onerror;
269 	if (! g_module_symbol (module, "sqlite3_value_bytes", (gpointer*) &(s3r->sqlite3_value_bytes)))
270 		goto onerror;
271 	if (! g_module_symbol (module, "sqlite3_value_int", (gpointer*) &(s3r->sqlite3_value_int)))
272 		goto onerror;
273 	if (! g_module_symbol (module, "sqlite3_value_int64", (gpointer*) &(s3r->sqlite3_value_int64)))
274 		goto onerror;
275 	if (! g_module_symbol (module, "sqlite3_value_double", (gpointer*) &(s3r->sqlite3_value_double)))
276 		goto onerror;
277 	if (! g_module_symbol (module, "sqlite3_value_text", (gpointer*) &(s3r->sqlite3_value_text)))
278 		goto onerror;
279 	if (! g_module_symbol (module, "sqlite3_value_type", (gpointer*) &(s3r->sqlite3_value_type)))
280 		goto onerror;
281 	if (! g_module_symbol (module, "sqlite3_key", (gpointer*) &(s3r->sqlite3_key)))
282 		s3r->sqlite3_key = NULL;
283 	if (! g_module_symbol (module, "sqlite3_rekey", (gpointer*) &(s3r->sqlite3_key)))
284 		s3r->sqlite3_rekey = NULL;
285 
286 	if (! g_module_symbol (module, "sqlite3_create_collation", (gpointer*) &(s3r->sqlite3_create_collation)))
287 		goto onerror;
288 	if (! g_module_symbol (module, "sqlite3_enable_load_extension", (gpointer*) &(s3r->sqlite3_enable_load_extension)))
289 		s3r->sqlite3_enable_load_extension = NULL;
290 	return;
291 
292  onerror:
293 	g_free (s3r);
294 	s3r = NULL;
295 	g_module_close (module);
296 }
297 
298