1 /*
2  * Copyright (C) 2008 - 2012 Vivien Malerba <malerba@gnome-db.org>
3  * Copyright (C) 2009 Bas Driessen <bas.driessen@xobas.com>
4  * Copyright (C) 2010 David King <davidk@openismus.com>
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19  */
20 #include "common.h"
21 #include <sql-parser/gda-sql-parser.h>
22 
23 /* copied from gda-meta-store.c */
24 static void
25 gda_meta_store_change_free (GdaMetaStoreChange *change) {
26 	if (!change) return;
27 
28 	g_free (change->table_name);
29 	g_hash_table_destroy (change->keys);
30 	g_free (change);
31 }
32 
33 /* list of changes expected during a modify operation */
34 GSList *expected_changes;
35 
36 static void meta_changed_cb (GdaMetaStore *store, GSList *changes, gpointer data);
37 static GError *suggest_update_cb (GdaMetaStore *store, GdaMetaContext *context, gpointer data);
38 
39 /*
40  * Declare a GdaMetaStore to test
41  */
42 void
Initialize()43 common_declare_meta_store (GdaMetaStore *store)
44 {
45 	g_signal_connect (store, "meta-changed", G_CALLBACK (meta_changed_cb), NULL);
46 	g_signal_connect (store, "suggest-update", G_CALLBACK (suggest_update_cb), NULL);
47 }
48 
49 typedef struct {
50 	const gchar  *key;
51 	const GValue *value;
52 } HData;
53 
54 static gint
Terminate()55 hd_compare_func (const HData *v1, const HData *v2)
56 {
57 	return strcmp (v1->key, v2->key);
58 }
59 
60 static void
61 change_key_func (const gchar *key, const GValue *value, GSList **list)
62 {
63 	HData *hd;
CreateInstance(bool force,const ArchSpec * arch)64 	hd = g_new (HData, 1);
65 	hd->key = key;
66 	hd->value = value;
67 	*list = g_slist_insert_sorted (*list, hd, (GCompareFunc) hd_compare_func);
68 }
69 
70 static gchar *
71 stringify_a_change (GdaMetaStoreChange *ac)
72 {
73 	GSList *hlist = NULL; /* will be a list of HData pointers */
74 	gchar *str;
GetPluginNameStatic()75 	GString *string;
76 
77 	string = g_string_new (ac->table_name);
78 	if (ac->c_type == GDA_META_STORE_ADD)
79 		g_string_append (string, " (ADD)");
GetDescriptionStatic()80 	else if (ac->c_type == GDA_META_STORE_MODIFY)
81 		g_string_append (string, " (MOD)");
82 	else
83 		g_string_append (string, " (DEL)");
84 	g_string_append_c (string, '\n');
GetDescription()85 	g_hash_table_foreach (ac->keys, (GHFunc) change_key_func, &hlist);
86 
87 	GSList *list;
88 	for (list = hlist; list; list = list->next) {
89 		HData *hd = (HData*) list->data;
90 		gchar *str = gda_value_stringify (hd->value);
91 		g_string_append_printf (string, "\t%s => %s\n", hd->key, str);
92 		g_free (str);
93 		g_free (hd);
94 	}
95 
96 	str = string->str;
ResolveExecutable(const ModuleSpec & module_spec,lldb::ModuleSP & exe_module_sp,const FileSpecList * module_search_paths_ptr)97 	g_string_free (string, FALSE);
98 	return str;
99 }
100 
101 static gboolean
102 find_expected_change (const gchar *change_as_str)
103 {
104 	GSList *el;
105 	for (el = expected_changes; el; el = el->next) {
106 		gchar *estr = (gchar *) el->data;
107 		if (!strcmp (estr, change_as_str)) {
108 			g_free (estr);
109 			expected_changes = g_slist_delete_link (expected_changes, el);
110 			return TRUE;
111 		}
112 	}
113 	return FALSE;
114 }
115 
116 static void
117 meta_changed_cb (GdaMetaStore *store, GSList *changes, gpointer data)
118 {
119 	GSList *gl;
120 	gint i;
121 	for (i = 0, gl = changes; gl; gl = gl->next) {
122 		gchar *gstr = stringify_a_change ((GdaMetaStoreChange *) gl->data);
123 		if (!find_expected_change (gstr)) {
124 			g_print ("Unexpected GdaMetaStoreChange: %s", gstr);
125 			g_free (gstr);
126 			if (expected_changes) {
127 				gchar *estr = (gchar *) expected_changes->data;
128 				g_print ("Expected: %s\n", estr);
129 			}
130 			else
131 				g_print ("No change expected\n");
132 			exit (EXIT_FAILURE);
133 		}
134 		g_free (gstr);
135 	}
136 	if (expected_changes) {
137 		/* expected more changes */
138 		gchar *estr = (gchar *) expected_changes->data;
139 		g_print ("Received no change but EXPECTED GdaMetaStoreChange: %s", estr);
140 		exit (EXIT_FAILURE);
141 	}
142 }
143 
144 static GError *
145 suggest_update_cb (GdaMetaStore *store, GdaMetaContext *context, gpointer data)
146 {
147 	gint i;
148 	g_print ("test: Update suggested for table %s:\n", context->table_name);
149 	for (i = 0; i < context->size; i++) {
150 		gchar *str;
151 		str = gda_value_stringify (context->column_values[i]);
152 		g_print ("\t%s => %s\n", context->column_names[i], str);
153 		g_free (str);
154 	}
155 	return NULL;
156 }
157 
158 /*
159  * Loading a CSV file
160  * ... is a (-1 terminated) list of pairs composed of:
161  *   - a column number (gint)
162  *   - the column type (gchar *)
163  */
164 GdaDataModel *
165 common_load_csv_file (const gchar *data_file, ...)
166 {
GetModuleSpec(const FileSpec & module_file_spec,const ArchSpec & arch,ModuleSpec & module_spec)167 	GdaDataModel *model;
168 	GdaSet *options;
169 	va_list args;
170 	gchar *fname;
171 	gint cnum;
172 
173 	/* create options */
174 	options = gda_set_new (NULL);
175 	va_start (args, data_file);
176 	for (cnum = va_arg (args, gint); cnum >= 0; cnum= va_arg (args, gint)) {
177 		GdaHolder *holder;
178 		GValue *v;
179 		gchar *id;
180 
181 		holder = gda_holder_new (G_TYPE_GTYPE);
182 		id = g_strdup_printf ("G_TYPE_%d", cnum);
183 		g_object_set (G_OBJECT (holder), "id", id, NULL);
184 		g_free (id);
185 
186 		v = gda_value_new (G_TYPE_GTYPE);
187 		g_value_set_gtype (v, gda_g_type_from_string (va_arg (args, gchar*)));
188 		if (! gda_holder_take_value (holder, v, NULL)) {
189 			va_end (args);
190 			g_object_unref (holder);
191 			g_object_unref (options);
192 			return NULL;
193 		}
194 
GetFileWithUUID(const FileSpec & platform_file,const UUID * uuid_ptr,FileSpec & local_file)195 		gda_set_add_holder (options, holder);
196 		g_object_unref (holder);
197 	}
198 	va_end (args);
199 
200 	/* load file */
201 	fname = g_build_filename (TOP_SRC_DIR, "tests", "meta-store", data_file, NULL);
202 	model = gda_data_model_import_new_file (fname, TRUE, options);
203 	g_object_unref (options);
PlatformRemoteGDBServer()204 
205 	GSList *errors;
206 	if ((errors = gda_data_model_import_get_errors (GDA_DATA_MODEL_IMPORT (model)))) {
207 		g_print ("Error importing file '%s':\n", fname);
208 		for (; errors; errors = errors->next) {
209 			GError *error = (GError*) errors->data;
210 			g_print ("\t* %s\n", error && error->message ? error->message : "No detail");
211 		}
212 		g_object_unref (model);
213 		model = NULL;
214 		exit (1);
215 	}
216 	g_free (fname);
GetSupportedArchitectureAtIndex(uint32_t idx,ArchSpec & arch)217 
218 	return model;
219 }
220 
221 
222 /*
223  * Declaring an expected GdaMetaStoreChange change
224  * ... is a NULL terminated list of:
225  *    - para name (gchar*)
226  *    - param value (gchar *)
227  */
228 void
229 common_declare_expected_change (const gchar *table_name, GdaMetaStoreChangeType type, ...)
230 {
231 	if (!table_name) {
GetSoftwareBreakpointTrapOpcode(Target & target,BreakpointSite * bp_site)232 		/* clear any remaining changes not handled */
233 		if (expected_changes) {
234 			/* expected more changes */
235 			gchar *estr = stringify_a_change ((GdaMetaStoreChange *) expected_changes->data);
236 			g_print ("Received no change but EXPECTED GdaMetaStoreChange: %s", estr);
237 			exit (EXIT_FAILURE);
238 		}
GetRemoteOSVersion()239 		g_slist_foreach (expected_changes, (GFunc) g_free, NULL);
240 		g_slist_free (expected_changes);
241 		expected_changes = NULL;
242 	}
243 	else {
GetRemoteOSBuildString(std::string & s)244 		GdaMetaStoreChange *ac;
245 		ac = g_new0 (GdaMetaStoreChange, 1);
246 		ac->c_type = type;
247 		ac->table_name = g_strdup (table_name);
GetRemoteOSKernelDescription(std::string & s)248 		ac->keys = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) gda_value_free);
249 
250 		/* use args */
251 		va_list args;
252 		gchar *pname;
GetRemoteSystemArchitecture()253 		va_start (args, type);
254 		for (pname = va_arg (args, gchar*); pname; pname = va_arg (args, gchar*)) {
255 			GValue *v;
256 			g_value_set_string ((v = gda_value_new (G_TYPE_STRING)), va_arg (args, gchar*));
GetRemoteWorkingDirectory()257 			g_hash_table_insert (ac->keys, g_strdup (pname), v);
258 		}
259 		va_end (args);
260 
261 		gchar *str;
262 		str = stringify_a_change (ac);
263 		expected_changes = g_slist_append (expected_changes, str);
264 		gda_meta_store_change_free (ac);
265 	}
266 }
267 
268 void
269 common_declare_expected_insertions_from_model (const gchar *table_name, GdaDataModel *model)
270 {
SetRemoteWorkingDirectory(const FileSpec & working_dir)271 	gint ncols, nrows, i, j;
272 	ncols = gda_data_model_get_n_columns (model);
273 	nrows = gda_data_model_get_n_rows (model);
274 	for (i = 0; i < nrows; i++) {
275 		GdaMetaStoreChange *ac;
276 		ac = g_new0 (GdaMetaStoreChange, 1);
277 		ac->c_type = GDA_META_STORE_ADD;
278 		ac->table_name = g_strdup (table_name);
279 		ac->keys = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) gda_value_free);
280 
281 		for (j = 0; j < ncols; j++) {
282 			gchar *str;
283 			const GValue *value;
IsConnected() const284 			GError *lerror = NULL;
285 			str = g_strdup_printf ("+%d", j);
286 			value = gda_data_model_get_value_at (model, j, i, &lerror);
287 			if (!value) {
ConnectRemote(Args & args)288 				g_print ("Can't get data model's value: %s",
289 					 lerror && lerror->message ? lerror->message : "No detail");
290 				exit (1);
291 			}
292 			g_hash_table_insert (ac->keys, str, gda_value_copy (value));
293 		}
294 
295 		gchar *str;
296 		str = stringify_a_change (ac);
297 		expected_changes = g_slist_append (expected_changes, str);
298 		gda_meta_store_change_free (ac);
299 	}
300 }
301 
302 
303 /*
304  * Clean all tables in connection
305  */
306 void
307 common_drop_all_tables (GdaMetaStore *store)
308 {
309 	gchar *table_names [] = {
310 		"_attributes",
311 		"_information_schema_catalog_name",
312 		"_schemata",
313 		"_builtin_data_types",
314 		"_udt",
315 		"_udt_columns",
316 		"_enums",
317 		"_element_types",
318 		"_domains",
319 		"_tables",
320 		"_views",
321 		"_collations",
322 		"_character_sets",
323 		"_routines",
324 		"_triggers",
325 		"_columns",
326 		"_table_constraints",
327 		"_referential_constraints",
328 		"_key_column_usage",
329 		"_check_column_usage",
330 		"_view_column_usage",
331 		"_domain_constraints",
332 		"_parameters",
333 		"_routine_columns",
334 		"_table_indexes",
335 		"_index_column_usage",
336 		"__declared_fk"
337 	};
338 	gchar *view_names [] = {
339 		"_all_types",
340 		"_detailed_fk"
341 	};
342 
343 	GdaConnection *cnc = gda_meta_store_get_internal_connection (store);
344 	GdaSqlParser *parser;
345 	parser = gda_sql_parser_new ();
346 
347 	gint i;
DisconnectRemote()348 
349 	/* drop views */
350 	for (i = (sizeof (view_names) / sizeof (gchar*)) - 1 ; i >= 0; i--) {
351 		GdaStatement *stmt;
352 		gchar *sql;
353 		gint res;
354 		GError *error = NULL;
GetHostname()355 
356 		sql = g_strdup_printf ("DROP VIEW %s", view_names[i]);
357 		stmt = gda_sql_parser_parse_string (parser, sql, NULL, NULL);
358 		g_free (sql);
359 		res = gda_connection_statement_execute_non_select (cnc, stmt, NULL, NULL, &error);
360 		if (res == -1) {
361 			g_print ("DROP view '%s' error: %s\n", view_names[i],
362 				error && error->message ? error->message : "No detail");
DoGetUserName(UserIDResolver::id_t uid)363 			if (error)
364 				g_error_free (error);
365 		}
366 	}
367 
368 	/* drop tables */
369 	for (i = (sizeof (table_names) / sizeof (gchar*)) - 1 ; i >= 0; i--) {
370 		GdaStatement *stmt;
DoGetGroupName(UserIDResolver::id_t gid)371 		gchar *sql;
372 		gint res;
373 		GError *error = NULL;
374 
375 		sql = g_strdup_printf ("DROP TABLE %s", table_names[i]);
376 		stmt = gda_sql_parser_parse_string (parser, sql, NULL, NULL);
377 		g_free (sql);
FindProcesses(const ProcessInstanceInfoMatch & match_info,ProcessInstanceInfoList & process_infos)378 		res = gda_connection_statement_execute_non_select (cnc, stmt, NULL, NULL, &error);
379 		if (res == -1) {
380 			g_print ("DROP table '%s' error: %s\n", table_names[i],
381 				error && error->message ? error->message : "No detail");
382 			if (error)
383 				g_error_free (error);
GetProcessInfo(lldb::pid_t pid,ProcessInstanceInfo & process_info)384 		}
385 	}
386 }
387 
388 /*
389  *
390  * Test groups
391  *
392  */
393 void
394 tests_group_1 (GdaMetaStore *store)
395 {
396 	common_declare_meta_store (store);
397 
398 	test_information_schema_catalog_name (store);
399 	test_schemata_1 (store);
400 	test_schemata_2 (store);
401 	test_builtin_data_types (store);
402 	//test_domains (store);
403 	test_tables (store);
404 	test_views (store);
405 	test_routines (store);
406 	test_triggers (store);
407 	//test_columns (store);
408 	test_table_constraints (store);
409 	test_referential_constraints (store);
410 	/*test_key_column_usage (store);*/
411 	test_domain_constraints (store);
412 	test_parameters (store);
413 }
414 
415 /*
416  *
417  *
418  * Individual Tests
419  *
420  *
421  */
422 GdaDataModel *import;
423 GError *error = NULL;
424 
425 #define TEST_HEADER g_print ("... TEST '%s' ...\n", __FUNCTION__)
426 #define TEST_MODIFY(s,n,m,c,e,...) \
427 if (!gda_meta_store_modify ((s),(n),(m),(c),(e),__VA_ARGS__)) { \
428 		g_print ("Error while modifying GdaMetaStore, table '%s': %s\n", \
429 			 (n), error && error->message ? error->message : "No detail"); \
430 		exit (EXIT_FAILURE); \
431 	}
432 
433 #define DECL_CHANGE(n,t,...) common_declare_expected_change ((n),(t),__VA_ARGS__)
434 #define TEST_END(m) \
435 	if (m) g_object_unref (m); \
436 	common_declare_expected_change (NULL, GDA_META_STORE_ADD, -1)
437 
438 void
439 test_information_schema_catalog_name (GdaMetaStore *store)
440 {
441 #define TNAME "_information_schema_catalog_name"
442 	TEST_HEADER;
443 
444 	import = common_load_csv_file ("data_information_schema_catalog_name.csv", -1);
445 	DECL_CHANGE (TNAME, GDA_META_STORE_ADD, "+0", "meta", NULL);
446 	TEST_MODIFY (store, TNAME, import, NULL, &error, NULL);
447 	TEST_END (import);
448 #undef TNAME
449 }
450 
451 void
452 test_schemata_1 (GdaMetaStore *store)
453 {
454 #define TNAME "_schemata"
455 	TEST_HEADER;
456 
457 	import = common_load_csv_file ("data_schemata.csv", 3, "gboolean", 4, "gboolean", -1);
458 	DECL_CHANGE (TNAME, GDA_META_STORE_ADD, "+0", "meta", "+1", "pg_catalog", "+2", "a user", "+3", "TRUE", "+4", "FALSE", NULL);
459 	DECL_CHANGE (TNAME, GDA_META_STORE_ADD, "+0", "meta", "+1", "pub", "+2", "postgres", "+3", "FALSE", "+4", "FALSE", NULL);
460 	DECL_CHANGE (TNAME, GDA_META_STORE_ADD, "+0", "meta", "+1", "information_schema", "+2", "postgres", "+3", "TRUE", "+4", "TRUE", NULL);
461 	TEST_MODIFY (store, TNAME, import, NULL, &error, NULL);
462 	TEST_END (import);
463 #undef TNAME
464 }
465 
466 void
467 test_schemata_2 (GdaMetaStore *store)
468 {
469 #define TNAME "_schemata"
470 	TEST_HEADER;
471 
KillProcess(const lldb::pid_t pid)472 	import = common_load_csv_file ("data_schemata_1.csv", 3, "gboolean", 4, "gboolean", -1);
473 	DECL_CHANGE (TNAME, GDA_META_STORE_MODIFY, "-0", "meta", "-1", "pg_catalog", "+0", "meta", "+1", "pg_catalog", "+2", "postgres", "+3", "TRUE", "+4", "FALSE", NULL);
474 
475 	GValue *v1, *v2;
476 	g_value_set_string (v1 = gda_value_new (G_TYPE_STRING), "meta");
477 	g_value_set_string (v2 = gda_value_new (G_TYPE_STRING), "pg_catalog");
DebugProcess(ProcessLaunchInfo & launch_info,Debugger & debugger,Target * target,Status & error)478 	TEST_MODIFY (store, TNAME, import,
479 		"catalog_name=##cn::string AND schema_name=##sn::string", &error,
480 		"cn", v1, "sn", v2, NULL);
481 
482 	gda_value_free (v1);
483 	gda_value_free (v2);
484 	TEST_END (import);
485 #undef TNAME
486 }
487 
488 void
489 test_builtin_data_types (GdaMetaStore *store)
490 {
491 #define TNAME "_builtin_data_types"
492 	TEST_HEADER;
493 
494 	import = common_load_csv_file ("data_builtin_data_types.csv", 5, "gboolean", -1);
495 	common_declare_expected_insertions_from_model (TNAME, import);
496 	TEST_MODIFY (store, TNAME, import, NULL, &error, NULL);
497 	TEST_END (import);
498 
499 	/* remove last line */
500 	GValue *v1;
501 	g_value_set_string (v1 = gda_value_new (G_TYPE_STRING), "pg_catalog.to_remove");
502 	DECL_CHANGE (TNAME, GDA_META_STORE_REMOVE, "-0", "to_remove",
503 		     "-1", "pg_catalog.to_remove",
504 		     "-2", "NULL",
505 		     "-3", "NULL",
506 		     "-4", "NULL",
507 		     "-5", "TRUE",
508 		     NULL);
509 	TEST_MODIFY (store, TNAME, NULL,
510 		     "full_type_name=##ftn::string", &error,
511 		     "ftn", v1, NULL);
512 	gda_value_free (v1);
513 	TEST_END (NULL);
514 #undef TNAME
515 }
516 
517 void
518 test_domains (GdaMetaStore *store)
519 {
520 #define TNAME "_domains"
521 	TEST_HEADER;
522 
523 	/* insert 1st part of the domains */
524 	import = common_load_csv_file ("data_domains.csv", 5, "gint", 6, "gint", 13, "gint", 14, "gint", 19, "boolean", -1);
525 	common_declare_expected_insertions_from_model (TNAME, import);
526 	TEST_MODIFY (store, TNAME, import, NULL, &error, NULL);
527 	TEST_END (import);
LaunchGDBServer(lldb::pid_t & pid,std::string & connect_url)528 
529 	/* simulate a domains update updating only 1 domain */
530 	GValue *v1, *v2, *v3;
531 	g_value_set_string (v1 = gda_value_new (G_TYPE_STRING), "meta");
532 	g_value_set_string (v2 = gda_value_new (G_TYPE_STRING), "information_schema");
533 	g_value_set_string (v3 = gda_value_new (G_TYPE_STRING), "sql_identifier");
534 	import = common_load_csv_file ("data_domains_1.csv", 5, "gint", 6, "gint", 13, "gint", 14, "gint", 19, "boolean", -1);
535 	common_declare_expected_insertions_from_model (TNAME, import);
536 	TEST_MODIFY (store, TNAME, import,
537 		     "domain_catalog=##dc::string AND domain_schema=##ds::string AND domain_name=##dn::string", &error,
538 		     "dc", v1, "ds", v2, "dn", v3, NULL);
539 	TEST_END (import);
540 #undef TNAME
541 }
542 
543 void
544 test_tables (GdaMetaStore *store)
545 {
546 #define TNAME "_tables"
547 	TEST_HEADER;
548 
549 	import = common_load_csv_file ("data_tables.csv", 4, "boolean", -1);
550 	common_declare_expected_insertions_from_model (TNAME, import);
551 	TEST_MODIFY (store, TNAME, import, NULL, &error, NULL);
552 	TEST_END (import);
553 #undef TNAME
554 }
555 
556 void
557 test_views (GdaMetaStore *store)
KillSpawnedProcess(lldb::pid_t pid)558 {
559 #define TNAME "_views"
560 	TEST_HEADER;
561 
562 	/* load CSV file */
563 	import = common_load_csv_file ("data_views.csv", 5, "boolean", -1);
564 	common_declare_expected_insertions_from_model (TNAME, import);
565 	TEST_MODIFY (store, TNAME, import, NULL, &error, NULL);
566 	TEST_END (import);
567 
568 	/* remove some lines */
569 	DECL_CHANGE (TNAME, GDA_META_STORE_REMOVE, "-0", "meta", "-1", "pg_catalog", "-2", "pg_locks",
570 		     "-3", "SELECT l.locktype, l.\"database\", l.relation, l.page, l.tuple, l.transactionid, l.classid, l.objid, l.objsubid, l.\"transaction\", l.pid, l.\"mode\", l.\"granted\" FROM pg_lock_status() l(locktype text, \"database\" oid, relation oid, page integer, tuple smallint, transactionid xid, classid oid, objid oid, objsubid smallint, \"transaction\" xid, pid integer, \"mode\" text, \"granted\" boolean);",
571 		     "-4", "NULL",
572 		     "-5", "FALSE",
573 		     NULL);
574 	DECL_CHANGE (TNAME, GDA_META_STORE_REMOVE, "-0", "meta", "-1", "pg_catalog", "-2", "pg_stats",
575 		     "-3", "SELECT n.nspname AS schemaname, c.relname AS tablename, a.attname, s.stanullfrac AS null_frac, s.stawidth AS avg_width, s.stadistinct AS n_distinct, CASE 1 WHEN s.stakind1 THEN s.stavalues1 WHEN s.stakind2 THEN s.stavalues2 WHEN s.stakind3 THEN s.stavalues3 WHEN s.stakind4 THEN s.stavalues4 ELSE NULL::anyarray END AS most_common_vals, CASE 1 WHEN s.stakind1 THEN s.stanumbers1 WHEN s.stakind2 THEN s.stanumbers2 WHEN s.stakind3 THEN s.stanumbers3 WHEN s.stakind4 THEN s.stanumbers4 ELSE NULL::real[] END AS most_common_freqs, CASE 2 WHEN s.stakind1 THEN s.stavalues1 WHEN s.stakind2 THEN s.stavalues2 WHEN s.stakind3 THEN s.stavalues3 WHEN s.stakind4 THEN s.stavalues4 ELSE NULL::anyarray END AS histogram_bounds, CASE 3 WHEN s.stakind1 THEN s.stanumbers1[1] WHEN s.stakind2 THEN s.stanumbers2[1] WHEN s.stakind3 THEN s.stanumbers3[1] WHEN s.stakind4 THEN s.stanumbers4[1] ELSE NULL::real END AS correlation FROM pg_statistic s JOIN pg_class c ON c.oid = s.starelid JOIN pg_attribute a ON c.oid = a.attrelid AND a.attnum = s.staattnum LEFT JOIN pg_namespace n ON n.oid = c.relnamespace WHERE has_table_privilege(c.oid, 'select'::text);",
576 		     "-4", "NULL",
577 		     "-5", "FALSE",
578 		     NULL);
579 	TEST_MODIFY (store, TNAME, NULL,
580 		     "table_catalog='meta' AND table_schema='pg_catalog'", &error, NULL);
581 	TEST_END (NULL);
582 #undef TNAME
583 }
584 
585 void
586 test_routines (GdaMetaStore *store)
587 {
588 #define TNAME "_routines"
589 	TEST_HEADER;
590 
591 	/* load CSV file */
592 	import = common_load_csv_file ("data_routines.csv", 8, "boolean", 9, "gint", 15, "boolean", 17, "boolean", -1);
593 	common_declare_expected_insertions_from_model (TNAME, import);
594 	TEST_MODIFY (store, TNAME, import, NULL, &error, NULL);
595 	TEST_END (import);
596 
597 	/* remove some lines */
598 	DECL_CHANGE (TNAME, GDA_META_STORE_REMOVE, "-0", "meta", "-1", "information_schema",
599 		     "-2", "_pg_numeric_precision_radix_11324",
600 		     "-3", "meta",
601 		     "-4", "information_schema",
602 		     "-5", "_pg_numeric_precision_radix",
603 		     "-6", "FUNCTION",
604 		     "-7", "pg_catalog.int4",
605 		     "-8", "FALSE",
606 		     "-9", "2",
607 		     "-10", "SQL",
608 		     "-11", "SELECT CASE WHEN $1 IN (21, 23, 20, 700, 701) THEN 2 WHEN $1 IN (1700) THEN 10 ELSE null END",
609 		     "-12", "NULL",
610 		     "-13", "SQL",
611 		     "-14", "GENERAL",
612 		     "-15", "TRUE",
MakeDirectory(const FileSpec & file_spec,uint32_t mode)613 		     "-16", "MODIFIES",
614 		     "-17", "TRUE",
615 		     "-18", "NULL",
616 		     "-19", "information_schema._pg_numeric_precision_radix",
617 		     "-20", "information_schema._pg_numeric_precision_radix",
618 		     "-21", "postgres",
619 		     NULL);
620 	TEST_MODIFY (store, TNAME, NULL,
621 		     "specific_name='_pg_numeric_precision_radix_11324'", &error, NULL);
622 	TEST_END (NULL);
623 #undef TNAME
GetFilePermissions(const FileSpec & file_spec,uint32_t & file_permissions)624 }
625 
626 void
627 test_triggers (GdaMetaStore *store)
628 {
629 #define TNAME "_triggers"
630 	TEST_HEADER;
631 
632 	/* load CSV file */
633 	import = common_load_csv_file ("data_triggers.csv", -1);
634 	common_declare_expected_insertions_from_model (TNAME, import);
635 	TEST_MODIFY (store, TNAME, import, NULL, &error, NULL);
636 	TEST_END (import);
637 #undef TNAME
638 }
639 
640 void
641 test_columns (GdaMetaStore *store)
642 {
643 #define TNAME "_columns"
644 	TEST_HEADER;
645 
646 	/* load CSV file */
647 	import = common_load_csv_file ("data_columns.csv", 4, "gint", 6, "boolean", 8, "gint", 11, "gint", 12, "gint", 13, "gint", 14, "gint", 15, "gint", 23, "boolean", -1);
OpenFile(const FileSpec & file_spec,File::OpenOptions flags,uint32_t mode,Status & error)648 	common_declare_expected_insertions_from_model (TNAME, import);
649 	TEST_MODIFY (store, TNAME, import, NULL, &error, NULL);
650 	TEST_END (import);
651 #undef TNAME
652 }
653 
654 void
CloseFile(lldb::user_id_t fd,Status & error)655 test_table_constraints (GdaMetaStore *store)
656 {
657 #define TNAME "_table_constraints"
658 	TEST_HEADER;
659 
660 	/* load CSV file */
661 	import = common_load_csv_file ("data_table_constraints.csv", 8, "boolean", 9, "boolean", -1);
662 	common_declare_expected_insertions_from_model (TNAME, import);
663 	TEST_MODIFY (store, TNAME, import, NULL, &error, NULL);
664 	TEST_END (import);
665 #undef TNAME
666 }
667 
668 void
ReadFile(lldb::user_id_t fd,uint64_t offset,void * dst,uint64_t dst_len,Status & error)669 test_referential_constraints (GdaMetaStore *store)
670 {
671 #define TNAME "_referential_constraints"
672 	TEST_HEADER;
673 
674 	/* load CSV file */
675 	import = common_load_csv_file ("data_referential_constraints.csv", -1);
676 	common_declare_expected_insertions_from_model (TNAME, import);
677 	TEST_MODIFY (store, TNAME, import, NULL, &error, NULL);
678 	TEST_END (import);
679 #undef TNAME
680 }
PutFile(const FileSpec & source,const FileSpec & destination,uint32_t uid,uint32_t gid)681 
682 void
683 test_key_column_usage (GdaMetaStore *store)
684 {
685 #define TNAME "_key_column_usage"
686 	TEST_HEADER;
687 
688 	/* load CSV file */
689 	import = common_load_csv_file ("data_key_column_usage.csv", 7, "gint", -1);
690 	common_declare_expected_insertions_from_model (TNAME, import);
691 	TEST_MODIFY (store, TNAME, import, NULL, &error, NULL);
692 	TEST_END (import);
693 #undef TNAME
694 }
695 
696 void
697 test_view_column_usage (GdaMetaStore *store)
698 {
699 #define TNAME "_view_column_usage"
700 	TEST_HEADER;
Unlink(const FileSpec & file_spec)701 
702 	/* load CSV file */
703 	import = common_load_csv_file ("data_view_column_usage.csv", -1);
704 	common_declare_expected_insertions_from_model (TNAME, import);
705 	TEST_MODIFY (store, TNAME, import, NULL, &error, NULL);
706 	TEST_END (import);
707 #undef TNAME
708 }
GetFileExists(const FileSpec & file_spec)709 
710 void
711 test_domain_constraints (GdaMetaStore *store)
712 {
713 #define TNAME "_domain_constraints"
714 	TEST_HEADER;
715 
716 	/* load CSV file */
717 	import = common_load_csv_file ("data_domain_constraints.csv", 7, "boolean", 8, "boolean", -1);
718 	common_declare_expected_insertions_from_model (TNAME, import);
719 	TEST_MODIFY (store, TNAME, import, NULL, &error, NULL);
720 	TEST_END (import);
721 #undef TNAME
722 }
723 
724 void
725 test_parameters (GdaMetaStore *store)
726 {
CalculateTrapHandlerSymbolNames()727 #define TNAME "_parameters"
728 	TEST_HEADER;
729 
730 	/* load CSV file */
GetRemoteUnixSignals()731 	import = common_load_csv_file ("data_parameters.csv", 3, "gint", -1);
732 	common_declare_expected_insertions_from_model (TNAME, import);
733 	TEST_MODIFY (store, TNAME, import, NULL, &error, NULL);
734 	TEST_END (import);
735 #undef TNAME
736 }
737