1 /*
2  * Copyright (C) 2007 - 2011 Murray Cumming <murrayc@murrayc.com>
3  * Copyright (C) 2007 - 2011 Vivien Malerba <malerba@gnome-db.org>
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program 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
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18  */
19 #include <stdlib.h>
20 #include <string.h>
21 #include <glib.h>
22 #include <libgda/libgda.h>
23 #include <stdarg.h>
24 #include "../test-errors.h"
25 
26 #define fail(x) g_warning (x)
27 #define fail_if(x,y) if (x) g_warning (y)
28 #define fail_unless(x,y) if (!(x)) g_warning (y)
29 
30 #define CHECK_EXTRA_INFO
31 /*#undef CHECK_EXTRA_INFO*/
32 static gboolean do_test_signal (void);
33 static gboolean do_test_common_read (GdaDataModel *proxy);
34 static gboolean do_test_read_direct_1 (void);
35 static gboolean do_test_read_direct_2 (void);
36 
37 static gboolean do_test_common_write (GdaDataModel *proxy);
38 static gboolean do_test_array (void);
39 
40 static gboolean do_test_prop_change (void);
41 static gboolean do_test_proxied_model_modif (void);
42 
43 static gboolean do_test_delete_rows (void);
44 
45 static gboolean do_test_modifs_persistance (void);
46 
47 /*
48  * the tests are all run with all the possible combinations of defer_sync (TRUE/FALSE) and
49  * prepend_null_row (TRUE/FALSE), so the ADJUST_ROW() macro allows for row adjustment
50  * when specifying expected results
51  */
52 gboolean defer_sync;
53 gboolean prepend_null_row;
54 #define ADJUST_ROW(x) (prepend_null_row ? (x)+1 : (x))
55 #define ADJUST_ROW_FOR_MODEL(model,x) (GDA_IS_DATA_PROXY(model)? (prepend_null_row ? (x)+1 : (x)) : (x))
56 
57 static void proxy_reset_cb (GdaDataModel *model, gchar *detail);
58 static void proxy_row_cb (GdaDataModel *model, gint row, gchar *detail);
59 static void declare_expected_signals (const gchar *expected, const gchar *name);
60 static void clean_expected_signals (GdaDataModel *model);
61 static void wait_for_signals (void);
62 static gboolean check_data_model_value (GdaDataModel *model, gint row, gint col, GType type, const gchar *value);
63 static gboolean check_data_model_n_rows (GdaDataModel *model, gint nrow);
64 static gboolean check_proxy_set_filter (GdaDataProxy *proxy, const gchar *filter);
65 static gboolean check_proxy_row_is_deleted (GdaDataProxy *proxy, gint row, gboolean is_deleted);
66 static gboolean check_data_model_append_row (GdaDataModel *model);
67 static gboolean check_data_model_set_values (GdaDataModel *model, gint row, GList *values);
68 static gboolean check_data_model_remove_row (GdaDataModel *model, gint row);
69 
70 static GList *make_values_list (gint dummy, ...);
71 static void free_values_list (GList *list);
72 
73 
74 int
75 main (int argc, char **argv)
76 {
77 	int number_failed = 0;
78 
79 	gda_init ();
80 
81 	prepend_null_row = FALSE;
82 	defer_sync = FALSE;
83 	if (!do_test_modifs_persistance ())
84 		number_failed ++;
85 
86 	defer_sync = TRUE;
87 	if (!do_test_modifs_persistance ())
88 		number_failed ++;
89 
90 	prepend_null_row = TRUE;
91  	defer_sync = FALSE;
92 	if (!do_test_modifs_persistance ())
93 		number_failed ++;
94 	defer_sync = TRUE;
95 	if (!do_test_modifs_persistance ())
96 		number_failed ++;
97 
98 	prepend_null_row = FALSE;
99 	defer_sync = FALSE;
100 	if (!do_test_delete_rows ())
101 		number_failed ++;
102 	defer_sync = TRUE;
103 	if (!do_test_delete_rows ())
104 		number_failed ++;
105 
106 	prepend_null_row = TRUE;
107  	defer_sync = FALSE;
108 	if (!do_test_delete_rows ())
109 		number_failed ++;
110 	defer_sync = TRUE;
111 	if (!do_test_delete_rows ())
112 		number_failed ++;
113 
114 	if (!do_test_signal ())
115 		number_failed ++;
116 
117 	prepend_null_row = FALSE;
118 	defer_sync = FALSE;
119 	if (!do_test_read_direct_1 ())
120 		number_failed ++;
121 	defer_sync = TRUE;
122 	if (!do_test_read_direct_1 ())
123 		number_failed ++;
124 
125 	defer_sync = FALSE;
126 	if (!do_test_read_direct_2 ())
127 		number_failed ++;
128 	defer_sync = TRUE;
129 	if (!do_test_read_direct_2 ())
130 		number_failed ++;
131 
132 	defer_sync = FALSE;
133 	if (!do_test_array ())
134 		number_failed ++;
135 
136 	defer_sync = TRUE;
137 	if (!do_test_array ())
138 		number_failed ++;
139 
140 	prepend_null_row = TRUE;
141 	defer_sync = FALSE;
142 	if (!do_test_read_direct_1 ())
143 		number_failed ++;
144 	defer_sync = TRUE;
145 	if (!do_test_read_direct_1 ())
146 		number_failed ++;
147 
148 	defer_sync = FALSE;
149 	if (!do_test_read_direct_2 ())
150 		number_failed ++;
151 	defer_sync = TRUE;
152 	if (!do_test_read_direct_2 ())
153 		number_failed ++;
154 
155 	defer_sync = FALSE;
156 	if (!do_test_array ())
157 		number_failed ++;
158 	defer_sync = TRUE;
159 	if (!do_test_array ())
160 		number_failed ++;
161 
162 	prepend_null_row = FALSE;
163 	defer_sync = FALSE;
164 	if (!do_test_prop_change ())
165 		number_failed ++;
166 	defer_sync = TRUE;
167 	if (!do_test_prop_change ())
168 		number_failed ++;
169 
170 	prepend_null_row = FALSE;
171 	defer_sync = FALSE;
172 	if (!do_test_proxied_model_modif ())
173 		number_failed ++;
174 	defer_sync = TRUE;
175 	if (!do_test_proxied_model_modif ())
176 		number_failed ++;
177 
178 	prepend_null_row = TRUE;
179 	defer_sync = FALSE;
180 	if (!do_test_proxied_model_modif ())
181 		number_failed ++;
182 	defer_sync = TRUE;
183 	if (!do_test_proxied_model_modif ())
184 		number_failed ++;
185 
186 	if (number_failed == 0)
187 		g_print ("Ok.\n");
188 	else
189 		g_print ("%d failed\n", number_failed);
190 	return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
191 }
192 
193 static GError *
194 validate_row_changes (GdaDataProxy *proxy, gint row, gint proxied_row, gchar *token)
195 {
196 	const GValue *cvalue;
197 	/* refuse if population < 100 */
198 
199 	cvalue = gda_data_model_get_value_at ((GdaDataModel*) proxy, 2, row, NULL);
200 	g_assert (cvalue);
201 	if (G_VALUE_TYPE (cvalue) == GDA_TYPE_NULL)
202 		return NULL;
203 	else {
204 		gint pop;
205 		pop = g_value_get_int (cvalue);
206 		if (pop < 100) {
207 			GError *error = NULL;
208 			g_set_error (&error, TEST_ERROR, TEST_ERROR_GENERIC,
209 				     "%s", "Population is too small");
210 			return error;
211 		}
212 		else
213 			return NULL;
214 	}
215 }
216 
217 static gboolean
218 do_test_signal (void)
219 {
220 #define FILE "city.csv"
221 	gchar *file;
222 	GdaDataModel *import, *proxy, *rw_model;
223 	GSList *errors;
224 	GdaSet *options;
225 	GValue *value;
226 	GError *lerror = NULL;
227 
228 	file = g_build_filename (CHECK_FILES, "tests", "data-models", FILE, NULL);
229 	options = gda_set_new_inline (2,
230 				      "TITLE_AS_FIRST_LINE", G_TYPE_BOOLEAN, TRUE,
231 				      "G_TYPE_2", G_TYPE_GTYPE, G_TYPE_INT);
232 	import = gda_data_model_import_new_file (file, TRUE, options);
233 	g_free (file);
234 	g_object_unref (options);
235 
236 	if ((errors = gda_data_model_import_get_errors (GDA_DATA_MODEL_IMPORT (import)))) {
237 #ifdef CHECK_EXTRA_INFO
238 		g_print ("ERROR: Could not load file '%s'\n", FILE);
239 #endif
240 		g_object_unref (import);
241 		return FALSE;
242 	}
243 
244 	rw_model = (GdaDataModel*) gda_data_model_array_copy_model (import, NULL);
245 	g_assert (rw_model);
246 	g_object_unref (import);
247 	proxy = g_object_new (GDA_TYPE_DATA_PROXY, "model", rw_model, "sample-size", 0, NULL);
248 	if (!proxy) {
249 #ifdef CHECK_EXTRA_INFO
250 		g_print ("ERROR: Could not create GdaDataProxy\n");
251 #endif
252 		return FALSE;
253 	}
254 
255 	g_signal_connect (G_OBJECT (proxy), "validate_row_changes",
256 			  G_CALLBACK (validate_row_changes), "Token");
257 
258 	/**/
259 	g_value_set_int ((value = gda_value_new (G_TYPE_INT)), 23);
260 	g_assert (gda_data_model_set_value_at (proxy, 2, 5, value, NULL));
261 	g_value_set_int (value, 100);
262 	g_assert (gda_data_model_set_value_at (proxy, 2, 3, value, NULL));
263 	gda_value_free (value);
264 
265 	if (gda_data_proxy_apply_all_changes (GDA_DATA_PROXY (proxy), &lerror)) {
266 #ifdef CHECK_EXTRA_INFO
267 		g_print ("ERROR: gda_data_proxy_apply_all_changes() should have failed\n");
268 #endif
269 		return FALSE;
270 	}
271 	if (!lerror) {
272 #ifdef CHECK_EXTRA_INFO
273 		g_print ("ERROR: returned error should not be NULL\n");
274 #endif
275 		return FALSE;
276 	}
277 	if (strcmp (lerror->message, "Population is too small")) {
278 #ifdef CHECK_EXTRA_INFO
279 		g_print ("ERROR: returned error message should be 'Population is too small', and got '%s'\n",
280 			 lerror->message);
281 #endif
282 		return FALSE;
283 	}
284 	g_error_free (lerror);
285 
286 	/**/
287 	g_assert (gda_data_proxy_cancel_all_changes (GDA_DATA_PROXY (proxy)));
288 	g_value_set_int ((value = gda_value_new (G_TYPE_INT)), 123);
289 	g_assert (gda_data_model_set_value_at (proxy, 2, 5, value, NULL));
290 	gda_value_free (value);
291 	if (!gda_data_proxy_apply_all_changes (GDA_DATA_PROXY (proxy), &lerror)) {
292 #ifdef CHECK_EXTRA_INFO
293 		g_print ("ERROR: gda_data_proxy_apply_all_changes() should not have failed, error: %s\n",
294 			 lerror && lerror->message ? lerror->message : "No detail");
295 #endif
296 		return FALSE;
297 	}
298 
299 	g_object_unref (proxy);
300 	g_object_unref (rw_model);
301 
302 	return TRUE;
303 }
304 
305 static gboolean
306 do_test_read_direct_1 ()
307 {
308 	#define FILE "city.csv"
309 	gchar *file;
310 	GdaDataModel *import, *proxy;
311 	GSList *errors;
312 	GdaSet *options;
313 
314 	file = g_build_filename (CHECK_FILES, "tests", "data-models", FILE, NULL);
315 	options = gda_set_new_inline (1, "TITLE_AS_FIRST_LINE", G_TYPE_BOOLEAN, TRUE);
316 	import = gda_data_model_import_new_file (file, TRUE, options);
317 	g_free (file);
318 	g_object_unref (options);
319 
320 	if ((errors = gda_data_model_import_get_errors (GDA_DATA_MODEL_IMPORT (import)))) {
321 #ifdef CHECK_EXTRA_INFO
322 		g_print ("ERROR: Could not load file '%s'\n", FILE);
323 #endif
324 		g_object_unref (import);
325 		return FALSE;
326 	}
327 
328 	proxy = g_object_new (GDA_TYPE_DATA_PROXY, "model", import, "sample-size", 0, NULL);
329 	g_object_unref (import);
330 	if (!proxy) {
331 #ifdef CHECK_EXTRA_INFO
332 		g_print ("ERROR: Could not create GdaDataProxy\n");
333 #endif
334 		return FALSE;
335 	}
336 	g_object_set (G_OBJECT (proxy), "defer-sync", FALSE, NULL);
337 	return do_test_common_read (proxy);
338 }
339 
340 static gboolean
341 do_test_read_direct_2 ()
342 {
343 	#define FILE "city.csv"
344 	gchar *file;
345 	GdaDataModel *import, *proxy;
346 	GSList *errors;
347 	GdaSet *options;
348 
349 	file = g_build_filename (CHECK_FILES, "tests", "data-models", FILE, NULL);
350 	options = gda_set_new_inline (1, "TITLE_AS_FIRST_LINE", G_TYPE_BOOLEAN, TRUE);
351 	import = gda_data_model_import_new_file (file, TRUE, options);
352 	g_free (file);
353 	g_object_unref (options);
354 
355 	if ((errors = gda_data_model_import_get_errors (GDA_DATA_MODEL_IMPORT (import)))) {
356 #ifdef CHECK_EXTRA_INFO
357 		g_print ("ERROR: Could not load file '%s'\n", FILE);
358 #endif
359 		g_object_unref (import);
360 		return FALSE;
361 	}
362 
363 	proxy = (GdaDataModel *) gda_data_proxy_new (import);
364 	g_object_unref (import);
365 	if (!proxy) {
366 #ifdef CHECK_EXTRA_INFO
367 		g_print ("ERROR: Could not create GdaDataProxy\n");
368 #endif
369 		return FALSE;
370 	}
371 	g_object_set (G_OBJECT (proxy), "defer-sync", FALSE, NULL);
372 	return do_test_common_read (proxy);
373 }
374 
375 static gboolean
376 do_test_array ()
377 {
378 	#define FILE "city.csv"
379 	GError *error;
380 	gchar *file;
381 	GdaDataModel *import, *model, *proxy;
382 	GSList *errors;
383 	GdaSet *options;
384 
385 	file = g_build_filename (CHECK_FILES, "tests", "data-models", FILE, NULL);
386 	options = gda_set_new_inline (1, "TITLE_AS_FIRST_LINE", G_TYPE_BOOLEAN, TRUE);
387 	import = gda_data_model_import_new_file (file, TRUE, options);
388 	g_free (file);
389 	g_object_unref (options);
390 
391 	if ((errors = gda_data_model_import_get_errors (GDA_DATA_MODEL_IMPORT (import)))) {
392 #ifdef CHECK_EXTRA_INFO
393 		g_print ("ERROR: Could not load file '%s'\n", FILE);
394 #endif
395 		g_object_unref (import);
396 		return FALSE;
397 	}
398 
399 	model = (GdaDataModel*) gda_data_model_array_copy_model (import, &error);
400 	if (!model) {
401 #ifdef CHECK_EXTRA_INFO
402 		g_print ("ERROR: Could not copy GdaDataModelImport into a GdaDataModelArray: %s\n",
403 			 error && error->message ? error->message : "No detail");
404 #endif
405 		g_error_free (error);
406 		return FALSE;
407 	}
408 	g_object_unref (import);
409 
410 	proxy = (GdaDataModel *) gda_data_proxy_new (model);
411 	g_object_unref (model);
412 	if (!proxy) {
413 #ifdef CHECK_EXTRA_INFO
414 		g_print ("ERROR: Could not create GdaDataProxy\n");
415 #endif
416 		return FALSE;
417 	}
418 	g_object_set (G_OBJECT (proxy), "defer-sync", FALSE, NULL);
419 	return do_test_common_write (proxy);
420 }
421 
422 static gboolean
423 do_test_prop_change (void)
424 {
425 #define FILE "city.csv"
426 	GError *error;
427 	gchar *file;
428 	GdaDataModel *import, *model, *proxy;
429 	GSList *errors;
430 	GdaSet *options;
431 
432 	file = g_build_filename (CHECK_FILES, "tests", "data-models", FILE, NULL);
433 	options = gda_set_new_inline (1, "TITLE_AS_FIRST_LINE", G_TYPE_BOOLEAN, TRUE);
434 	import = gda_data_model_import_new_file (file, TRUE, options);
435 	g_free (file);
436 	g_object_unref (options);
437 
438 	if ((errors = gda_data_model_import_get_errors (GDA_DATA_MODEL_IMPORT (import)))) {
439 #ifdef CHECK_EXTRA_INFO
440 		g_print ("ERROR: Could not load file '%s'\n", FILE);
441 #endif
442 		g_object_unref (import);
443 		return FALSE;
444 	}
445 
446 	model = (GdaDataModel*) gda_data_model_array_copy_model (import, &error);
447 	if (!model) {
448 #ifdef CHECK_EXTRA_INFO
449 		g_print ("ERROR: Could not copy GdaDataModelImport into a GdaDataModelArray: %s\n",
450 			 error && error->message ? error->message : "No detail");
451 #endif
452 		g_error_free (error);
453 		return FALSE;
454 	}
455 	g_object_unref (import);
456 
457 	proxy = (GdaDataModel *) gda_data_proxy_new (model);
458 	g_object_unref (model);
459 	if (!proxy) {
460 #ifdef CHECK_EXTRA_INFO
461 		g_print ("ERROR: Could not create GdaDataProxy\n");
462 #endif
463 		return FALSE;
464 	}
465 	g_object_set (G_OBJECT (proxy), "defer-sync", FALSE, NULL);
466 	gda_data_proxy_set_sample_size (GDA_DATA_PROXY (proxy), 0);
467 	g_object_set (G_OBJECT (proxy), "defer-sync", defer_sync, NULL);
468 
469 	gboolean retval = FALSE;
470 
471 	g_signal_connect (G_OBJECT (proxy), "reset",
472 			  G_CALLBACK (proxy_reset_cb), NULL);
473 	g_signal_connect (G_OBJECT (proxy), "row-inserted",
474 			  G_CALLBACK (proxy_row_cb), "I");
475 	g_signal_connect (G_OBJECT (proxy), "row-updated",
476 			  G_CALLBACK (proxy_row_cb), "U");
477 	g_signal_connect (G_OBJECT (proxy), "row-removed",
478 			  G_CALLBACK (proxy_row_cb), "R");
479 
480 	/*
481 	 * Set prepend-null-entry to TRUE
482 	 */
483 	declare_expected_signals ("I0", "Set prepend-null-entry to TRUE (no chunk)");
484 	g_object_set (G_OBJECT (proxy), "prepend-null-entry", TRUE, NULL);
485 	clean_expected_signals (proxy);
486 
487 	/*
488 	 * Set prepend-null-entry to FALSE
489 	 */
490 	declare_expected_signals ("R0", "Set prepend-null-entry to FALSE (no chunk)");
491 	g_object_set (G_OBJECT (proxy), "prepend-null-entry", FALSE, NULL);
492 	clean_expected_signals (proxy);
493 
494 	/*
495 	 * change sample size to 20
496 	 */
497 	declare_expected_signals ("138R20", "change sample size to 20");
498 	gda_data_proxy_set_sample_size (GDA_DATA_PROXY (proxy), 20);
499 	clean_expected_signals (proxy);
500 
501 	/*
502 	 * Set prepend-null-entry to TRUE
503 	 */
504 	declare_expected_signals ("I0", "Set prepend-null-entry to TRUE (with chunk)");
505 	g_object_set (G_OBJECT (proxy), "prepend-null-entry", TRUE, NULL);
506 	clean_expected_signals (proxy);
507 
508 	/*
509 	 * Set prepend-null-entry to FALSE
510 	 */
511 	declare_expected_signals ("R0", "Set prepend-null-entry to FALSE (with chunk)");
512 	g_object_set (G_OBJECT (proxy), "prepend-null-entry", FALSE, NULL);
513 	clean_expected_signals (proxy);
514 
515 	retval = TRUE;
516 	g_object_unref (proxy);
517 	return retval;
518 }
519 
520 static gboolean
521 do_test_proxied_model_modif (void)
522 {
523 #define FILE "city.csv"
524 	GError *error = NULL;
525 	gchar *file;
526 	GdaDataModel *import, *model, *proxy;
527 	GSList *errors;
528 	GdaSet *options;
529 
530 	file = g_build_filename (CHECK_FILES, "tests", "data-models", FILE, NULL);
531 	options = gda_set_new_inline (1, "TITLE_AS_FIRST_LINE", G_TYPE_BOOLEAN, TRUE);
532 	import = gda_data_model_import_new_file (file, TRUE, options);
533 	g_free (file);
534 	g_object_unref (options);
535 
536 	if ((errors = gda_data_model_import_get_errors (GDA_DATA_MODEL_IMPORT (import)))) {
537 #ifdef CHECK_EXTRA_INFO
538 		g_print ("ERROR: Could not load file '%s'\n", FILE);
539 #endif
540 		g_object_unref (import);
541 		return FALSE;
542 	}
543 
544 	model = (GdaDataModel*) gda_data_model_array_copy_model (import, &error);
545 	if (!model) {
546 #ifdef CHECK_EXTRA_INFO
547 		g_print ("ERROR: Could not copy GdaDataModelImport into a GdaDataModelArray: %s\n",
548 			 error && error->message ? error->message : "No detail");
549 #endif
550 		g_error_free (error);
551 		return FALSE;
552 	}
553 	g_object_unref (import);
554 
555 	proxy = (GdaDataModel *) gda_data_proxy_new (model);
556 	g_object_unref (model);
557 	if (!proxy) {
558 #ifdef CHECK_EXTRA_INFO
559 		g_print ("ERROR: Could not create GdaDataProxy\n");
560 #endif
561 		return FALSE;
562 	}
563 	g_object_set (G_OBJECT (proxy), "defer-sync", FALSE, NULL);
564 	gda_data_proxy_set_sample_size (GDA_DATA_PROXY (proxy), 0);
565 	g_object_set (G_OBJECT (proxy), "defer-sync", defer_sync,
566 		      "prepend-null-entry", prepend_null_row, NULL);
567 
568 	gboolean retval = FALSE;
569 
570 	g_signal_connect (G_OBJECT (proxy), "reset",
571 			  G_CALLBACK (proxy_reset_cb), NULL);
572 	g_signal_connect (G_OBJECT (proxy), "row-inserted",
573 			  G_CALLBACK (proxy_row_cb), "I");
574 	g_signal_connect (G_OBJECT (proxy), "row-updated",
575 			  G_CALLBACK (proxy_row_cb), "U");
576 	g_signal_connect (G_OBJECT (proxy), "row-removed",
577 			  G_CALLBACK (proxy_row_cb), "R");
578 
579 
580 	GValue *value;
581 	GList *values;
582 	/*
583 	 * update a row in proxied model
584 	 */
585 	declare_expected_signals ("U157", "update a row in proxied model - 1");
586 	g_value_set_string (value = gda_value_new (G_TYPE_STRING), "BigCity");
587 	if (!gda_data_model_set_value_at (model, 0, 157, value, &error)) {
588 #ifdef CHECK_EXTRA_INFO
589 		g_print ("ERROR: Failed to set value: %s\n", error && error->message ? error->message : "No detail");
590 #endif
591 		goto out;
592 	}
593 	clean_expected_signals (proxy);
594 	if (!check_data_model_value (proxy, 157, 0, G_TYPE_STRING, "BigCity")) goto out;
595 	if (!check_data_model_value (proxy, 157, 2, G_TYPE_STRING, "299801")) goto out;
596 	if (!check_data_model_value (proxy, 157, 3, G_TYPE_STRING, "BigCity")) goto out;
597 	if (!check_data_model_value (proxy, 157, 5, G_TYPE_STRING, "299801")) goto out;
598 
599 	/*
600 	 * insert a row in the proxied data model
601 	 */
602 	declare_expected_signals ("I158", "insert a row in proxied model - 1");
603 	if (! check_data_model_append_row (model)) goto out;
604 	clean_expected_signals (proxy);
605 	if (!check_data_model_n_rows (proxy, 159)) goto out;
606 
607 	values = make_values_list (0, G_TYPE_STRING, "BigCity2", G_TYPE_STRING, NULL, G_TYPE_STRING, "567890", (GType) 0);
608 	declare_expected_signals ("U158", "Set values of new proxied row - 1");
609 	if (!check_data_model_set_values (model, 158, values)) goto out;
610 	free_values_list (values);
611 	clean_expected_signals (proxy);
612 	if (!check_data_model_value (proxy, 158, 0, G_TYPE_STRING, "BigCity2")) goto out;
613 	if (!check_data_model_value (proxy, 158, 1, G_TYPE_STRING, NULL)) goto out;
614 	if (!check_data_model_value (proxy, 158, 2, G_TYPE_STRING, "567890")) goto out;
615 	if (!check_data_model_value (proxy, 158, 3, G_TYPE_STRING, "BigCity2")) goto out;
616 	if (!check_data_model_value (proxy, 158, 4, G_TYPE_STRING, NULL)) goto out;
617 	if (!check_data_model_value (proxy, 158, 5, G_TYPE_STRING, "567890")) goto out;
618 
619 	/*
620 	 * delete a proxy row
621 	 */
622 	gda_data_model_dump (proxy, stdout);
623 	declare_expected_signals ("R5", "Delete a proxy row - 1");
624 	if (!check_data_model_remove_row (model, 5)) goto out;
625 	clean_expected_signals (proxy);
626 	if (!check_data_model_n_rows (proxy, 158)) goto out;
627 	gda_data_model_dump (proxy, stdout);
628 
629 	/*
630 	 * Set sample size
631 	 */
632 	declare_expected_signals ("138R20", "change sample size to 20");
633 	gda_data_proxy_set_sample_size (GDA_DATA_PROXY (proxy), 20);
634 	clean_expected_signals (proxy);
635 	if (!check_data_model_n_rows (proxy, 20)) goto out;
636 
637 	/*
638 	 * update a row in proxied model
639 	 */
640 	declare_expected_signals ("U10", "update a row in proxied model - 2");
641 	g_value_set_string (value = gda_value_new (G_TYPE_STRING), "SmallCity");
642 	if (!gda_data_model_set_value_at (model, 0, 10, value, &error)) {
643 #ifdef CHECK_EXTRA_INFO
644 		g_print ("ERROR: Failed to set value: %s\n", error && error->message ? error->message : "No detail");
645 #endif
646 		goto out;
647 	}
648 	clean_expected_signals (proxy);
649 	if (!check_data_model_value (proxy, 10, 0, G_TYPE_STRING, "SmallCity")) goto out;
650 	if (!check_data_model_value (proxy, 10, 2, G_TYPE_STRING, "595")) goto out;
651 	if (!check_data_model_value (proxy, 10, 3, G_TYPE_STRING, "SmallCity")) goto out;
652 	if (!check_data_model_value (proxy, 10, 5, G_TYPE_STRING, "595")) goto out;
653 
654 	/*
655 	 * insert a row in the proxied data model, no signal is emited by @proxy
656 	 */
657 	declare_expected_signals (NULL, "insert a row in proxied model - 2");
658 	if (! check_data_model_append_row (model)) goto out;
659 	clean_expected_signals (proxy);
660 	if (!check_data_model_n_rows (proxy, 20)) goto out;
661 
662 	/*
663 	 * Set sample start
664 	 */
665 	declare_expected_signals ("20U0", "change sample start to 20");
666 	gda_data_proxy_set_sample_start (GDA_DATA_PROXY (proxy), 20);
667 	clean_expected_signals (proxy);
668 	if (!check_data_model_n_rows (proxy, 20)) goto out;
669 
670 	/*
671 	 * change new proxied's rows values
672 	 */
673 	values = make_values_list (0, G_TYPE_STRING, "SmallCity2", G_TYPE_STRING, NULL, G_TYPE_STRING, "4907", (GType) 0);
674 	declare_expected_signals ("U1", "Set values of new proxied row - 2");
675 	if (!check_data_model_set_values (model, 21, values)) goto out;
676 	free_values_list (values);
677 	clean_expected_signals (proxy);
678 	if (!check_data_model_value (proxy, 1, 0, G_TYPE_STRING, "SmallCity2")) goto out;
679 	if (!check_data_model_value (proxy, 1, 1, G_TYPE_STRING, "ARG")) goto out;
680 	if (!check_data_model_value (proxy, 1, 2, G_TYPE_STRING, "4907")) goto out;
681 	if (!check_data_model_value (proxy, 1, 3, G_TYPE_STRING, "SmallCity2")) goto out;
682 	if (!check_data_model_value (proxy, 1, 4, G_TYPE_STRING, "ARG")) goto out;
683 	if (!check_data_model_value (proxy, 1, 5, G_TYPE_STRING, "4907")) goto out;
684 
685 	/*
686 	 * delete a proxy row, not in current proxy's chunk
687 	 */
688 	gda_data_model_dump (proxy, stdout);
689 	declare_expected_signals (NULL, "Delete a proxy row - 2");
690 	if (!check_data_model_remove_row (model, 5)) goto out;
691 	clean_expected_signals (proxy);
692 	if (!check_data_model_n_rows (proxy, 20)) goto out;
693 	gda_data_model_dump (proxy, stdout);
694 
695 	/*
696 	 * delete a proxy row, in current proxy's chunk
697 	 */
698 	declare_expected_signals ("R6", "Delete a proxy row - 3");
699 	if (!check_data_model_remove_row (model, 25)) goto out;
700 	clean_expected_signals (proxy);
701 	gda_data_model_dump (proxy, stdout);
702 	if (!check_data_model_n_rows (proxy, 19)) goto out;
703 
704 	retval = TRUE;
705  out:
706 	g_object_unref (proxy);
707 	return retval;
708 }
709 
710 static gboolean
711 do_test_common_read (GdaDataModel *proxy)
712 {
713 	const gchar *filter;
714 	gboolean retval = FALSE;
715 
716 	gda_data_proxy_set_sample_size (GDA_DATA_PROXY (proxy), 10);
717 	g_object_set (G_OBJECT (proxy), "defer-sync", FALSE, NULL);
718 	g_object_set (G_OBJECT (proxy), "defer-sync", defer_sync,
719 		      "prepend-null-entry", prepend_null_row, NULL);
720 	g_signal_connect (G_OBJECT (proxy), "reset",
721 			  G_CALLBACK (proxy_reset_cb), NULL);
722 	g_signal_connect (G_OBJECT (proxy), "row-inserted",
723 			  G_CALLBACK (proxy_row_cb), "I");
724 	g_signal_connect (G_OBJECT (proxy), "row-updated",
725 			  G_CALLBACK (proxy_row_cb), "U");
726 	g_signal_connect (G_OBJECT (proxy), "row-removed",
727 			  G_CALLBACK (proxy_row_cb), "R");
728 
729 	/*
730 	 * try some filter with multiple statements, should not be accepted
731 	 */
732 	if (gda_data_proxy_set_filter_expr (GDA_DATA_PROXY (proxy), "countrycode = 'BFA'; SELECT * FROM proxy", NULL)) {
733 #ifdef CHECK_EXTRA_INFO
734 		g_print ("ERROR: Should not accept multi statement SQL filter!\n");
735 #endif
736 		g_object_unref (proxy);
737 		return FALSE;
738 	}
739 	filter = gda_data_proxy_get_filter_expr (GDA_DATA_PROXY (proxy));
740 	if (filter != NULL) {
741 #ifdef CHECK_EXTRA_INFO
742 		g_print ("ERROR: Filter should be NULL\n");
743 #endif
744 		g_object_unref (proxy);
745 		return FALSE;
746 	}
747 
748 	/*
749 	 * try a correct filter, and check for the signals
750 	 */
751 	declare_expected_signals ("3U0/7R3", "try a correct filter, and check for the signals");
752 	if (! check_proxy_set_filter (GDA_DATA_PROXY (proxy), "countrycode = 'BFA'")) goto out;
753 	clean_expected_signals (proxy);
754 
755 
756 	filter = gda_data_proxy_get_filter_expr (GDA_DATA_PROXY (proxy));
757 	if (!filter || strcmp (filter, "countrycode = 'BFA'")) {
758 #ifdef CHECK_EXTRA_INFO
759 		g_print ("ERROR: Filter should be '%s' and is '%s'\n", "countrycode = 'BFA'", filter);
760 #endif
761 		g_object_unref (proxy);
762 		return FALSE;
763 	}
764 
765 	/*
766 	 * try another correct filter, and check for the signals
767 	 */
768 	declare_expected_signals ("3U0/7I3", "try another correct filter, and check for the signals");
769 	if (! check_proxy_set_filter (GDA_DATA_PROXY (proxy), "countrycode = 'BGD'")) goto out;
770 	clean_expected_signals (proxy);
771 
772 	/*
773 	 * change sample start
774 	 */
775 	declare_expected_signals ("10U0", "change sample start to 2");
776 	gda_data_proxy_set_sample_start (GDA_DATA_PROXY (proxy), 2);
777 	clean_expected_signals (proxy);
778 
779 	/*
780 	 * change sample size to 13
781 	 */
782 	declare_expected_signals ("3I10", "change sample size to 13");
783 	gda_data_proxy_set_sample_size (GDA_DATA_PROXY (proxy), 13);
784 	clean_expected_signals (proxy);
785 
786 	/*
787 	 * change sample size to 0 => no chunking
788 	 */
789 	declare_expected_signals ("13U0/11I13", "change sample size to 0 => no chunking");
790 	gda_data_proxy_set_sample_size (GDA_DATA_PROXY (proxy), 0);
791 	clean_expected_signals (proxy);
792 
793 	/*
794 	 * change sample size to 7
795 	 */
796 	declare_expected_signals ("17R7", "change sample size to 7");
797 	gda_data_proxy_set_sample_size (GDA_DATA_PROXY (proxy), 7);
798 	clean_expected_signals (proxy);
799 
800 	/*
801 	 * change sample start to 22
802 	 */
803 	declare_expected_signals ("2U0/5R2", "change sample start to 22");
804 	gda_data_proxy_set_sample_start (GDA_DATA_PROXY (proxy), 22);
805 	clean_expected_signals (proxy);
806 
807 	/*
808 	 * remove filter
809 	 */
810 	declare_expected_signals ("2U0/5I2", "unset filter");
811 	if (! check_proxy_set_filter (GDA_DATA_PROXY (proxy), NULL)) goto out;
812 	clean_expected_signals (proxy);
813 
814 	/*
815 	 * last change sample size to 0 (no chunking and no filter)
816 	 */
817 	declare_expected_signals ("7U0/151I7", "last change sample size to 0 (no chunking and no filter)");
818 	gda_data_proxy_set_sample_size (GDA_DATA_PROXY (proxy), 0);
819 	clean_expected_signals (proxy);
820 
821 	retval = TRUE;
822  out:
823 	g_object_unref (proxy);
824 	return retval;
825 }
826 
827 static gboolean
828 do_test_common_write (GdaDataModel *proxy)
829 {
830 	GError *error = NULL;
831 	GValue *value;
832 	GList *values;
833 	gboolean retval = FALSE;
834 
835 	gda_data_proxy_set_sample_size (GDA_DATA_PROXY (proxy), 10);
836 	g_object_set (G_OBJECT (proxy), "defer-sync", defer_sync,
837 		      "prepend-null-entry", prepend_null_row, NULL);
838 
839 	g_signal_connect (G_OBJECT (proxy), "reset",
840 			  G_CALLBACK (proxy_reset_cb), NULL);
841 	g_signal_connect (G_OBJECT (proxy), "row-inserted",
842 			  G_CALLBACK (proxy_row_cb), "I");
843 	g_signal_connect (G_OBJECT (proxy), "row-updated",
844 			  G_CALLBACK (proxy_row_cb), "U");
845 	g_signal_connect (G_OBJECT (proxy), "row-removed",
846 			  G_CALLBACK (proxy_row_cb), "R");
847 
848 	/*
849 	 * change sample size to 0 (no chunking and no filter)
850 	 */
851 	declare_expected_signals ("148I10", "change sample size to 0 (no chunking and no filter)");
852 	gda_data_proxy_set_sample_size (GDA_DATA_PROXY (proxy), 0);
853 	clean_expected_signals (proxy);
854 
855 	/*
856 	 * append a row
857 	 */
858 	declare_expected_signals ("1I158", "Insert a row");
859 	if (! check_data_model_append_row (proxy)) goto out;
860 	clean_expected_signals (proxy);
861 	if (!check_data_model_value (proxy, 158, 0, G_TYPE_STRING, NULL)) goto out;
862 
863 	/*
864 	 * Set value of the new row
865 	 */
866 	declare_expected_signals ("U158", "Set value of new row");
867 	g_value_set_string (value = gda_value_new (G_TYPE_STRING), "MyCity");
868 	if (!gda_data_model_set_value_at (proxy, 0, ADJUST_ROW (158), value, &error)) {
869 #ifdef CHECK_EXTRA_INFO
870 		g_print ("ERROR: Failed to set value: %s\n", error && error->message ? error->message : "No detail");
871 #endif
872 		goto out;
873 	}
874 	clean_expected_signals (proxy);
875 	if (!check_data_model_value (proxy, 158, 0, G_TYPE_STRING, "MyCity")) goto out;
876 	if (!check_data_model_value (proxy, 158, 2, G_TYPE_STRING, NULL)) goto out;
877 
878 	declare_expected_signals ("U158", "Set value of new row");
879 	if (!gda_data_proxy_apply_row_changes (GDA_DATA_PROXY (proxy), ADJUST_ROW (158), &error)) {
880 #ifdef CHECK_EXTRA_INFO
881 		g_print ("ERROR: Failed to apply changes: %s\n", error && error->message ? error->message : "No detail");
882 #endif
883 		goto out;
884 	}
885 	clean_expected_signals (proxy);
886 	if (!check_data_model_value (proxy, 158, 0, G_TYPE_STRING, "MyCity")) goto out;
887 
888 	/*
889 	 * append another row
890 	 */
891 	declare_expected_signals ("I159", "Insert another row");
892 	if (! check_data_model_append_row (proxy)) goto out;
893 	clean_expected_signals (proxy);
894 	if (!check_data_model_value (proxy, 159, 0, G_TYPE_STRING, NULL)) goto out;
895 
896 	/*
897 	 * set several values for the new row
898 	 */
899 	values = make_values_list (0, G_TYPE_STRING, "MyCity2", G_TYPE_STRING, NULL, G_TYPE_STRING, "12345", (GType) 0);
900 	declare_expected_signals ("U159", "Set values of new row - new row");
901 	if (!check_data_model_set_values (proxy, 159, values)) goto out;
902 	free_values_list (values);
903 	clean_expected_signals (proxy);
904 	if (!check_data_model_value (proxy, 159, 0, G_TYPE_STRING, "MyCity2")) goto out;
905 	if (!check_data_model_value (proxy, 159, 1, G_TYPE_STRING, NULL)) goto out;
906 	if (!check_data_model_value (proxy, 159, 2, G_TYPE_STRING, "12345")) goto out;
907 	if (!check_data_model_value (proxy, 159, 3, G_TYPE_STRING, NULL)) goto out;
908 	if (!check_data_model_value (proxy, 159, 4, G_TYPE_STRING, NULL)) goto out;
909 	if (!check_data_model_value (proxy, 159, 5, G_TYPE_STRING, NULL)) goto out;
910 	if (!check_data_model_n_rows (proxy, 160)) goto out;
911 
912 	values = make_values_list (0, G_TYPE_STRING, "MyCity3", G_TYPE_STRING, "ZZZ", G_TYPE_STRING, "787", (GType) 0);
913 	declare_expected_signals ("U157", "Set values of new row - existing row");
914 	if (!check_data_model_set_values (proxy, 157, values)) goto out;
915 	free_values_list (values);
916 	clean_expected_signals (proxy);
917 
918 	if (!check_data_model_value (proxy, 157, 0, G_TYPE_STRING, "MyCity3")) goto out;
919 	if (!check_data_model_value (proxy, 157, 1, G_TYPE_STRING, "ZZZ")) goto out;
920 	if (!check_data_model_value (proxy, 157, 2, G_TYPE_STRING, "787")) goto out;
921 	if (!check_data_model_value (proxy, 157, 3, G_TYPE_STRING, "Varna")) goto out;
922 	if (!check_data_model_value (proxy, 157, 4, G_TYPE_STRING, "BGR")) goto out;
923 	if (!check_data_model_value (proxy, 157, 5, G_TYPE_STRING, "299801")) goto out;
924 
925 	/*
926 	 * Change sample size to 50
927 	 */
928 	declare_expected_signals ("U50/109R51", "change sample size to 50 (still no filter)");
929 	gda_data_proxy_set_sample_size (GDA_DATA_PROXY (proxy), 50);
930 	clean_expected_signals (proxy);
931 
932 	if (!check_data_model_value (proxy, 50, 0, G_TYPE_STRING, "MyCity2")) goto out;
933 	if (!check_data_model_value (proxy, 50, 1, G_TYPE_STRING, NULL)) goto out;
934 	if (!check_data_model_value (proxy, 50, 2, G_TYPE_STRING, "12345")) goto out;
935 	if (!check_data_model_value (proxy, 49, 3, G_TYPE_STRING, "Merlo")) goto out;
936 	if (!check_data_model_value (proxy, 49, 4, G_TYPE_STRING, "ARG")) goto out;
937 	if (!check_data_model_value (proxy, 49, 5, G_TYPE_STRING, "463846")) goto out;
938 	if (!check_data_model_n_rows (proxy, 51)) goto out;
939 
940 	/*
941 	 * Set filter
942 	 */
943 	declare_expected_signals ("3U0/48R3", "set filter to 'MyCity%'");
944 	if (! check_proxy_set_filter (GDA_DATA_PROXY (proxy), "name LIKE 'MyCity%' ORDER BY name")) goto out;
945 	clean_expected_signals (proxy);
946 
947 	if (!check_data_model_value (proxy, 0, 0, G_TYPE_STRING, "MyCity")) goto out;
948 	if (!check_data_model_value (proxy, 1, 0, G_TYPE_STRING, "MyCity2")) goto out;
949 	if (!check_data_model_value (proxy, 2, 0, G_TYPE_STRING, "MyCity3")) goto out;
950 	if (!check_data_model_n_rows (proxy, 3)) goto out;
951 
952 	/*
953 	 * Cancel changes to existing row
954 	 */
955 	declare_expected_signals ("U2", "Cancel changes of existing row");
956 	gda_data_proxy_cancel_row_changes (GDA_DATA_PROXY (proxy), ADJUST_ROW (2), -1);
957 	clean_expected_signals (proxy);
958 	if (!check_data_model_n_rows (proxy, 3)) goto out;
959 
960 	/*
961 	 * Cancel changes to row
962 	 */
963 	declare_expected_signals ("R1", "Cancel changes of new row");
964 	gda_data_proxy_cancel_row_changes (GDA_DATA_PROXY (proxy), ADJUST_ROW (1), -1);
965 	clean_expected_signals (proxy);
966 	if (!check_data_model_n_rows (proxy, 2)) goto out;
967 
968 	/*
969 	 * Unset filter
970 	 */
971 	declare_expected_signals ("2U0/48I2", "Unset filter");
972 	if (! check_proxy_set_filter (GDA_DATA_PROXY (proxy), NULL)) goto out;
973 	clean_expected_signals (proxy);
974 	if (!check_data_model_n_rows (proxy, 50)) goto out;
975 
976 	/*
977 	 * Delete an existing row
978 	 */
979 	declare_expected_signals ("U5", "Delete an existing row");
980 	if (!check_data_model_remove_row (proxy, 5)) goto out;
981 	clean_expected_signals (proxy);
982 	if (!check_proxy_row_is_deleted (GDA_DATA_PROXY (proxy), 5, TRUE)) goto out;
983 	if (!check_data_model_n_rows (proxy, 50)) goto out;
984 
985 	/*
986 	 * Undelete an existing row
987 	 */
988 	declare_expected_signals ("U5", "Undelete an existing row");
989 	gda_data_proxy_undelete (GDA_DATA_PROXY (proxy), ADJUST_ROW (5));
990 	clean_expected_signals (proxy);
991 	if (!check_proxy_row_is_deleted (GDA_DATA_PROXY (proxy), 5, FALSE)) goto out;
992 	if (!check_data_model_n_rows (proxy, 50)) goto out;
993 
994 	/*
995 	 * Add 4 new rows
996 	 */
997 	declare_expected_signals ("4I50", "Insert 4 rows");
998 	if (! check_data_model_append_row (proxy)) goto out;
999 	if (! check_data_model_append_row (proxy)) goto out;
1000 	if (! check_data_model_append_row (proxy)) goto out;
1001 	if (! check_data_model_append_row (proxy)) goto out;
1002 	clean_expected_signals (proxy);
1003 	if (!check_data_model_n_rows (proxy, 54)) goto out;
1004 
1005 	/*
1006 	 * Set values for those 3 new rows
1007 	 */
1008 	declare_expected_signals ("4U50", "Set values of 3 new rows");
1009 	values = make_values_list (0, G_TYPE_STRING, "NR1", G_TYPE_STRING, "AAA", G_TYPE_STRING, "319", (GType) 0);
1010 	if (!check_data_model_set_values (proxy, 50, values)) goto out;
1011 	free_values_list (values);
1012 	values = make_values_list (0, G_TYPE_STRING, "NR2", G_TYPE_STRING, "BBB", G_TYPE_STRING, "320", (GType) 0);
1013 	if (!check_data_model_set_values (proxy, 51, values)) goto out;
1014 	free_values_list (values);
1015 	values = make_values_list (0, G_TYPE_STRING, "NR3", G_TYPE_STRING, "CCC", G_TYPE_STRING, "321", (GType) 0);
1016 	if (!check_data_model_set_values (proxy, 52, values)) goto out;
1017 	free_values_list (values);
1018 	values = make_values_list (0, G_TYPE_STRING, "NR4", G_TYPE_STRING, "DDD", G_TYPE_STRING, "330", (GType) 0);
1019 	if (!check_data_model_set_values (proxy, 53, values)) goto out;
1020 	free_values_list (values);
1021 	clean_expected_signals (proxy);
1022 
1023 	if (!check_data_model_value (proxy, 50, 0, G_TYPE_STRING, "NR1")) goto out;
1024 	if (!check_data_model_value (proxy, 50, 1, G_TYPE_STRING, "AAA")) goto out;
1025 	if (!check_data_model_value (proxy, 50, 2, G_TYPE_STRING, "319")) goto out;
1026 	if (!check_data_model_value (proxy, 50, 3, G_TYPE_STRING, NULL)) goto out;
1027 	if (!check_data_model_value (proxy, 50, 4, G_TYPE_STRING, NULL)) goto out;
1028 	if (!check_data_model_value (proxy, 50, 5, G_TYPE_STRING, NULL)) goto out;
1029 	if (!check_data_model_value (proxy, 51, 0, G_TYPE_STRING, "NR2")) goto out;
1030 	if (!check_data_model_value (proxy, 51, 1, G_TYPE_STRING, "BBB")) goto out;
1031 	if (!check_data_model_value (proxy, 51, 2, G_TYPE_STRING, "320")) goto out;
1032 	if (!check_data_model_value (proxy, 52, 0, G_TYPE_STRING, "NR3")) goto out;
1033 	if (!check_data_model_value (proxy, 52, 1, G_TYPE_STRING, "CCC")) goto out;
1034 	if (!check_data_model_value (proxy, 52, 2, G_TYPE_STRING, "321")) goto out;
1035 	if (!check_data_model_value (proxy, 53, 0, G_TYPE_STRING, "NR4")) goto out;
1036 	if (!check_data_model_value (proxy, 53, 1, G_TYPE_STRING, "DDD")) goto out;
1037 	if (!check_data_model_value (proxy, 53, 2, G_TYPE_STRING, "330")) goto out;
1038 
1039 	/*
1040 	 * Remove 2nd row of the 4 new rows
1041 	 */
1042 	declare_expected_signals ("R51", "Remove 2nd row of the 4 new rows");
1043 	if (!check_data_model_remove_row (proxy, 51)) goto out;
1044 	if (!check_data_model_value (proxy, 50, 0, G_TYPE_STRING, "NR1")) goto out;
1045 	if (!check_data_model_value (proxy, 50, 1, G_TYPE_STRING, "AAA")) goto out;
1046 	if (!check_data_model_value (proxy, 50, 2, G_TYPE_STRING, "319")) goto out;
1047 	if (!check_data_model_value (proxy, 50, 3, G_TYPE_STRING, NULL)) goto out;
1048 	if (!check_data_model_value (proxy, 50, 4, G_TYPE_STRING, NULL)) goto out;
1049 	if (!check_data_model_value (proxy, 50, 5, G_TYPE_STRING, NULL)) goto out;
1050 	if (!check_data_model_value (proxy, 51, 0, G_TYPE_STRING, "NR3")) goto out;
1051 	if (!check_data_model_value (proxy, 51, 1, G_TYPE_STRING, "CCC")) goto out;
1052 	if (!check_data_model_value (proxy, 51, 2, G_TYPE_STRING, "321")) goto out;
1053 	if (!check_data_model_value (proxy, 51, 3, G_TYPE_STRING, NULL)) goto out;
1054 	if (!check_data_model_value (proxy, 51, 4, G_TYPE_STRING, NULL)) goto out;
1055 	if (!check_data_model_value (proxy, 51, 5, G_TYPE_STRING, NULL)) goto out;
1056 	if (!check_data_model_value (proxy, 52, 0, G_TYPE_STRING, "NR4")) goto out;
1057 	if (!check_data_model_value (proxy, 52, 1, G_TYPE_STRING, "DDD")) goto out;
1058 	if (!check_data_model_value (proxy, 52, 2, G_TYPE_STRING, "330")) goto out;
1059 	if (!check_data_model_value (proxy, 52, 3, G_TYPE_STRING, NULL)) goto out;
1060 	if (!check_data_model_value (proxy, 52, 4, G_TYPE_STRING, NULL)) goto out;
1061 	if (!check_data_model_value (proxy, 52, 5, G_TYPE_STRING, NULL)) goto out;
1062 	clean_expected_signals (proxy);
1063 	if (!check_data_model_n_rows (proxy, 53)) goto out;
1064 
1065 	/*
1066 	 * cancel changes for the 1st new row
1067 	 */
1068 	declare_expected_signals ("R50", "Cancel changes of new row");
1069 	gda_data_proxy_cancel_row_changes (GDA_DATA_PROXY (proxy), ADJUST_ROW (50), -1);
1070 	clean_expected_signals (proxy);
1071 	if (!check_data_model_n_rows (proxy, 52)) goto out;
1072 	if (!check_data_model_value (proxy, 50, 0, G_TYPE_STRING, "NR3")) goto out;
1073 	if (!check_data_model_value (proxy, 50, 1, G_TYPE_STRING, "CCC")) goto out;
1074 	if (!check_data_model_value (proxy, 50, 2, G_TYPE_STRING, "321")) goto out;
1075 	if (!check_data_model_value (proxy, 50, 3, G_TYPE_STRING, NULL)) goto out;
1076 	if (!check_data_model_value (proxy, 50, 4, G_TYPE_STRING, NULL)) goto out;
1077 	if (!check_data_model_value (proxy, 50, 5, G_TYPE_STRING, NULL)) goto out;
1078 	if (!check_data_model_value (proxy, 51, 0, G_TYPE_STRING, "NR4")) goto out;
1079 	if (!check_data_model_value (proxy, 51, 1, G_TYPE_STRING, "DDD")) goto out;
1080 	if (!check_data_model_value (proxy, 51, 2, G_TYPE_STRING, "330")) goto out;
1081 	if (!check_data_model_value (proxy, 51, 3, G_TYPE_STRING, NULL)) goto out;
1082 	if (!check_data_model_value (proxy, 51, 4, G_TYPE_STRING, NULL)) goto out;
1083 	if (!check_data_model_value (proxy, 51, 5, G_TYPE_STRING, NULL)) goto out;
1084 
1085 	/*
1086 	 * Clean changes
1087 	 */
1088 	declare_expected_signals ("2R50", "Cancel all changes");
1089 	gda_data_proxy_cancel_all_changes (GDA_DATA_PROXY (proxy));
1090 	clean_expected_signals (proxy);
1091 	if (!check_data_model_n_rows (proxy, 50)) goto out;
1092 
1093 	/*
1094 	 * Change sample size to 0
1095 	 */
1096 	declare_expected_signals ("109I50", "change sample size to 0");
1097 	gda_data_proxy_set_sample_size (GDA_DATA_PROXY (proxy), 0);
1098 	clean_expected_signals (proxy);
1099 
1100 	/*
1101 	 * Add 4 new rows
1102 	 */
1103 	declare_expected_signals ("4I159", "Insert 4 rows");
1104 	if (! check_data_model_append_row (proxy)) goto out;
1105 	if (! check_data_model_append_row (proxy)) goto out;
1106 	if (! check_data_model_append_row (proxy)) goto out;
1107 	if (! check_data_model_append_row (proxy)) goto out;
1108 	clean_expected_signals (proxy);
1109 	if (!check_data_model_n_rows (proxy, 163)) goto out;
1110 
1111 	/*
1112 	 * Set values for those 4 new rows
1113 	 */
1114 	declare_expected_signals ("4U159", "Set values of 4 new rows");
1115 	values = make_values_list (0, G_TYPE_STRING, "NR1", G_TYPE_STRING, "AAA", G_TYPE_STRING, "319", (GType) 0);
1116 	if (!check_data_model_set_values (proxy, 159, values)) goto out;
1117 	free_values_list (values);
1118 	values = make_values_list (0, G_TYPE_STRING, "NR2", G_TYPE_STRING, "BBB", G_TYPE_STRING, "320", (GType) 0);
1119 	if (!check_data_model_set_values (proxy, 160, values)) goto out;
1120 	free_values_list (values);
1121 	values = make_values_list (0, G_TYPE_STRING, "NR3", G_TYPE_STRING, "CCC", G_TYPE_STRING, "321", (GType) 0);
1122 	if (!check_data_model_set_values (proxy, 161, values)) goto out;
1123 	free_values_list (values);
1124 	values = make_values_list (0, G_TYPE_STRING, "NR4", G_TYPE_STRING, "DDD", G_TYPE_STRING, "330", (GType) 0);
1125 	if (!check_data_model_set_values (proxy, 162, values)) goto out;
1126 	free_values_list (values);
1127 	clean_expected_signals (proxy);
1128 
1129 	if (!check_data_model_value (proxy, 159, 0, G_TYPE_STRING, "NR1")) goto out;
1130 	if (!check_data_model_value (proxy, 159, 1, G_TYPE_STRING, "AAA")) goto out;
1131 	if (!check_data_model_value (proxy, 159, 2, G_TYPE_STRING, "319")) goto out;
1132 	if (!check_data_model_value (proxy, 159, 3, G_TYPE_STRING, NULL)) goto out;
1133 	if (!check_data_model_value (proxy, 159, 4, G_TYPE_STRING, NULL)) goto out;
1134 	if (!check_data_model_value (proxy, 159, 5, G_TYPE_STRING, NULL)) goto out;
1135 	if (!check_data_model_value (proxy, 160, 0, G_TYPE_STRING, "NR2")) goto out;
1136 	if (!check_data_model_value (proxy, 160, 1, G_TYPE_STRING, "BBB")) goto out;
1137 	if (!check_data_model_value (proxy, 160, 2, G_TYPE_STRING, "320")) goto out;
1138 	if (!check_data_model_value (proxy, 161, 0, G_TYPE_STRING, "NR3")) goto out;
1139 	if (!check_data_model_value (proxy, 161, 1, G_TYPE_STRING, "CCC")) goto out;
1140 	if (!check_data_model_value (proxy, 161, 2, G_TYPE_STRING, "321")) goto out;
1141 	if (!check_data_model_value (proxy, 162, 0, G_TYPE_STRING, "NR4")) goto out;
1142 	if (!check_data_model_value (proxy, 162, 1, G_TYPE_STRING, "DDD")) goto out;
1143 	if (!check_data_model_value (proxy, 162, 2, G_TYPE_STRING, "330")) goto out;
1144 
1145 	/*
1146 	 * Remove 2nd row of the 4 new rows
1147 	 */
1148 	declare_expected_signals ("R160", "Remove 2nd row of the 4 new rows");
1149 	if (!check_data_model_remove_row (proxy, 160)) goto out;
1150 	if (!check_data_model_value (proxy, 159, 0, G_TYPE_STRING, "NR1")) goto out;
1151 	if (!check_data_model_value (proxy, 159, 1, G_TYPE_STRING, "AAA")) goto out;
1152 	if (!check_data_model_value (proxy, 159, 2, G_TYPE_STRING, "319")) goto out;
1153 	if (!check_data_model_value (proxy, 159, 3, G_TYPE_STRING, NULL)) goto out;
1154 	if (!check_data_model_value (proxy, 159, 4, G_TYPE_STRING, NULL)) goto out;
1155 	if (!check_data_model_value (proxy, 159, 5, G_TYPE_STRING, NULL)) goto out;
1156 	if (!check_data_model_value (proxy, 160, 0, G_TYPE_STRING, "NR3")) goto out;
1157 	if (!check_data_model_value (proxy, 160, 1, G_TYPE_STRING, "CCC")) goto out;
1158 	if (!check_data_model_value (proxy, 160, 2, G_TYPE_STRING, "321")) goto out;
1159 	if (!check_data_model_value (proxy, 160, 3, G_TYPE_STRING, NULL)) goto out;
1160 	if (!check_data_model_value (proxy, 160, 4, G_TYPE_STRING, NULL)) goto out;
1161 	if (!check_data_model_value (proxy, 160, 5, G_TYPE_STRING, NULL)) goto out;
1162 	if (!check_data_model_value (proxy, 161, 0, G_TYPE_STRING, "NR4")) goto out;
1163 	if (!check_data_model_value (proxy, 161, 1, G_TYPE_STRING, "DDD")) goto out;
1164 	if (!check_data_model_value (proxy, 161, 2, G_TYPE_STRING, "330")) goto out;
1165 	if (!check_data_model_value (proxy, 161, 3, G_TYPE_STRING, NULL)) goto out;
1166 	if (!check_data_model_value (proxy, 161, 4, G_TYPE_STRING, NULL)) goto out;
1167 	if (!check_data_model_value (proxy, 161, 5, G_TYPE_STRING, NULL)) goto out;
1168 	clean_expected_signals (proxy);
1169 	if (!check_data_model_n_rows (proxy, 162)) goto out;
1170 
1171 	/*
1172 	 * cancel changes for the 1st new row
1173 	 */
1174 	declare_expected_signals ("R159", "Cancel changes of new row");
1175 	gda_data_proxy_cancel_row_changes (GDA_DATA_PROXY (proxy), ADJUST_ROW (159), -1);
1176 	clean_expected_signals (proxy);
1177 	if (!check_data_model_n_rows (proxy, 161)) goto out;
1178 	if (!check_data_model_value (proxy, 159, 0, G_TYPE_STRING, "NR3")) goto out;
1179 	if (!check_data_model_value (proxy, 159, 1, G_TYPE_STRING, "CCC")) goto out;
1180 	if (!check_data_model_value (proxy, 159, 2, G_TYPE_STRING, "321")) goto out;
1181 	if (!check_data_model_value (proxy, 159, 3, G_TYPE_STRING, NULL)) goto out;
1182 	if (!check_data_model_value (proxy, 159, 4, G_TYPE_STRING, NULL)) goto out;
1183 	if (!check_data_model_value (proxy, 159, 5, G_TYPE_STRING, NULL)) goto out;
1184 	if (!check_data_model_value (proxy, 160, 0, G_TYPE_STRING, "NR4")) goto out;
1185 	if (!check_data_model_value (proxy, 160, 1, G_TYPE_STRING, "DDD")) goto out;
1186 	if (!check_data_model_value (proxy, 160, 2, G_TYPE_STRING, "330")) goto out;
1187 	if (!check_data_model_value (proxy, 160, 3, G_TYPE_STRING, NULL)) goto out;
1188 	if (!check_data_model_value (proxy, 160, 4, G_TYPE_STRING, NULL)) goto out;
1189 	if (!check_data_model_value (proxy, 160, 5, G_TYPE_STRING, NULL)) goto out;
1190 
1191 	/*
1192 	 * Clean changes
1193 	 */
1194 	declare_expected_signals ("R160/R159", "Cancel all changes");
1195 	gda_data_proxy_cancel_all_changes (GDA_DATA_PROXY (proxy));
1196 	clean_expected_signals (proxy);
1197 	if (!check_data_model_n_rows (proxy, 159)) goto out;
1198 
1199 	/*
1200 	 * Test specific if a NULL row is prepended
1201 	 */
1202 	if (prepend_null_row) {
1203 		/*
1204 		 * Try to remove first row
1205 		 */
1206 		if (gda_data_model_remove_row (proxy, 0, NULL)) {
1207 #ifdef CHECK_EXTRA_INFO
1208 			g_print ("ERROR: Should not be able to remove row 0 (as it is the prepended row)\n");
1209 #endif
1210 			goto out;
1211 		}
1212 
1213 		/*
1214 		 * Try to alter first row
1215 		 */
1216 		values = make_values_list (0, G_TYPE_STRING, "MyCity3", G_TYPE_STRING, "ZZZ", G_TYPE_STRING, "787", (GType) 0);
1217 		if (gda_data_model_set_values (proxy, 0, values, NULL)) {
1218 #ifdef CHECK_EXTRA_INFO
1219 			g_print ("ERROR: Should not be able to alter row 0 (as it is the prepended row)\n");
1220 #endif
1221 			free_values_list (values);
1222 			goto out;
1223 		}
1224 		free_values_list (values);
1225 	}
1226 
1227 
1228 	/* end */
1229 	retval = TRUE;
1230  out:
1231 	g_object_unref (proxy);
1232 	return retval;
1233 }
1234 
1235 /*
1236  * list of (GType, value as string) pairs ended with a 0 (for type)
1237  */
1238 static GList *
1239 make_values_list (gint dummy, ...)
1240 {
1241 	GList *list = NULL;
1242 	va_list ap;
1243 
1244 	gchar *str;
1245 	GType type;
1246 
1247 	va_start (ap, dummy);
1248 	for (type = va_arg (ap, GType); type != 0; type = va_arg (ap, GType)) {
1249 		GValue *value;
1250 		str = va_arg (ap, gchar *);
1251 		if (str) {
1252 			value = gda_value_new (type);
1253 			g_assert (gda_value_set_from_string (value, str, type));
1254 		}
1255 		else
1256 			value = NULL;
1257 		list = g_list_append (list, value);
1258 	}
1259 	va_end (ap);
1260 	return list;
1261 }
1262 
1263 static void
1264 free_values_list (GList *list)
1265 {
1266 	GList *l;
1267 	for (l = list; l; l = l->next)
1268 		if (l->data)
1269 			gda_value_free ((GValue *) l->data);
1270 	g_list_free (list);
1271 }
1272 
1273 
1274 /*
1275  *
1276  * Signals test implementation
1277  *
1278  */
1279 
1280 typedef struct {
1281 	gchar sig;
1282 	gint  row;
1283 } ASignal;
1284 
1285 GArray      *expected_signals;
1286 const gchar *expected_signals_name;
1287 guint         expected_signals_index;
1288 
1289 /* Format is "<nb><type><row_nb>[/...]"
1290  * for example:
1291  *   - 1U123 means 1 update of row 123
1292  *   - 2U123 means 2 updates, 1 for row 123 and 1 for row 124
1293  *   - 2I4 means 2 inserts, 1 for row 4 and 1 for row 5
1294  *   - 2R6 means 2 deletes, all for row 6
1295  *
1296  * Use lower case to avoid taking into account the prepend_null_row variable
1297  */
1298 static void
1299 declare_expected_signals (const gchar *expected, const gchar *name)
1300 {
1301 #ifdef CHECK_EXTRA_INFO
1302 	g_print (">>> NEW_TEST: %s (defer_sync=%s, prepend_null_row=%s)\n", name,
1303 		 defer_sync ? "TRUE" : "FALSE", prepend_null_row ? "TRUE" : "FALSE");
1304 #endif
1305 	expected_signals_name = name;
1306 	if (!expected)
1307 		return;
1308 
1309 	expected_signals = g_array_new (FALSE, TRUE, sizeof (ASignal));
1310 	const gchar *ptr;
1311 	for (ptr = expected; *ptr;) {
1312 		gint i, nb = 1, row = -1;
1313 		gchar type;
1314 		if ((*ptr <= '9') && (*ptr >= '0')) {
1315 			nb = atoi (ptr);
1316 			for (; *ptr; ptr++)
1317 				if ((*ptr > '9') || (*ptr < '0'))
1318 					break;
1319 		}
1320 		type = *ptr;
1321 		ptr++;
1322 		if ((*ptr <= '9') && (*ptr >= '0')) {
1323 			row = atoi (ptr);
1324 			for (; *ptr; ptr++)
1325 				if ((*ptr > '9') || (*ptr < '0'))
1326 					break;
1327 		}
1328 		if (*ptr == '/')
1329 			ptr++;
1330 		for (i = 0; i < nb; i++) {
1331 			gint sigrow;
1332 			gboolean use_prepend_null_row = TRUE;
1333 			if (type >= 'a') {
1334 				type += 'A' - 'a';
1335 				use_prepend_null_row = FALSE;
1336 			}
1337 			switch (type) {
1338 			case 'U':
1339 			case 'I':
1340 				sigrow = row + i;
1341 				break;
1342 			case 'R':
1343 				sigrow = row;
1344 				break;
1345 			default:
1346 				g_assert_not_reached ();
1347 			}
1348 
1349 			ASignal sig;
1350 			sig.sig = type;
1351 			if (use_prepend_null_row)
1352 				sig.row = ADJUST_ROW (sigrow);
1353 			else
1354 				sig.row = sigrow;
1355 			g_array_append_val (expected_signals, sig);
1356 		}
1357 	}
1358 
1359 	expected_signals_index = 0;
1360 }
1361 
1362 static void
1363 clean_expected_signals (GdaDataModel *model)
1364 {
1365 	if (!expected_signals)
1366 		return;
1367 	wait_for_signals ();
1368 	if (expected_signals_index != expected_signals->len) {
1369 #ifdef CHECK_EXTRA_INFO
1370 		g_print ("ERROR: There are some non received signals:\n");
1371 		for (; expected_signals_index < expected_signals->len; expected_signals_index++) {
1372 			ASignal sig = g_array_index (expected_signals, ASignal, expected_signals_index);
1373 			g_print ("\t%c for row %d\n", sig.sig, sig.row);
1374 		}
1375 #endif
1376 		exit (1);
1377 	}
1378 	g_array_free (expected_signals, TRUE);
1379 	expected_signals = NULL;
1380 
1381 	if (prepend_null_row) {
1382 		gint col, ncols;
1383 		/* check that row 0 is all NULL */
1384 		if (gda_data_model_get_n_rows (model) <= 0) {
1385 #ifdef CHECK_EXTRA_INFO
1386 			g_print ("ERROR: As the \"prepend-null-entry\" property is set, there should always be a first "
1387 				 "all-NULL entry\n");
1388 #endif
1389 			exit (1);
1390 		}
1391 		ncols = gda_data_model_get_n_columns (model);
1392 		for (col = 0; col < ncols; col++) {
1393 			GError *lerror = NULL;
1394 			const GValue *value = gda_data_model_get_value_at (model, col, 0, &lerror);
1395 			if (!value) {
1396 #ifdef CHECK_EXTRA_INFO
1397 				g_print ("Can't get data model's value: %s\n",
1398 					 lerror && lerror->message ? lerror->message : "No detail");
1399 #endif
1400 				exit (1);
1401 			}
1402 			else if (! gda_value_is_null (value)) {
1403 #ifdef CHECK_EXTRA_INFO
1404 				g_print ("ERROR: As the \"prepend-null-entry\" property is set, there should always be a first "
1405 					 "all-NULL entry, got '%s' at column %d\n", gda_value_stringify (value), col);
1406 #endif
1407 				exit (1);
1408 			}
1409 		}
1410 	}
1411 #ifdef CHECK_EXTRA_INFO
1412 	g_print (">>> END OF TEST %s\n", expected_signals_name);
1413 #endif
1414 }
1415 
1416 static gboolean
1417 wait_timeout (GMainLoop *loop)
1418 {
1419         g_main_loop_quit (loop);
1420 #ifdef CHECK_EXTRA_INFO
1421 	g_print ("End of wait.\n");
1422 #endif
1423         return FALSE; /* remove the time out */
1424 }
1425 
1426 static void
1427 wait_for_signals (void)
1428 {
1429 	GMainLoop *loop;
1430 	guint ms;
1431 	if (!defer_sync)
1432 		return;
1433 
1434 	ms = ((expected_signals->len / 5)+1) * 75; /* nice heuristic, heu? */
1435 	loop = g_main_loop_new (NULL, FALSE);
1436 #ifdef CHECK_EXTRA_INFO
1437 	g_print ("Waiting %d ms...\n", ms);
1438 #endif
1439 	g_timeout_add (ms, (GSourceFunc) wait_timeout, loop);
1440 	g_main_loop_run (loop);
1441 	g_main_loop_unref (loop);
1442 }
1443 
1444 static void
1445 proxy_reset_cb (GdaDataModel *model, gchar *detail)
1446 {
1447 #ifdef CHECK_EXTRA_INFO
1448 	g_print ("RESET\n");
1449 #endif
1450 }
1451 
1452 static void
1453 proxy_row_cb (GdaDataModel *model, gint row, gchar *detail)
1454 {
1455 	gchar *str;
1456 
1457 	switch (*detail) {
1458 		case 'I':
1459 			str = g_strdup_printf ("row %d inserted", row);
1460 			break;
1461 		case 'U':
1462 			str = g_strdup_printf ("row %d updated", row);
1463 			break;
1464 		case 'R':
1465 			str = g_strdup_printf ("row %d removed", row);
1466 			break;
1467 		default:
1468 			g_assert_not_reached ();
1469 	}
1470 
1471 	if (expected_signals) {
1472 		if (expected_signals_index < expected_signals->len) {
1473 			ASignal sig = g_array_index (expected_signals, ASignal, expected_signals_index);
1474 			if (sig.sig != *detail) {
1475 #ifdef CHECK_EXTRA_INFO
1476 				g_print ("ERROR: %s: Expected signal %c for row %d, received %s (step %d)\n", expected_signals_name,
1477 					 sig.sig, sig.row, str, expected_signals_index);
1478 #endif
1479 				exit (1);
1480 			}
1481 			if (sig.row != row) {
1482 #ifdef CHECK_EXTRA_INFO
1483 				g_print ("ERROR: %s: Expected signal for row %d, received %s (step %d)\n", expected_signals_name,
1484 					 sig.row, str, expected_signals_index);
1485 #endif
1486 				exit (1);
1487 			}
1488 			expected_signals_index ++;
1489 		}
1490 		else {
1491 #ifdef CHECK_EXTRA_INFO
1492 			g_print ("ERROR: %s: Unexpected signal: %s\n", expected_signals_name, str);
1493 #endif
1494 			exit (1);
1495 		}
1496 	}
1497 #ifdef CHECK_EXTRA_INFO
1498 	else
1499 		g_print ("WARNING: Non tested signal: %s\n", str);
1500 #endif
1501 
1502 	g_free (str);
1503 }
1504 
1505 static gboolean
1506 check_data_model_value (GdaDataModel *model, gint row, gint col, GType type, const gchar *value)
1507 {
1508 	GValue *gvalue;
1509 	const GValue *mvalue;
1510 	gboolean retval;
1511 	GError *lerror = NULL;
1512 
1513 	row = ADJUST_ROW_FOR_MODEL (model, row);
1514 
1515 	if (value) {
1516 		gvalue = gda_value_new (type);
1517 		if (!gda_value_set_from_string (gvalue, value, type)) {
1518 			gda_value_free (gvalue);
1519 			return FALSE;
1520 		}
1521 	}
1522 	else
1523 		gvalue = gda_value_new_null ();
1524 
1525 	mvalue = gda_data_model_get_value_at (model, col, row, &lerror);
1526 	if (!mvalue) {
1527 #ifdef CHECK_EXTRA_INFO
1528 		g_print ("Can't get data model's value: %s\n",
1529 			 lerror && lerror->message ? lerror->message : "No detail");
1530 #endif
1531 		return FALSE;
1532 	}
1533 	retval = !gda_value_compare (gvalue, mvalue);
1534 	gda_value_free (gvalue);
1535 
1536 #ifdef CHECK_EXTRA_INFO
1537 	if (!retval) {
1538 		gchar *str = gda_value_stringify (mvalue);
1539 		g_print ("ERROR: At row=%d, col=%d, expected '%s' and got '%s'\n", row, col, value, str);
1540 		g_free (str);
1541 		g_print ("Model is:\n");
1542 		gda_data_model_dump (model, stdout);
1543 	}
1544 #endif
1545 
1546 	return retval;
1547 }
1548 
1549 static gboolean
1550 check_data_model_n_rows (GdaDataModel *model, gint nrows)
1551 {
1552 	const GValue *value;
1553 
1554 	nrows = ADJUST_ROW_FOR_MODEL (model, nrows);
1555 
1556 	if (gda_data_model_get_n_rows (model) != nrows) {
1557 #ifdef CHECK_EXTRA_INFO
1558 		g_print ("ERROR: Number of rows is %d (expected %d)\n", gda_data_model_get_n_rows (model), nrows);
1559 #endif
1560 		return FALSE;
1561 	}
1562 
1563 	value = gda_data_model_get_value_at (model, 0, nrows, NULL);
1564 	if (value) {
1565 #ifdef CHECK_EXTRA_INFO
1566 		g_print ("ERROR: Got a value at row %d, should not get any as it is out of bounds\n", nrows);
1567 #endif
1568 		return FALSE;
1569 	}
1570 	return TRUE;
1571 }
1572 
1573 static gboolean
1574 check_proxy_set_filter (GdaDataProxy *proxy, const gchar *filter)
1575 {
1576 	GError *error = NULL;
1577 	if (!gda_data_proxy_set_filter_expr (proxy, filter, &error)) {
1578 #ifdef CHECK_EXTRA_INFO
1579 		g_print ("ERROR: Could not set filter to '%s': %s\n", filter,
1580 			 error && error->message ? error->message : "No detail");
1581 #endif
1582 		if (error)
1583 			g_error_free (error);
1584 		return FALSE;
1585 	}
1586 	return TRUE;
1587 }
1588 
1589 static gboolean
1590 check_proxy_row_is_deleted (GdaDataProxy *proxy, gint row, gboolean is_deleted)
1591 {
1592 	row = ADJUST_ROW (row);
1593 
1594 	if (gda_data_proxy_row_is_deleted (proxy, row) != is_deleted) {
1595 #ifdef CHECK_EXTRA_INFO
1596 		g_print ("ERROR: Expected row %d %s which is not true\n", row,
1597 			 is_deleted ? "deleted": "not deleted");
1598 #endif
1599 		return FALSE;
1600 	}
1601 	return TRUE;
1602 }
1603 
1604 static gboolean
1605 check_data_model_append_row (GdaDataModel *model)
1606 {
1607 	gint row;
1608 	GError *error = NULL;
1609 	row = gda_data_model_append_row (model, &error);
1610 	if (row < 0) {
1611 #ifdef CHECK_EXTRA_INFO
1612 		g_print ("ERROR: Failed to add a row: %s\n", error && error->message ? error->message : "No detail");
1613 #endif
1614 		if (error)
1615 			g_error_free (error);
1616 		return FALSE;
1617 	}
1618 #ifdef CHECK_EXTRA_INFO
1619 	g_print ("Added row %d\n", row);
1620 #endif
1621 	return TRUE;
1622 }
1623 
1624 static gboolean
1625 check_data_model_set_values (GdaDataModel *model, gint row, GList *values)
1626 {
1627 	GError *error = NULL;
1628 	row = ADJUST_ROW_FOR_MODEL (model, row);
1629 
1630 	if (!gda_data_model_set_values (model, row, values, &error)) {
1631 #ifdef CHECK_EXTRA_INFO
1632 		g_print ("ERROR: Failed to set values: %s\n", error && error->message ? error->message : "No detail");
1633 #endif
1634 		if (error)
1635 			g_error_free (error);
1636 		return FALSE;
1637 	}
1638 
1639 	/* check individual values */
1640 	GList *list;
1641 	gint col;
1642 	for (col = 0, list = values; list; col++, list = list->next) {
1643 		GError *lerror = NULL;
1644 		const GValue *cvalue = gda_data_model_get_value_at (model, col, row, &lerror);
1645 		if (!cvalue) {
1646 #ifdef CHECK_EXTRA_INFO
1647 			g_print ("Can't get data model's value: %s\n",
1648 				 lerror && lerror->message ? lerror->message : "No detail");
1649 #endif
1650 			return FALSE;
1651 		}
1652 		if (list->data && gda_value_compare (cvalue, (GValue *) list->data)) {
1653 #ifdef CHECK_EXTRA_INFO
1654 			g_print ("ERROR: Read value is not equal to set value: got '%s' and expected '%s'\n",
1655 				 gda_value_stringify (cvalue), gda_value_stringify ((GValue *) list->data));
1656 #endif
1657 			return FALSE;
1658 		}
1659 	}
1660 
1661 	return TRUE;
1662 }
1663 
1664 static gboolean
1665 check_data_model_remove_row (GdaDataModel *model, gint row)
1666 {
1667 	GError *error = NULL;
1668 	row = ADJUST_ROW_FOR_MODEL (model, row);
1669 
1670 	if (!gda_data_model_remove_row (model, row, &error)) {
1671 #ifdef CHECK_EXTRA_INFO
1672 		g_print ("ERROR: Failed to remove row: %s\n", error && error->message ? error->message : "No detail");
1673 #endif
1674 		if (error)
1675 			g_error_free (error);
1676 		return FALSE;
1677 	}
1678 
1679 	return TRUE;
1680 }
1681 
1682 /* remove several rows */
1683 static gboolean do_test_delete_rows (void)
1684 {
1685 #define FILE "city.csv"
1686 	GError *error = NULL;
1687 	gchar *file;
1688 	GdaDataModel *import, *model, *proxy;
1689 	GSList *errors;
1690 	GdaSet *options;
1691 
1692 	file = g_build_filename (CHECK_FILES, "tests", "data-models", FILE, NULL);
1693 	options = gda_set_new_inline (1, "TITLE_AS_FIRST_LINE", G_TYPE_BOOLEAN, TRUE);
1694 	import = gda_data_model_import_new_file (file, TRUE, options);
1695 	g_free (file);
1696 	g_object_unref (options);
1697 
1698 	if ((errors = gda_data_model_import_get_errors (GDA_DATA_MODEL_IMPORT (import)))) {
1699 #ifdef CHECK_EXTRA_INFO
1700 		g_print ("ERROR: Could not load file '%s'\n", FILE);
1701 #endif
1702 		g_object_unref (import);
1703 		return FALSE;
1704 	}
1705 
1706 	model = (GdaDataModel*) gda_data_model_array_copy_model (import, &error);
1707 	if (!model) {
1708 #ifdef CHECK_EXTRA_INFO
1709 		g_print ("ERROR: Could not copy GdaDataModelImport into a GdaDataModelArray: %s\n",
1710 			 error && error->message ? error->message : "No detail");
1711 #endif
1712 		g_error_free (error);
1713 		return FALSE;
1714 	}
1715 	g_object_unref (import);
1716 
1717 	proxy = (GdaDataModel *) gda_data_proxy_new (model);
1718 	if (!proxy) {
1719 #ifdef CHECK_EXTRA_INFO
1720 		g_print ("ERROR: Could not create GdaDataProxy\n");
1721 #endif
1722 		return FALSE;
1723 	}
1724 	g_object_set (G_OBJECT (proxy), "defer-sync", FALSE, NULL);
1725 	gda_data_proxy_set_sample_size (GDA_DATA_PROXY (proxy), 0);
1726 	g_object_set (G_OBJECT (proxy), "defer-sync", defer_sync,
1727 		      "prepend-null-entry", prepend_null_row, NULL);
1728 
1729 	gboolean retval = FALSE;
1730 
1731 	g_signal_connect (G_OBJECT (proxy), "reset",
1732 			  G_CALLBACK (proxy_reset_cb), NULL);
1733 	g_signal_connect (G_OBJECT (proxy), "row-inserted",
1734 			  G_CALLBACK (proxy_row_cb), "I");
1735 	g_signal_connect (G_OBJECT (proxy), "row-updated",
1736 			  G_CALLBACK (proxy_row_cb), "U");
1737 	g_signal_connect (G_OBJECT (proxy), "row-removed",
1738 			  G_CALLBACK (proxy_row_cb), "R");
1739 
1740 
1741 	/*
1742 	 * mark a proxy row to be deleted
1743 	 */
1744 	declare_expected_signals ("u3", "Prepare to delete row 3");
1745 	gda_data_proxy_delete (GDA_DATA_PROXY (proxy), 3);
1746 	clean_expected_signals (proxy);
1747 	if (!check_data_model_n_rows (proxy, 158)) goto out;
1748 
1749 	/*
1750 	 * mark a proxy row to be deleted
1751 	 */
1752 	declare_expected_signals ("u5", "Prepare to delete row 5");
1753 	gda_data_proxy_delete (GDA_DATA_PROXY (proxy), 5);
1754 	clean_expected_signals (proxy);
1755 	if (!check_data_model_n_rows (proxy, 158)) goto out;
1756 
1757 	/*
1758 	 * mark a proxy row to be deleted
1759 	 */
1760 	declare_expected_signals ("u1", "Prepare to delete row 1");
1761 	gda_data_proxy_delete (GDA_DATA_PROXY (proxy), 1);
1762 	clean_expected_signals (proxy);
1763 	if (!check_data_model_n_rows (proxy, 158)) goto out;
1764 
1765 	if (!check_data_model_value (proxy, 12, 0, G_TYPE_STRING, "Tirana")) goto out;
1766 	if (!check_data_model_value (proxy, 12, 2, G_TYPE_STRING, "270000")) goto out;
1767 	if (!check_data_model_value (proxy, 12, 3, G_TYPE_STRING, "Tirana")) goto out;
1768 	if (!check_data_model_value (proxy, 12, 5, G_TYPE_STRING, "270000")) goto out;
1769 
1770 	/* commit changes */
1771 	declare_expected_signals ("r1r4r2", "Commit row changes");
1772 
1773 	if (! gda_data_proxy_apply_all_changes (GDA_DATA_PROXY (proxy), &error)) {
1774 #ifdef CHECK_EXTRA_INFO
1775 		g_print ("ERROR: Could not copy GdaDataModelImport into a GdaDataModelArray: %s\n",
1776 			 error && error->message ? error->message : "No detail");
1777 #endif
1778 		g_error_free (error);
1779 		return FALSE;
1780 	}
1781 
1782 	clean_expected_signals (proxy);
1783 	if (!check_data_model_n_rows (proxy, 155)) goto out;
1784 
1785 	if (!check_data_model_value (model, 9, 0, G_TYPE_STRING, "Tirana")) goto out;
1786 	if (!check_data_model_value (model, 9, 2, G_TYPE_STRING, "270000")) goto out;
1787 	if (prepend_null_row) {
1788 		if (!check_data_model_value (model, 0, 0, G_TYPE_STRING, "Herat")) goto out;
1789 		if (!check_data_model_value (model, 1, 0, G_TYPE_STRING, "Mazar-e-Sharif")) goto out;
1790 		if (!check_data_model_value (model, 2, 0, G_TYPE_STRING, "Benguela")) goto out;
1791 	}
1792 	else {
1793 		if (!check_data_model_value (model, 0, 0, G_TYPE_STRING, "Oranjestad")) goto out;
1794 		if (!check_data_model_value (model, 1, 0, G_TYPE_STRING, "Kabul")) goto out;
1795 		if (!check_data_model_value (model, 2, 0, G_TYPE_STRING, "Qandahar")) goto out;
1796 	}
1797 	if (!check_data_model_value (model, 3, 0, G_TYPE_STRING, "Huambo")) goto out;
1798 	if (!check_data_model_value (model, 4, 0, G_TYPE_STRING, "Lobito")) goto out;
1799 
1800 	retval = TRUE;
1801  out:
1802 	g_object_unref (model);
1803 	g_object_unref (proxy);
1804 	return retval;
1805 }
1806 
1807 /* remove several rows */
1808 static gboolean do_test_modifs_persistance (void)
1809 {
1810 #define FILE "city.csv"
1811 	GError *error = NULL;
1812 	gchar *file;
1813 	GdaDataModel *import, *model_1, *model_2, *proxy;
1814 	GSList *errors;
1815 	GdaSet *options;
1816 	gint nrows, i;
1817 	gboolean retval = FALSE;
1818 	GValue *value;
1819 
1820 	/* load complete city.csv file */
1821 	file = g_build_filename (CHECK_FILES, "tests", "data-models", FILE, NULL);
1822 	options = gda_set_new_inline (1, "TITLE_AS_FIRST_LINE", G_TYPE_BOOLEAN, TRUE);
1823 	import = gda_data_model_import_new_file (file, TRUE, options);
1824 	g_free (file);
1825 	g_object_unref (options);
1826 
1827 	if ((errors = gda_data_model_import_get_errors (GDA_DATA_MODEL_IMPORT (import)))) {
1828 #ifdef CHECK_EXTRA_INFO
1829 		g_print ("ERROR: Could not load file '%s'\n", FILE);
1830 #endif
1831 		g_object_unref (import);
1832 		return FALSE;
1833 	}
1834 	nrows = gda_data_model_get_n_rows (import);
1835 
1836 	/* define model_1 and model_2: take one part of the file only:
1837 	 * model_1 has a bit more than the 1st half of import, and model_2 has
1838 	 * a bit more than the 2nd half of import */
1839 	model_1 = (GdaDataModel*) gda_data_model_array_copy_model (import, &error);
1840 	if (!model_1) {
1841 #ifdef CHECK_EXTRA_INFO
1842 		g_print ("ERROR: Could not copy GdaDataModelImport into a GdaDataModelArray: %s\n",
1843 			 error && error->message ? error->message : "No detail");
1844 #endif
1845 		g_error_free (error);
1846 		return FALSE;
1847 	}
1848 	for (i = 74 + 10; i < nrows; i++) {
1849 		if (! gda_data_model_remove_row (model_1, 74 + 10, &error)) {
1850 #ifdef CHECK_EXTRA_INFO
1851 			g_print ("ERROR: Could not trim end of GdaDataModelArray: %s\n",
1852 				 error && error->message ? error->message : "No detail");
1853 #endif
1854 			g_error_free (error);
1855 			return FALSE;
1856 		}
1857 	}
1858 
1859 	model_2 = (GdaDataModel*) gda_data_model_array_copy_model (import, &error);
1860 	if (!model_2) {
1861 #ifdef CHECK_EXTRA_INFO
1862 		g_print ("ERROR: Could not copy GdaDataModelImport into a GdaDataModelArray: %s\n",
1863 			 error && error->message ? error->message : "No detail");
1864 #endif
1865 		g_error_free (error);
1866 		return FALSE;
1867 	}
1868 	for (i = 0; i < 74 - 10; i++) {
1869 		if (! gda_data_model_remove_row (model_2, 0, &error)) {
1870 #ifdef CHECK_EXTRA_INFO
1871 			g_print ("ERROR: Could not trim start of GdaDataModelArray: %s\n",
1872 				 error && error->message ? error->message : "No detail");
1873 #endif
1874 			g_error_free (error);
1875 			return FALSE;
1876 		}
1877 	}
1878 	g_object_unref (import);
1879 
1880 	proxy = (GdaDataModel *) gda_data_proxy_new (model_1);
1881 	if (!proxy) {
1882 #ifdef CHECK_EXTRA_INFO
1883 		g_print ("ERROR: Could not create GdaDataProxy\n");
1884 #endif
1885 		return FALSE;
1886 	}
1887 	g_object_set (G_OBJECT (proxy), "cache-changes", TRUE, NULL);
1888 	g_object_set (G_OBJECT (proxy), "defer-sync", FALSE, NULL);
1889 	gda_data_proxy_set_sample_size (GDA_DATA_PROXY (proxy), 0);
1890 	g_object_set (G_OBJECT (proxy), "defer-sync", defer_sync,
1891 		      "prepend-null-entry", prepend_null_row, NULL);
1892 
1893 	g_signal_connect (G_OBJECT (proxy), "reset", G_CALLBACK (proxy_reset_cb), NULL);
1894 	g_signal_connect (G_OBJECT (proxy), "row-inserted", G_CALLBACK (proxy_row_cb), "I");
1895 	g_signal_connect (G_OBJECT (proxy), "row-updated", G_CALLBACK (proxy_row_cb), "U");
1896 	g_signal_connect (G_OBJECT (proxy), "row-removed", G_CALLBACK (proxy_row_cb), "R");
1897 
1898 	/*
1899 	 * update a row
1900 	 */
1901 	declare_expected_signals ("U74", "update a row in proxied model_1 (1st half)");
1902 	g_value_set_string (value = gda_value_new (G_TYPE_STRING), "BigCity");
1903 	if (!gda_data_model_set_value_at (proxy, 0, ADJUST_ROW (74), value, &error)) {
1904 #ifdef CHECK_EXTRA_INFO
1905 		g_print ("ERROR: Failed to set value: %s\n", error && error->message ? error->message : "No detail");
1906 #endif
1907 		goto out;
1908 	}
1909 	clean_expected_signals (proxy);
1910 	if (!check_data_model_value (proxy, 74, 0, G_TYPE_STRING, "BigCity")) goto out;
1911 	if (!check_data_model_value (proxy, 74, 2, G_TYPE_STRING, "296226")) goto out;
1912 	if (!check_data_model_value (proxy, 74, 3, G_TYPE_STRING, "Tigre")) goto out;
1913 	if (!check_data_model_value (proxy, 74, 5, G_TYPE_STRING, "296226")) goto out;
1914 
1915 	/*
1916 	 * insert a row
1917 	 */
1918 	GList *values;
1919 	declare_expected_signals ("I84", "insert a row in proxied model_1");
1920 	if (! check_data_model_append_row (proxy)) goto out;
1921 	clean_expected_signals (proxy);
1922 	if (!check_data_model_n_rows (proxy, 85)) goto out;
1923 
1924 	values = make_values_list (0, G_TYPE_STRING, "BigCity3", G_TYPE_STRING, NULL, G_TYPE_STRING, "123456", (GType) 0);
1925 	declare_expected_signals ("U84", "Set values of new proxied row");
1926 	if (!check_data_model_set_values (proxy, 84, values)) goto out;
1927 	free_values_list (values);
1928 	clean_expected_signals (proxy);
1929 	if (!check_data_model_value (proxy, 84, 0, G_TYPE_STRING, "BigCity3")) goto out;
1930 	if (!check_data_model_value (proxy, 84, 1, G_TYPE_STRING, NULL)) goto out;
1931 	if (!check_data_model_value (proxy, 84, 2, G_TYPE_STRING, "123456")) goto out;
1932 	if (!check_data_model_value (proxy, 84, 3, G_TYPE_STRING, NULL)) goto out;
1933 	if (!check_data_model_value (proxy, 84, 4, G_TYPE_STRING, NULL)) goto out;
1934 	if (!check_data_model_value (proxy, 84, 5, G_TYPE_STRING, NULL)) goto out;
1935 
1936 	/*
1937 	 * change to proxied model_2 & update a row
1938 	 */
1939 	g_print ("Setting proxied data model to model_2\n");
1940 	g_object_set (G_OBJECT (proxy), "model", model_2, NULL);
1941 
1942 	check_data_model_n_rows (proxy, 95);
1943 
1944 	declare_expected_signals ("U21", "update a row in proxied model_2 (2nd half)");
1945 	g_value_set_string (value = gda_value_new (G_TYPE_STRING), "BigCity2");
1946 	if (!gda_data_model_set_value_at (proxy, 0, ADJUST_ROW (21), value, &error)) {
1947 #ifdef CHECK_EXTRA_INFO
1948 		g_print ("ERROR: Failed to set value: %s\n", error && error->message ? error->message : "No detail");
1949 #endif
1950 		goto out;
1951 	}
1952 	clean_expected_signals (proxy);
1953 	if (!check_data_model_value (proxy, 21, 0, G_TYPE_STRING, "BigCity2")) goto out;
1954 	if (!check_data_model_value (proxy, 21, 2, G_TYPE_STRING, "92273")) goto out;
1955 	if (!check_data_model_value (proxy, 21, 3, G_TYPE_STRING, "Cairns")) goto out;
1956 	if (!check_data_model_value (proxy, 21, 5, G_TYPE_STRING, "92273")) goto out;
1957 
1958 	if (!check_data_model_value (proxy, 94, 0, G_TYPE_STRING, "BigCity3")) goto out;
1959 	if (!check_data_model_value (proxy, 94, 1, G_TYPE_STRING, NULL)) goto out;
1960 	if (!check_data_model_value (proxy, 94, 2, G_TYPE_STRING, "123456")) goto out;
1961 	if (!check_data_model_value (proxy, 94, 3, G_TYPE_STRING, NULL)) goto out;
1962 	if (!check_data_model_value (proxy, 94, 4, G_TYPE_STRING, NULL)) goto out;
1963 	if (!check_data_model_value (proxy, 94, 5, G_TYPE_STRING, NULL)) goto out;
1964 
1965 	/*
1966 	 * change proxied model and make sure the changes are cached
1967 	 */
1968 	g_print ("Seting proxied data model to model_1\n");
1969 	g_object_set (G_OBJECT (proxy), "model", model_1, NULL);
1970 	if (!check_data_model_value (proxy, 74, 0, G_TYPE_STRING, "BigCity")) goto out;
1971 	if (!check_data_model_value (proxy, 74, 2, G_TYPE_STRING, "296226")) goto out;
1972 	if (!check_data_model_value (proxy, 74, 3, G_TYPE_STRING, "Tigre")) goto out;
1973 	if (!check_data_model_value (proxy, 74, 5, G_TYPE_STRING, "296226")) goto out;
1974 
1975 	g_print ("Setting proxied data model to model_2\n");
1976 	g_object_set (G_OBJECT (proxy), "model", model_2, NULL);
1977 	if (!check_data_model_value (proxy, 21, 0, G_TYPE_STRING, "BigCity2")) goto out;
1978 	if (!check_data_model_value (proxy, 21, 2, G_TYPE_STRING, "92273")) goto out;
1979 	if (!check_data_model_value (proxy, 21, 3, G_TYPE_STRING, "Cairns")) goto out;
1980 	if (!check_data_model_value (proxy, 21, 5, G_TYPE_STRING, "92273")) goto out;
1981 
1982 	if (!check_data_model_value (proxy, 10, 0, G_TYPE_STRING, "BigCity")) goto out;
1983 	if (!check_data_model_value (proxy, 10, 2, G_TYPE_STRING, "296226")) goto out;
1984 	if (!check_data_model_value (proxy, 10, 3, G_TYPE_STRING, "Tigre")) goto out;
1985 	if (!check_data_model_value (proxy, 10, 5, G_TYPE_STRING, "296226")) goto out;
1986 
1987 	//gda_data_model_dump (proxy, NULL);
1988 
1989 	g_print ("Seting proxied data model to model_1\n");
1990 	g_object_set (G_OBJECT (proxy), "model", model_1, NULL);
1991 	if (!check_data_model_value (proxy, 74, 0, G_TYPE_STRING, "BigCity")) goto out;
1992 	if (!check_data_model_value (proxy, 74, 2, G_TYPE_STRING, "296226")) goto out;
1993 	if (!check_data_model_value (proxy, 74, 3, G_TYPE_STRING, "Tigre")) goto out;
1994 	if (!check_data_model_value (proxy, 74, 5, G_TYPE_STRING, "296226")) goto out;
1995 
1996 	//gda_data_model_dump (proxy, NULL);
1997 
1998 	g_print ("Setting proxied data model to model_2\n");
1999 	g_object_set (G_OBJECT (proxy), "model", model_2, NULL);
2000 	declare_expected_signals ("R94/U21/U10", "Resetting all the changes");
2001 	gda_data_proxy_cancel_all_changes (GDA_DATA_PROXY (proxy));
2002 	clean_expected_signals (proxy);
2003 
2004 	retval = TRUE;
2005  out:
2006 	g_signal_handlers_disconnect_by_func (G_OBJECT (proxy), G_CALLBACK (proxy_reset_cb), NULL);
2007 	g_signal_handlers_disconnect_by_func (G_OBJECT (proxy), G_CALLBACK (proxy_row_cb), "I");
2008 	g_signal_handlers_disconnect_by_func (G_OBJECT (proxy), G_CALLBACK (proxy_row_cb), "U");
2009 	g_signal_handlers_disconnect_by_func (G_OBJECT (proxy), G_CALLBACK (proxy_row_cb), "R");
2010 
2011 	g_object_unref (model_1);
2012 	g_object_unref (model_2);
2013 	g_object_unref (proxy);
2014 	return retval;
2015 }
2016