libgda r3075 - in trunk: . doc/C doc/C/tmpl libgda libgda/sqlite po providers/postgres providers/skel-implementation/capi providers/sqlite tests/data-models tests/meta-store tests/providers tools
- From: vivien svn gnome org
- To: svn-commits-list gnome org
- Subject: libgda r3075 - in trunk: . doc/C doc/C/tmpl libgda libgda/sqlite po providers/postgres providers/skel-implementation/capi providers/sqlite tests/data-models tests/meta-store tests/providers tools
- Date: Wed, 12 Mar 2008 21:18:25 +0000 (GMT)
Author: vivien
Date: Wed Mar 12 21:18:24 2008
New Revision: 3075
URL: http://svn.gnome.org/viewvc/libgda?rev=3075&view=rev
Log:
2008-03-12 Vivien Malerba <malerba gnome-db org>
* tools/command-exec.c:
* tools/gda-sql.c:
* libgda/gda-meta-struct.[ch]: improvements (to compute only the necessary features, and others)
* doc/C: doc. updates
* po/POTFILES.in:
* po/POTFILES.skip: applied corrections (as proposed by
http://l10n.gnome.org/module/libgda)
* libgda/gda-easy.c: applied correction for gda_drop_table() (from Phil Longstaff)
* libgda/sqlite/gda-sqlite-provider.c: don't count the number of opened connections
* libgda/gda-meta-struct.[ch]:
* libgda/gda-meta-store.[ch]: added new methods
* tests/providers: changed tests to avoid needing reference XML files
* tools/gda-sql.c: allow to display a graph for a table and the tables it references (by
appending a '=' after that table name)
* others: misc. corrections
Removed:
trunk/tests/providers/FIELDS_SCHEMA_Berkeley-DB_data.xml
trunk/tests/providers/FIELDS_SCHEMA_Mdb_actor.xml
trunk/tests/providers/FIELDS_SCHEMA_Mdb_film.xml
trunk/tests/providers/FIELDS_SCHEMA_Mdb_film_actor.xml
trunk/tests/providers/FIELDS_SCHEMA_Mdb_language.xml
trunk/tests/providers/FIELDS_SCHEMA_MySQL_actor.xml
trunk/tests/providers/FIELDS_SCHEMA_MySQL_film.xml
trunk/tests/providers/FIELDS_SCHEMA_MySQL_film_actor.xml
trunk/tests/providers/FIELDS_SCHEMA_MySQL_language.xml
trunk/tests/providers/FIELDS_SCHEMA_PostgreSQL_actor.xml
trunk/tests/providers/FIELDS_SCHEMA_PostgreSQL_film.xml
trunk/tests/providers/FIELDS_SCHEMA_PostgreSQL_film_actor.xml
trunk/tests/providers/FIELDS_SCHEMA_PostgreSQL_language.xml
trunk/tests/providers/FIELDS_SCHEMA_SQLite_actor.xml
trunk/tests/providers/FIELDS_SCHEMA_SQLite_film.xml
trunk/tests/providers/FIELDS_SCHEMA_SQLite_film_actor.xml
trunk/tests/providers/FIELDS_SCHEMA_SQLite_language.xml
Modified:
trunk/ChangeLog
trunk/doc/C/information_schema.png
trunk/doc/C/information_schema.svg
trunk/doc/C/libgda-4.0-sections.txt
trunk/doc/C/libgda-4.0.types.in
trunk/doc/C/tmpl/gda-batch.sgml
trunk/doc/C/tmpl/gda-meta-store.sgml
trunk/doc/C/tmpl/gda-meta-struct.sgml
trunk/doc/C/tmpl/gda-server-provider.sgml
trunk/libgda/gda-batch.c
trunk/libgda/gda-config.c
trunk/libgda/gda-connection.c
trunk/libgda/gda-connection.h
trunk/libgda/gda-data-model-import.c
trunk/libgda/gda-data-model.c
trunk/libgda/gda-decl.h
trunk/libgda/gda-easy.c
trunk/libgda/gda-marshal.list
trunk/libgda/gda-meta-store.c
trunk/libgda/gda-meta-store.h
trunk/libgda/gda-meta-struct.c
trunk/libgda/gda-meta-struct.h
trunk/libgda/gda-server-operation.c
trunk/libgda/gda-server-provider.h
trunk/libgda/gda-value.c
trunk/libgda/information_schema.xml
trunk/libgda/libgda-array.dtd
trunk/libgda/sqlite/gda-sqlite-meta.c
trunk/libgda/sqlite/gda-sqlite-meta.h
trunk/libgda/sqlite/gda-sqlite-provider.c
trunk/libgda/sqlite/utils.c
trunk/po/POTFILES.in
trunk/po/POTFILES.skip
trunk/providers/postgres/gda-postgres-ddl.c
trunk/providers/postgres/gda-postgres-meta.c
trunk/providers/postgres/gda-postgres-meta.h
trunk/providers/postgres/gda-postgres-provider.c
trunk/providers/skel-implementation/capi/ (props changed)
trunk/providers/sqlite/sqlite_specs_create_table.xml.in
trunk/tests/data-models/check_data_proxy.c
trunk/tests/data-models/check_model_import.c
trunk/tests/meta-store/common.c
trunk/tests/providers/Makefile.am
trunk/tests/providers/README
trunk/tests/providers/TYPES_SCHEMA_SQLite.xml
trunk/tests/providers/check_bdb.c
trunk/tests/providers/check_mdb.c
trunk/tests/providers/check_mysql.c
trunk/tests/providers/check_oracle.c
trunk/tests/providers/check_postgres.c
trunk/tests/providers/check_sqlite.c
trunk/tests/providers/prov-test-common.c
trunk/tests/providers/prov-test-common.h
trunk/tests/providers/prov-test-util.c
trunk/tests/providers/prov-test-util.h
trunk/tools/command-exec.c
trunk/tools/gda-sql.c
Modified: trunk/doc/C/information_schema.png
==============================================================================
Binary files. No diff available.
Modified: trunk/doc/C/information_schema.svg
==============================================================================
--- trunk/doc/C/information_schema.svg (original)
+++ trunk/doc/C/information_schema.svg Wed Mar 12 21:18:24 2008
@@ -3,363 +3,358 @@
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd" [
<!ATTLIST svg xmlns:xlink CDATA #FIXED "http://www.w3.org/1999/xlink">
]>
-<!-- Generated by Graphviz version 2.12 (Mon Apr 23 09:57:53 UTC 2007)
- For user: (vmalerba) MALERBA Vivien DSNA-DTI SIM ATM M204 p5713 -->
+<!-- Generated by Graphviz version 2.12 (Tue Sep 4 16:56:48 UTC 2007)
+ For user: (vivien) Vivien,,, -->
<!-- Title: G Pages: 1 -->
-<svg width="17.14in" height="7.60in"
+<svg width="17.22in" height="7.82in"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
-<g id="graph0" class="graph" transform="scale(1.33333 1.33333) rotate(0) translate(4 544)">
+<g id="graph0" class="graph" transform="scale(1.33333 1.33333) rotate(0) translate(4 560)">
<title>G</title>
-<polygon style="fill:white;stroke:white;" points="-4,4 -4,-544 1230,-544 1230,4 -4,4"/>
+<polygon style="fill:white;stroke:white;" points="-4,4 -4,-560 1236,-560 1236,4 -4,4"/>
<!-- _attributes -->
<g id="node1" class="node"><title>_attributes</title>
-<polygon style="fill:none;stroke:black;" points="210,-36 136,-36 136,-1.42109e-14 210,-0 210,-36"/>
-<text text-anchor="middle" x="173" y="-13" style="font-family:Nimbus Roman No9 L;font-weight:regular;font-size:11.34pt;">_attributes</text>
+<polygon style="fill:none;stroke:black;" points="204,-38 130,-38 130,-2 204,-2 204,-38"/>
+<text text-anchor="middle" x="167" y="-16" style="font-family:Nimbus Roman No9 L;font-weight:regular;font-size:11.34pt;">_attributes</text>
</g>
<!-- _information_schema_catalog_name -->
<g id="node2" class="node"><title>_information_schema_catalog_name</title>
-<polygon style="fill:none;stroke:black;" points="685,-540 463,-540 463,-504 685,-504 685,-540"/>
-<text text-anchor="middle" x="574" y="-517" style="font-family:Nimbus Roman No9 L;font-weight:regular;font-size:11.34pt;">_information_schema_catalog_name</text>
+<polygon style="fill:none;stroke:black;" points="721,-556 499,-556 499,-520 721,-520 721,-556"/>
+<text text-anchor="middle" x="610" y="-534" style="font-family:Nimbus Roman No9 L;font-weight:regular;font-size:11.34pt;">_information_schema_catalog_name</text>
</g>
<!-- _builtin_data_types -->
<g id="node3" class="node"><title>_builtin_data_types</title>
-<polygon style="fill:none;stroke:black;" points="918,-324 792,-324 792,-288 918,-288 918,-324"/>
-<text text-anchor="middle" x="855" y="-301" style="font-family:Nimbus Roman No9 L;font-weight:regular;font-size:11.34pt;">_builtin_data_types</text>
+<polygon style="fill:none;stroke:black;" points="924,-340 798,-340 798,-304 924,-304 924,-340"/>
+<text text-anchor="middle" x="861" y="-318" style="font-family:Nimbus Roman No9 L;font-weight:regular;font-size:11.34pt;">_builtin_data_types</text>
</g>
<!-- _udt -->
<g id="node4" class="node"><title>_udt</title>
-<polygon style="fill:none;stroke:black;" points="990,-324 936,-324 936,-288 990,-288 990,-324"/>
-<text text-anchor="middle" x="963" y="-301" style="font-family:Nimbus Roman No9 L;font-weight:regular;font-size:11.34pt;">_udt</text>
+<polygon style="fill:none;stroke:black;" points="996,-340 942,-340 942,-304 996,-304 996,-340"/>
+<text text-anchor="middle" x="969" y="-318" style="font-family:Nimbus Roman No9 L;font-weight:regular;font-size:11.34pt;">_udt</text>
</g>
<!-- _element_types -->
<g id="node5" class="node"><title>_element_types</title>
-<polygon style="fill:none;stroke:black;" points="508,-36 406,-36 406,-1.42109e-14 508,-0 508,-36"/>
-<text text-anchor="middle" x="457" y="-13" style="font-family:Nimbus Roman No9 L;font-weight:regular;font-size:11.34pt;">_element_types</text>
+<polygon style="fill:none;stroke:black;" points="504,-38 402,-38 402,-2 504,-2 504,-38"/>
+<text text-anchor="middle" x="453" y="-16" style="font-family:Nimbus Roman No9 L;font-weight:regular;font-size:11.34pt;">_element_types</text>
</g>
<!-- _schemata -->
<g id="node6" class="node"><title>_schemata</title>
-<polygon style="fill:none;stroke:black;" points="611,-468 537,-468 537,-432 611,-432 611,-468"/>
-<text text-anchor="middle" x="574" y="-445" style="font-family:Nimbus Roman No9 L;font-weight:regular;font-size:11.34pt;">_schemata</text>
+<polygon style="fill:none;stroke:black;" points="647,-484 573,-484 573,-448 647,-448 647,-484"/>
+<text text-anchor="middle" x="610" y="-462" style="font-family:Nimbus Roman No9 L;font-weight:regular;font-size:11.34pt;">_schemata</text>
</g>
<!-- _schemata->_information_schema_catalog_name -->
<g id="edge2" class="edge"><title>_schemata->_information_schema_catalog_name</title>
-<path style="fill:none;stroke:black;" d="M574,-468C574,-476 574,-485 574,-494"/>
-<polygon style="fill:black;stroke:black;" points="570.5,-494 574,-504 577.5,-494 570.5,-494"/>
+<path style="fill:none;stroke:black;" d="M610,-484C610,-492 610,-501 610,-510"/>
+<polygon style="fill:black;stroke:black;" points="606.5,-510 610,-520 613.5,-510 606.5,-510"/>
</g>
<!-- _udt_columns -->
<g id="node8" class="node"><title>_udt_columns</title>
-<polygon style="fill:none;stroke:black;" points="1104,-252 1010,-252 1010,-216 1104,-216 1104,-252"/>
-<text text-anchor="middle" x="1057" y="-229" style="font-family:Nimbus Roman No9 L;font-weight:regular;font-size:11.34pt;">_udt_columns</text>
+<polygon style="fill:none;stroke:black;" points="1110,-266 1016,-266 1016,-230 1110,-230 1110,-266"/>
+<text text-anchor="middle" x="1063" y="-244" style="font-family:Nimbus Roman No9 L;font-weight:regular;font-size:11.34pt;">_udt_columns</text>
</g>
<!-- _udt_columns->_udt -->
<g id="edge4" class="edge"><title>_udt_columns->_udt</title>
-<path style="fill:none;stroke:black;" d="M1033,-252C1022,-261 1007,-272 994,-282"/>
-<polygon style="fill:black;stroke:black;" points="991.9,-279.2 986,-288 996.1,-284.8 991.9,-279.2"/>
+<path style="fill:none;stroke:black;" d="M1040,-266C1028,-276 1013,-287 1000,-298"/>
+<polygon style="fill:black;stroke:black;" points="997.9,-295.2 992,-304 1002.1,-300.8 997.9,-295.2"/>
</g>
<!-- _enums -->
<g id="node10" class="node"><title>_enums</title>
-<polygon style="fill:none;stroke:black;" points="992,-252 934,-252 934,-216 992,-216 992,-252"/>
-<text text-anchor="middle" x="963" y="-229" style="font-family:Nimbus Roman No9 L;font-weight:regular;font-size:11.34pt;">_enums</text>
+<polygon style="fill:none;stroke:black;" points="998,-266 940,-266 940,-230 998,-230 998,-266"/>
+<text text-anchor="middle" x="969" y="-244" style="font-family:Nimbus Roman No9 L;font-weight:regular;font-size:11.34pt;">_enums</text>
</g>
<!-- _enums->_udt -->
<g id="edge6" class="edge"><title>_enums->_udt</title>
-<path style="fill:none;stroke:black;" d="M963,-252C963,-260 963,-269 963,-278"/>
-<polygon style="fill:black;stroke:black;" points="959.5,-278 963,-288 966.5,-278 959.5,-278"/>
+<path style="fill:none;stroke:black;" d="M969,-266C969,-275 969,-284 969,-294"/>
+<polygon style="fill:black;stroke:black;" points="965.5,-294 969,-304 972.5,-294 965.5,-294"/>
</g>
<!-- _domains -->
<g id="node12" class="node"><title>_domains</title>
-<polygon style="fill:none;stroke:black;" points="760,-324 690,-324 690,-288 760,-288 760,-324"/>
-<text text-anchor="middle" x="725" y="-301" style="font-family:Nimbus Roman No9 L;font-weight:regular;font-size:11.34pt;">_domains</text>
+<polygon style="fill:none;stroke:black;" points="765,-340 695,-340 695,-304 765,-304 765,-340"/>
+<text text-anchor="middle" x="730" y="-318" style="font-family:Nimbus Roman No9 L;font-weight:regular;font-size:11.34pt;">_domains</text>
</g>
<!-- _domains->_schemata -->
<g id="edge8" class="edge"><title>_domains->_schemata</title>
-<path style="fill:none;stroke:black;" d="M717,-324C708,-344 691,-375 668,-396 654,-409 637,-421 620,-429"/>
-<polygon style="fill:black;stroke:black;" points="618.042,-426.084 611,-434 621.441,-432.203 618.042,-426.084"/>
+<path style="fill:none;stroke:black;" d="M721,-340C710,-359 693,-390 673,-412 664,-422 653,-433 643,-441"/>
+<polygon style="fill:black;stroke:black;" points="640.221,-438.781 635,-448 644.831,-444.049 640.221,-438.781"/>
</g>
<!-- _tables -->
<g id="node14" class="node"><title>_tables</title>
-<polygon style="fill:none;stroke:black;" points="567,-324 513,-324 513,-288 567,-288 567,-324"/>
-<text text-anchor="middle" x="540" y="-301" style="font-family:Nimbus Roman No9 L;font-weight:regular;font-size:11.34pt;">_tables</text>
+<polygon style="fill:none;stroke:black;" points="582,-340 528,-340 528,-304 582,-304 582,-340"/>
+<text text-anchor="middle" x="555" y="-318" style="font-family:Nimbus Roman No9 L;font-weight:regular;font-size:11.34pt;">_tables</text>
</g>
<!-- _tables->_schemata -->
<g id="edge10" class="edge"><title>_tables->_schemata</title>
-<path style="fill:none;stroke:black;" d="M544,-324C549,-349 560,-393 568,-422"/>
-<polygon style="fill:black;stroke:black;" points="564.607,-422.881 570,-432 571.471,-421.508 564.607,-422.881"/>
+<path style="fill:none;stroke:black;" d="M562,-340C572,-365 589,-409 600,-438"/>
+<polygon style="fill:black;stroke:black;" points="596.774,-439.427 603,-448 603.479,-437.416 596.774,-439.427"/>
</g>
<!-- _collations -->
<g id="node16" class="node"><title>_collations</title>
-<polygon style="fill:none;stroke:black;" points="523,-396 447,-396 447,-360 523,-360 523,-396"/>
-<text text-anchor="middle" x="485" y="-373" style="font-family:Nimbus Roman No9 L;font-weight:regular;font-size:11.34pt;">_collations</text>
+<polygon style="fill:none;stroke:black;" points="498,-412 422,-412 422,-376 498,-376 498,-412"/>
+<text text-anchor="middle" x="460" y="-390" style="font-family:Nimbus Roman No9 L;font-weight:regular;font-size:11.34pt;">_collations</text>
</g>
<!-- _collations->_schemata -->
<g id="edge12" class="edge"><title>_collations->_schemata</title>
-<path style="fill:none;stroke:black;" d="M507,-396C518,-405 532,-416 544,-426"/>
-<polygon style="fill:black;stroke:black;" points="541.9,-428.8 552,-432 546.1,-423.2 541.9,-428.8"/>
+<path style="fill:none;stroke:black;" d="M498,-412C518,-422 543,-433 564,-444"/>
+<polygon style="fill:black;stroke:black;" points="562.44,-447.137 573,-448 565.283,-440.74 562.44,-447.137"/>
</g>
<!-- _routines -->
<g id="node18" class="node"><title>_routines</title>
-<polygon style="fill:none;stroke:black;" points="1100,-396 1032,-396 1032,-360 1100,-360 1100,-396"/>
-<text text-anchor="middle" x="1066" y="-373" style="font-family:Nimbus Roman No9 L;font-weight:regular;font-size:11.34pt;">_routines</text>
+<polygon style="fill:none;stroke:black;" points="1090,-412 1022,-412 1022,-376 1090,-376 1090,-412"/>
+<text text-anchor="middle" x="1056" y="-390" style="font-family:Nimbus Roman No9 L;font-weight:regular;font-size:11.34pt;">_routines</text>
</g>
<!-- _routines->_schemata -->
<g id="edge14" class="edge"><title>_routines->_schemata</title>
-<path style="fill:none;stroke:black;" d="M1032,-383C946,-396 720,-429 621,-443"/>
-<polygon style="fill:black;stroke:black;" points="620.119,-439.607 611,-445 621.492,-446.471 620.119,-439.607"/>
+<path style="fill:none;stroke:black;" d="M1022,-400C942,-413 747,-444 657,-458"/>
+<polygon style="fill:black;stroke:black;" points="656.119,-454.607 647,-460 657.492,-461.471 656.119,-454.607"/>
</g>
<!-- _views -->
<g id="node20" class="node"><title>_views</title>
-<polygon style="fill:none;stroke:black;" points="544,-252 490,-252 490,-216 544,-216 544,-252"/>
-<text text-anchor="middle" x="517" y="-229" style="font-family:Nimbus Roman No9 L;font-weight:regular;font-size:11.34pt;">_views</text>
+<polygon style="fill:none;stroke:black;" points="548,-266 494,-266 494,-230 548,-230 548,-266"/>
+<text text-anchor="middle" x="521" y="-244" style="font-family:Nimbus Roman No9 L;font-weight:regular;font-size:11.34pt;">_views</text>
</g>
<!-- _views->_tables -->
<g id="edge16" class="edge"><title>_views->_tables</title>
-<path style="fill:none;stroke:black;" d="M523,-252C526,-260 529,-269 531,-278"/>
-<polygon style="fill:black;stroke:black;" points="527.774,-279.427 534,-288 534.479,-277.416 527.774,-279.427"/>
+<path style="fill:none;stroke:black;" d="M529,-266C533,-275 538,-285 542,-295"/>
+<polygon style="fill:black;stroke:black;" points="538.74,-296.283 546,-304 545.137,-293.44 538.74,-296.283"/>
</g>
<!-- _character_sets -->
<g id="node22" class="node"><title>_character_sets</title>
-<polygon style="fill:none;stroke:black;" points="457,-324 357,-324 357,-288 457,-288 457,-324"/>
-<text text-anchor="middle" x="407" y="-301" style="font-family:Nimbus Roman No9 L;font-weight:regular;font-size:11.34pt;">_character_sets</text>
+<polygon style="fill:none;stroke:black;" points="510,-340 410,-340 410,-304 510,-304 510,-340"/>
+<text text-anchor="middle" x="460" y="-318" style="font-family:Nimbus Roman No9 L;font-weight:regular;font-size:11.34pt;">_character_sets</text>
</g>
<!-- _character_sets->_schemata -->
<g id="edge18" class="edge"><title>_character_sets->_schemata</title>
-<path style="fill:none;stroke:black;" d="M409,-324C412,-344 419,-377 438,-396 461,-421 498,-435 527,-442"/>
-<polygon style="fill:black;stroke:black;" points="526.508,-445.471 537,-444 527.881,-438.607 526.508,-445.471"/>
+<path style="fill:none;stroke:black;" d="M479,-340C506,-366 554,-412 584,-441"/>
+<polygon style="fill:black;stroke:black;" points="581.454,-443.404 591,-448 586.404,-438.454 581.454,-443.404"/>
</g>
<!-- _character_sets->_collations -->
<g id="edge20" class="edge"><title>_character_sets->_collations</title>
-<path style="fill:none;stroke:black;" d="M427,-324C437,-333 448,-343 458,-353"/>
-<polygon style="fill:black;stroke:black;" points="456.169,-356.049 466,-360 460.779,-350.781 456.169,-356.049"/>
+<path style="fill:none;stroke:black;" d="M460,-340C460,-348 460,-357 460,-366"/>
+<polygon style="fill:black;stroke:black;" points="456.5,-366 460,-376 463.5,-366 456.5,-366"/>
</g>
<!-- _triggers -->
<g id="node25" class="node"><title>_triggers</title>
-<polygon style="fill:none;stroke:black;" points="628,-252 562,-252 562,-216 628,-216 628,-252"/>
-<text text-anchor="middle" x="595" y="-229" style="font-family:Nimbus Roman No9 L;font-weight:regular;font-size:11.34pt;">_triggers</text>
+<polygon style="fill:none;stroke:black;" points="632,-266 566,-266 566,-230 632,-230 632,-266"/>
+<text text-anchor="middle" x="599" y="-244" style="font-family:Nimbus Roman No9 L;font-weight:regular;font-size:11.34pt;">_triggers</text>
</g>
<!-- _triggers->_schemata -->
<g id="edge22" class="edge"><title>_triggers->_schemata</title>
-<path style="fill:none;stroke:black;" d="M593,-252C589,-290 581,-377 577,-422"/>
-<polygon style="fill:black;stroke:black;" points="573.512,-421.701 576,-432 580.478,-422.398 573.512,-421.701"/>
+<path style="fill:none;stroke:black;" d="M600,-266C602,-305 606,-393 609,-438"/>
+<polygon style="fill:black;stroke:black;" points="605.5,-438 609,-448 612.5,-438 605.5,-438"/>
</g>
<!-- _triggers->_tables -->
<g id="edge24" class="edge"><title>_triggers->_tables</title>
-<path style="fill:none;stroke:black;" d="M581,-252C575,-260 567,-271 560,-280"/>
-<polygon style="fill:black;stroke:black;" points="557.2,-277.9 554,-288 562.8,-282.1 557.2,-277.9"/>
+<path style="fill:none;stroke:black;" d="M588,-266C583,-275 576,-285 571,-295"/>
+<polygon style="fill:black;stroke:black;" points="567.797,-293.559 566,-304 573.916,-296.958 567.797,-293.559"/>
</g>
<!-- _table_constraints -->
<g id="node28" class="node"><title>_table_constraints</title>
-<polygon style="fill:none;stroke:black;" points="384,-252 268,-252 268,-216 384,-216 384,-252"/>
-<text text-anchor="middle" x="326" y="-229" style="font-family:Nimbus Roman No9 L;font-weight:regular;font-size:11.34pt;">_table_constraints</text>
-</g>
-<!-- _table_constraints->_schemata -->
-<g id="edge28" class="edge"><title>_table_constraints->_schemata</title>
-<path style="fill:none;stroke:black;" d="M328,-252C330,-271 336,-301 348,-324 369,-363 379,-373 415,-396 449,-419 494,-432 527,-441"/>
-<polygon style="fill:black;stroke:black;" points="526.508,-444.471 537,-443 527.881,-437.607 526.508,-444.471"/>
+<polygon style="fill:none;stroke:black;" points="331,-266 215,-266 215,-230 331,-230 331,-266"/>
+<text text-anchor="middle" x="273" y="-244" style="font-family:Nimbus Roman No9 L;font-weight:regular;font-size:11.34pt;">_table_constraints</text>
</g>
<!-- _table_constraints->_tables -->
<g id="edge26" class="edge"><title>_table_constraints->_tables</title>
-<path style="fill:none;stroke:black;" d="M380,-252C418,-265 469,-282 503,-294"/>
-<polygon style="fill:black;stroke:black;" points="502.416,-297.479 513,-297 504.427,-290.774 502.416,-297.479"/>
+<path style="fill:none;stroke:black;" d="M331,-257C380,-266 450,-281 518,-305"/>
+<polygon style="fill:black;stroke:black;" points="517.416,-308.479 528,-308 519.427,-301.774 517.416,-308.479"/>
</g>
<!-- _domain_constraints -->
-<g id="node31" class="node"><title>_domain_constraints</title>
-<polygon style="fill:none;stroke:black;" points="778,-252 646,-252 646,-216 778,-216 778,-252"/>
-<text text-anchor="middle" x="712" y="-229" style="font-family:Nimbus Roman No9 L;font-weight:regular;font-size:11.34pt;">_domain_constraints</text>
+<g id="node30" class="node"><title>_domain_constraints</title>
+<polygon style="fill:none;stroke:black;" points="782,-266 650,-266 650,-230 782,-230 782,-266"/>
+<text text-anchor="middle" x="716" y="-244" style="font-family:Nimbus Roman No9 L;font-weight:regular;font-size:11.34pt;">_domain_constraints</text>
</g>
<!-- _domain_constraints->_schemata -->
-<g id="edge32" class="edge"><title>_domain_constraints->_schemata</title>
-<path style="fill:none;stroke:black;" d="M700,-252C676,-290 620,-379 591,-423"/>
-<polygon style="fill:black;stroke:black;" points="587.797,-421.559 586,-432 593.916,-424.958 587.797,-421.559"/>
+<g id="edge30" class="edge"><title>_domain_constraints->_schemata</title>
+<path style="fill:none;stroke:black;" d="M706,-266C700,-277 693,-291 686,-304 663,-351 637,-406 622,-439"/>
+<polygon style="fill:black;stroke:black;" points="618.863,-437.44 618,-448 625.26,-440.283 618.863,-437.44"/>
</g>
<!-- _domain_constraints->_domains -->
-<g id="edge30" class="edge"><title>_domain_constraints->_domains</title>
-<path style="fill:none;stroke:black;" d="M715,-252C716,-260 718,-269 720,-278"/>
-<polygon style="fill:black;stroke:black;" points="716.607,-278.881 722,-288 723.471,-277.508 716.607,-278.881"/>
+<g id="edge28" class="edge"><title>_domain_constraints->_domains</title>
+<path style="fill:none;stroke:black;" d="M719,-266C721,-275 723,-285 725,-294"/>
+<polygon style="fill:black;stroke:black;" points="721.607,-294.881 727,-304 728.471,-293.508 721.607,-294.881"/>
</g>
<!-- _parameters -->
-<g id="node34" class="node"><title>_parameters</title>
-<polygon style="fill:none;stroke:black;" points="1226,-324 1142,-324 1142,-288 1226,-288 1226,-324"/>
-<text text-anchor="middle" x="1184" y="-301" style="font-family:Nimbus Roman No9 L;font-weight:regular;font-size:11.34pt;">_parameters</text>
+<g id="node33" class="node"><title>_parameters</title>
+<polygon style="fill:none;stroke:black;" points="1098,-340 1014,-340 1014,-304 1098,-304 1098,-340"/>
+<text text-anchor="middle" x="1056" y="-318" style="font-family:Nimbus Roman No9 L;font-weight:regular;font-size:11.34pt;">_parameters</text>
</g>
<!-- _parameters->_routines -->
-<g id="edge34" class="edge"><title>_parameters->_routines</title>
-<path style="fill:none;stroke:black;" d="M1154,-324C1139,-333 1120,-345 1104,-355"/>
-<polygon style="fill:black;stroke:black;" points="1102.04,-352.084 1095,-360 1105.44,-358.203 1102.04,-352.084"/>
+<g id="edge32" class="edge"><title>_parameters->_routines</title>
+<path style="fill:none;stroke:black;" d="M1056,-340C1056,-348 1056,-357 1056,-366"/>
+<polygon style="fill:black;stroke:black;" points="1052.5,-366 1056,-376 1059.5,-366 1052.5,-366"/>
</g>
<!-- _routine_columns -->
-<g id="node36" class="node"><title>_routine_columns</title>
-<polygon style="fill:none;stroke:black;" points="1124,-324 1008,-324 1008,-288 1124,-288 1124,-324"/>
-<text text-anchor="middle" x="1066" y="-301" style="font-family:Nimbus Roman No9 L;font-weight:regular;font-size:11.34pt;">_routine_columns</text>
+<g id="node35" class="node"><title>_routine_columns</title>
+<polygon style="fill:none;stroke:black;" points="1232,-340 1116,-340 1116,-304 1232,-304 1232,-340"/>
+<text text-anchor="middle" x="1174" y="-318" style="font-family:Nimbus Roman No9 L;font-weight:regular;font-size:11.34pt;">_routine_columns</text>
</g>
<!-- _routine_columns->_routines -->
-<g id="edge36" class="edge"><title>_routine_columns->_routines</title>
-<path style="fill:none;stroke:black;" d="M1066,-324C1066,-332 1066,-341 1066,-350"/>
-<polygon style="fill:black;stroke:black;" points="1062.5,-350 1066,-360 1069.5,-350 1062.5,-350"/>
+<g id="edge34" class="edge"><title>_routine_columns->_routines</title>
+<path style="fill:none;stroke:black;" d="M1144,-340C1129,-349 1110,-361 1094,-371"/>
+<polygon style="fill:black;stroke:black;" points="1092.04,-368.084 1085,-376 1095.44,-374.203 1092.04,-368.084"/>
</g>
<!-- _all_types -->
-<g id="node38" class="node"><title>_all_types</title>
-<ellipse style="fill:none;stroke:black;" cx="875" cy="-234" rx="41.1755" ry="18"/>
-<text text-anchor="middle" x="875" y="-229" style="font-family:Nimbus Roman No9 L;font-weight:regular;font-size:11.34pt;">_all_types</text>
+<g id="node37" class="node"><title>_all_types</title>
+<ellipse style="fill:none;stroke:black;" cx="880" cy="-248" rx="41.8014" ry="19.799"/>
+<text text-anchor="middle" x="880" y="-244" style="font-family:Nimbus Roman No9 L;font-weight:regular;font-size:11.34pt;">_all_types</text>
</g>
<!-- _all_types->_builtin_data_types -->
-<g id="edge38" class="edge"><title>_all_types->_builtin_data_types</title>
-<path style="fill:none;stroke:black;" d="M870,-252C868,-260 865,-269 863,-278"/>
-<polygon style="fill:black;stroke:black;" points="859.521,-277.416 860,-288 866.226,-279.427 859.521,-277.416"/>
+<g id="edge36" class="edge"><title>_all_types->_builtin_data_types</title>
+<path style="fill:none;stroke:black;" d="M875,-268C873,-276 870,-285 868,-294"/>
+<polygon style="fill:black;stroke:black;" points="864.529,-293.508 866,-304 871.393,-294.881 864.529,-293.508"/>
</g>
<!-- _all_types->_udt -->
-<g id="edge40" class="edge"><title>_all_types->_udt</title>
-<path style="fill:none;stroke:black;" d="M895,-250C906,-259 920,-271 933,-281"/>
-<polygon style="fill:black;stroke:black;" points="931.169,-284.049 941,-288 935.779,-278.781 931.169,-284.049"/>
+<g id="edge38" class="edge"><title>_all_types->_udt</title>
+<path style="fill:none;stroke:black;" d="M901,-266C912,-275 927,-287 939,-297"/>
+<polygon style="fill:black;stroke:black;" points="937.169,-300.049 947,-304 941.779,-294.781 937.169,-300.049"/>
</g>
<!-- _all_types->_domains -->
-<g id="edge42" class="edge"><title>_all_types->_domains</title>
-<path style="fill:none;stroke:black;" d="M847,-247C826,-258 795,-272 769,-285"/>
-<polygon style="fill:black;stroke:black;" points="767.717,-281.74 760,-289 770.56,-288.137 767.717,-281.74"/>
+<g id="edge40" class="edge"><title>_all_types->_domains</title>
+<path style="fill:none;stroke:black;" d="M851,-262C829,-273 799,-288 774,-300"/>
+<polygon style="fill:black;stroke:black;" points="772.042,-297.084 765,-305 775.441,-303.203 772.042,-297.084"/>
</g>
<!-- _columns -->
-<g id="node42" class="node"><title>_columns</title>
-<polygon style="fill:none;stroke:black;" points="472,-252 402,-252 402,-216 472,-216 472,-252"/>
-<text text-anchor="middle" x="437" y="-229" style="font-family:Nimbus Roman No9 L;font-weight:regular;font-size:11.34pt;">_columns</text>
+<g id="node41" class="node"><title>_columns</title>
+<polygon style="fill:none;stroke:black;" points="476,-266 406,-266 406,-230 476,-230 476,-266"/>
+<text text-anchor="middle" x="441" y="-244" style="font-family:Nimbus Roman No9 L;font-weight:regular;font-size:11.34pt;">_columns</text>
</g>
<!-- _columns->_tables -->
-<g id="edge44" class="edge"><title>_columns->_tables</title>
-<path style="fill:none;stroke:black;" d="M463,-252C476,-261 492,-272 506,-282"/>
-<polygon style="fill:black;stroke:black;" points="504.738,-285.365 515,-288 508.621,-279.541 504.738,-285.365"/>
+<g id="edge42" class="edge"><title>_columns->_tables</title>
+<path style="fill:none;stroke:black;" d="M469,-266C484,-276 503,-288 519,-299"/>
+<polygon style="fill:black;stroke:black;" points="517.559,-302.203 528,-304 520.958,-296.084 517.559,-302.203"/>
</g>
<!-- _columns->_collations -->
-<g id="edge48" class="edge"><title>_columns->_collations</title>
-<path style="fill:none;stroke:black;" d="M448,-252C454,-262 462,-276 466,-288 474,-308 478,-332 481,-350"/>
-<polygon style="fill:black;stroke:black;" points="477.607,-350.881 483,-360 484.471,-349.508 477.607,-350.881"/>
+<g id="edge46" class="edge"><title>_columns->_collations</title>
+<path style="fill:none;stroke:black;" d="M424,-266C415,-276 406,-290 401,-304 397,-320 395,-326 401,-340 406,-352 415,-362 424,-370"/>
+<polygon style="fill:black;stroke:black;" points="421.9,-372.8 432,-376 426.1,-367.2 421.9,-372.8"/>
</g>
<!-- _columns->_character_sets -->
-<g id="edge46" class="edge"><title>_columns->_character_sets</title>
-<path style="fill:none;stroke:black;" d="M429,-252C426,-260 422,-270 419,-278"/>
-<polygon style="fill:black;stroke:black;" points="415.464,-277.415 415,-288 421.964,-280.015 415.464,-277.415"/>
+<g id="edge44" class="edge"><title>_columns->_character_sets</title>
+<path style="fill:none;stroke:black;" d="M446,-266C448,-275 450,-285 453,-294"/>
+<polygon style="fill:black;stroke:black;" points="449.607,-294.881 455,-304 456.471,-293.508 449.607,-294.881"/>
</g>
<!-- _referential_constraints -->
-<g id="node46" class="node"><title>_referential_constraints</title>
-<polygon style="fill:none;stroke:black;" points="148,-180 2.84217e-14,-180 0,-144 148,-144 148,-180"/>
-<text text-anchor="middle" x="74" y="-157" style="font-family:Nimbus Roman No9 L;font-weight:regular;font-size:11.34pt;">_referential_constraints</text>
+<g id="node45" class="node"><title>_referential_constraints</title>
+<polygon style="fill:none;stroke:black;" points="148,-190 2.84217e-14,-190 0,-154 148,-154 148,-190"/>
+<text text-anchor="middle" x="74" y="-168" style="font-family:Nimbus Roman No9 L;font-weight:regular;font-size:11.34pt;">_referential_constraints</text>
</g>
<!-- _referential_constraints->_table_constraints -->
-<g id="edge50" class="edge"><title>_referential_constraints->_table_constraints</title>
-<path style="fill:none;stroke:black;" d="M131,-180C169,-191 218,-205 258,-216"/>
-<polygon style="fill:black;stroke:black;" points="257.416,-219.479 268,-219 259.427,-212.774 257.416,-219.479"/>
+<g id="edge48" class="edge"><title>_referential_constraints->_table_constraints</title>
+<path style="fill:none;stroke:black;" d="M115,-190C143,-201 179,-215 211,-227"/>
+<polygon style="fill:black;stroke:black;" points="209.406,-230.158 220,-230 211.62,-223.517 209.406,-230.158"/>
</g>
<!-- _referential_constraints->_table_constraints -->
-<g id="edge52" class="edge"><title>_referential_constraints->_table_constraints</title>
-<path style="fill:none;stroke:black;" d="M143,-180C180,-190 224,-203 259,-213"/>
-<polygon style="fill:black;stroke:black;" points="258.416,-216.479 269,-216 260.427,-209.774 258.416,-216.479"/>
+<g id="edge50" class="edge"><title>_referential_constraints->_table_constraints</title>
+<path style="fill:none;stroke:black;" d="M127,-190C157,-201 193,-215 223,-226"/>
+<polygon style="fill:black;stroke:black;" points="221.44,-229.137 232,-230 224.283,-222.74 221.44,-229.137"/>
</g>
<!-- _check_constraints -->
-<g id="node49" class="node"><title>_check_constraints</title>
-<ellipse style="fill:none;stroke:black;" cx="540" cy="-162" rx="66.1777" ry="18"/>
-<text text-anchor="middle" x="540" y="-157" style="font-family:Nimbus Roman No9 L;font-weight:regular;font-size:11.34pt;">_check_constraints</text>
+<g id="node48" class="node"><title>_check_constraints</title>
+<ellipse style="fill:none;stroke:black;" cx="695" cy="-172" rx="66.799" ry="19.799"/>
+<text text-anchor="middle" x="695" y="-168" style="font-family:Nimbus Roman No9 L;font-weight:regular;font-size:11.34pt;">_check_constraints</text>
</g>
<!-- _check_constraints->_table_constraints -->
-<g id="edge54" class="edge"><title>_check_constraints->_table_constraints</title>
-<path style="fill:none;stroke:black;" d="M498,-176C467,-186 425,-201 390,-213"/>
-<polygon style="fill:black;stroke:black;" points="388.573,-209.774 380,-216 390.584,-216.479 388.573,-209.774"/>
+<g id="edge52" class="edge"><title>_check_constraints->_table_constraints</title>
+<path style="fill:none;stroke:black;" d="M646,-186C637,-188 628,-190 619,-192 616,-193 441,-221 341,-237"/>
+<polygon style="fill:black;stroke:black;" points="340.119,-233.607 331,-239 341.492,-240.471 340.119,-233.607"/>
</g>
<!-- _check_constraints->_domain_constraints -->
-<g id="edge56" class="edge"><title>_check_constraints->_domain_constraints</title>
-<path style="fill:none;stroke:black;" d="M576,-177C600,-187 632,-201 660,-212"/>
-<polygon style="fill:black;stroke:black;" points="658.44,-215.137 669,-216 661.283,-208.74 658.44,-215.137"/>
+<g id="edge54" class="edge"><title>_check_constraints->_domain_constraints</title>
+<path style="fill:none;stroke:black;" d="M701,-192C703,-201 706,-211 708,-220"/>
+<polygon style="fill:black;stroke:black;" points="704.774,-221.427 711,-230 711.479,-219.416 704.774,-221.427"/>
</g>
<!-- _key_column_usage -->
-<g id="node52" class="node"><title>_key_column_usage</title>
-<polygon style="fill:none;stroke:black;" points="296,-180 166,-180 166,-144 296,-144 296,-180"/>
-<text text-anchor="middle" x="231" y="-157" style="font-family:Nimbus Roman No9 L;font-weight:regular;font-size:11.34pt;">_key_column_usage</text>
+<g id="node51" class="node"><title>_key_column_usage</title>
+<polygon style="fill:none;stroke:black;" points="456,-190 326,-190 326,-154 456,-154 456,-190"/>
+<text text-anchor="middle" x="391" y="-168" style="font-family:Nimbus Roman No9 L;font-weight:regular;font-size:11.34pt;">_key_column_usage</text>
</g>
<!-- _key_column_usage->_table_constraints -->
-<g id="edge58" class="edge"><title>_key_column_usage->_table_constraints</title>
-<path style="fill:none;stroke:black;" d="M255,-180C266,-189 281,-200 294,-210"/>
-<polygon style="fill:black;stroke:black;" points="291.9,-212.8 302,-216 296.1,-207.2 291.9,-212.8"/>
+<g id="edge56" class="edge"><title>_key_column_usage->_table_constraints</title>
+<path style="fill:none;stroke:black;" d="M363,-190C347,-200 326,-213 309,-224"/>
+<polygon style="fill:black;stroke:black;" points="306.9,-221.2 301,-230 311.1,-226.8 306.9,-221.2"/>
</g>
<!-- _key_column_usage->_columns -->
-<g id="edge60" class="edge"><title>_key_column_usage->_columns</title>
-<path style="fill:none;stroke:black;" d="M288,-180C317,-189 352,-201 393,-216"/>
-<polygon style="fill:black;stroke:black;" points="391.406,-219.158 402,-219 393.62,-212.517 391.406,-219.158"/>
+<g id="edge58" class="edge"><title>_key_column_usage->_columns</title>
+<path style="fill:none;stroke:black;" d="M403,-190C409,-199 417,-211 424,-222"/>
+<polygon style="fill:black;stroke:black;" points="420.732,-223.375 429,-230 426.668,-219.665 420.732,-223.375"/>
</g>
<!-- _check_column_usage -->
-<g id="node55" class="node"><title>_check_column_usage</title>
-<polygon style="fill:none;stroke:black;" points="456,-180 314,-180 314,-144 456,-144 456,-180"/>
-<text text-anchor="middle" x="385" y="-157" style="font-family:Nimbus Roman No9 L;font-weight:regular;font-size:11.34pt;">_check_column_usage</text>
+<g id="node54" class="node"><title>_check_column_usage</title>
+<polygon style="fill:none;stroke:black;" points="308,-190 166,-190 166,-154 308,-154 308,-190"/>
+<text text-anchor="middle" x="237" y="-168" style="font-family:Nimbus Roman No9 L;font-weight:regular;font-size:11.34pt;">_check_column_usage</text>
</g>
<!-- _check_column_usage->_table_constraints -->
-<g id="edge62" class="edge"><title>_check_column_usage->_table_constraints</title>
-<path style="fill:none;stroke:black;" d="M370,-180C363,-189 355,-199 347,-208"/>
-<polygon style="fill:black;stroke:black;" points="344.2,-205.9 341,-216 349.8,-210.1 344.2,-205.9"/>
+<g id="edge60" class="edge"><title>_check_column_usage->_table_constraints</title>
+<path style="fill:none;stroke:black;" d="M246,-190C250,-199 255,-211 261,-221"/>
+<polygon style="fill:black;stroke:black;" points="257.74,-222.283 265,-230 264.137,-219.44 257.74,-222.283"/>
</g>
<!-- _check_column_usage->_columns -->
-<g id="edge64" class="edge"><title>_check_column_usage->_columns</title>
-<path style="fill:none;stroke:black;" d="M398,-180C404,-188 411,-199 418,-208"/>
-<polygon style="fill:black;stroke:black;" points="415.2,-210.1 424,-216 420.8,-205.9 415.2,-210.1"/>
+<g id="edge62" class="edge"><title>_check_column_usage->_columns</title>
+<path style="fill:none;stroke:black;" d="M285,-190C319,-202 364,-218 396,-231"/>
+<polygon style="fill:black;stroke:black;" points="395.415,-234.536 406,-235 398.015,-228.036 395.415,-234.536"/>
</g>
<!-- _view_column_usage -->
-<g id="node58" class="node"><title>_view_column_usage</title>
-<polygon style="fill:none;stroke:black;" points="760,-180 624,-180 624,-144 760,-144 760,-180"/>
-<text text-anchor="middle" x="692" y="-157" style="font-family:Nimbus Roman No9 L;font-weight:regular;font-size:11.34pt;">_view_column_usage</text>
+<g id="node57" class="node"><title>_view_column_usage</title>
+<polygon style="fill:none;stroke:black;" points="610,-190 474,-190 474,-154 610,-154 610,-190"/>
+<text text-anchor="middle" x="542" y="-168" style="font-family:Nimbus Roman No9 L;font-weight:regular;font-size:11.34pt;">_view_column_usage</text>
</g>
<!-- _view_column_usage->_views -->
-<g id="edge66" class="edge"><title>_view_column_usage->_views</title>
-<path style="fill:none;stroke:black;" d="M643,-180C618,-189 588,-201 553,-216"/>
-<polygon style="fill:black;stroke:black;" points="551.717,-212.74 544,-220 554.56,-219.137 551.717,-212.74"/>
+<g id="edge64" class="edge"><title>_view_column_usage->_views</title>
+<path style="fill:none;stroke:black;" d="M537,-190C535,-199 531,-210 529,-220"/>
+<polygon style="fill:black;stroke:black;" points="525.521,-219.416 526,-230 532.226,-221.427 525.521,-219.416"/>
</g>
<!-- _view_column_usage->_columns -->
-<g id="edge68" class="edge"><title>_view_column_usage->_columns</title>
-<path style="fill:none;stroke:black;" d="M624,-178C577,-190 518,-204 482,-216"/>
-<polygon style="fill:black;stroke:black;" points="480.573,-212.774 472,-219 482.584,-219.479 480.573,-212.774"/>
+<g id="edge66" class="edge"><title>_view_column_usage->_columns</title>
+<path style="fill:none;stroke:black;" d="M518,-190C505,-200 488,-213 473,-224"/>
+<polygon style="fill:black;stroke:black;" points="470.9,-221.2 465,-230 475.1,-226.8 470.9,-221.2"/>
</g>
<!-- _domain_column_usage -->
-<g id="node61" class="node"><title>_domain_column_usage</title>
-<ellipse style="fill:none;stroke:black;" cx="859" cy="-162" rx="81.1777" ry="18"/>
-<text text-anchor="middle" x="859" y="-157" style="font-family:Nimbus Roman No9 L;font-weight:regular;font-size:11.34pt;">_domain_column_usage</text>
+<g id="node60" class="node"><title>_domain_column_usage</title>
+<ellipse style="fill:none;stroke:black;" cx="862" cy="-172" rx="81.799" ry="19.799"/>
+<text text-anchor="middle" x="862" y="-168" style="font-family:Nimbus Roman No9 L;font-weight:regular;font-size:11.34pt;">_domain_column_usage</text>
</g>
<!-- _domain_column_usage->_domains -->
-<g id="edge70" class="edge"><title>_domain_column_usage->_domains</title>
-<path style="fill:none;stroke:black;" d="M846,-180C832,-199 809,-229 787,-252 778,-262 766,-273 756,-281"/>
-<polygon style="fill:black;stroke:black;" points="753.221,-278.781 748,-288 757.831,-284.049 753.221,-278.781"/>
+<g id="edge68" class="edge"><title>_domain_column_usage->_domains</title>
+<path style="fill:none;stroke:black;" d="M849,-192C835,-212 813,-244 791,-268 782,-278 771,-289 761,-297"/>
+<polygon style="fill:black;stroke:black;" points="758.221,-294.781 753,-304 762.831,-300.049 758.221,-294.781"/>
</g>
<!-- _domain_column_usage->_columns -->
-<g id="edge72" class="edge"><title>_domain_column_usage->_columns</title>
-<path style="fill:none;stroke:black;" d="M800,-175C790,-177 779,-178 769,-180 645,-200 608,-185 482,-216"/>
-<polygon style="fill:black;stroke:black;" points="480.573,-212.774 472,-219 482.584,-219.479 480.573,-212.774"/>
+<g id="edge70" class="edge"><title>_domain_column_usage->_columns</title>
+<path style="fill:none;stroke:black;" d="M803,-186C792,-188 781,-190 771,-192 648,-213 611,-195 486,-228"/>
+<polygon style="fill:black;stroke:black;" points="484.573,-224.774 476,-231 486.584,-231.479 484.573,-224.774"/>
</g>
<!-- _constraint_column_usage -->
-<g id="node64" class="node"><title>_constraint_column_usage</title>
-<ellipse style="fill:none;stroke:black;" cx="308" cy="-90" rx="87.1767" ry="18"/>
-<text text-anchor="middle" x="308" y="-85" style="font-family:Nimbus Roman No9 L;font-weight:regular;font-size:11.34pt;">_constraint_column_usage</text>
+<g id="node63" class="node"><title>_constraint_column_usage</title>
+<ellipse style="fill:none;stroke:black;" cx="303" cy="-96" rx="87.8001" ry="19.799"/>
+<text text-anchor="middle" x="303" y="-92" style="font-family:Nimbus Roman No9 L;font-weight:regular;font-size:11.34pt;">_constraint_column_usage</text>
</g>
<!-- _constraint_column_usage->_key_column_usage -->
-<g id="edge74" class="edge"><title>_constraint_column_usage->_key_column_usage</title>
-<path style="fill:none;stroke:black;" d="M289,-108C279,-117 268,-127 258,-137"/>
-<polygon style="fill:black;stroke:black;" points="255.221,-134.781 250,-144 259.831,-140.049 255.221,-134.781"/>
+<g id="edge72" class="edge"><title>_constraint_column_usage->_key_column_usage</title>
+<path style="fill:none;stroke:black;" d="M326,-116C337,-126 351,-137 362,-147"/>
+<polygon style="fill:black;stroke:black;" points="360.169,-150.049 370,-154 364.779,-144.781 360.169,-150.049"/>
</g>
<!-- _constraint_column_usage->_check_column_usage -->
-<g id="edge76" class="edge"><title>_constraint_column_usage->_check_column_usage</title>
-<path style="fill:none;stroke:black;" d="M327,-108C337,-117 348,-127 358,-137"/>
-<polygon style="fill:black;stroke:black;" points="356.169,-140.049 366,-144 360.779,-134.781 356.169,-140.049"/>
+<g id="edge74" class="edge"><title>_constraint_column_usage->_check_column_usage</title>
+<path style="fill:none;stroke:black;" d="M286,-116C278,-125 268,-136 260,-146"/>
+<polygon style="fill:black;stroke:black;" points="256.951,-144.169 253,-154 262.219,-148.779 256.951,-144.169"/>
</g>
<!-- _view_table_usage -->
-<g id="node67" class="node"><title>_view_table_usage</title>
-<ellipse style="fill:none;stroke:black;" cx="692" cy="-90" rx="66.1777" ry="18"/>
-<text text-anchor="middle" x="692" y="-85" style="font-family:Nimbus Roman No9 L;font-weight:regular;font-size:11.34pt;">_view_table_usage</text>
+<g id="node66" class="node"><title>_view_table_usage</title>
+<ellipse style="fill:none;stroke:black;" cx="542" cy="-96" rx="66.799" ry="19.799"/>
+<text text-anchor="middle" x="542" y="-92" style="font-family:Nimbus Roman No9 L;font-weight:regular;font-size:11.34pt;">_view_table_usage</text>
</g>
<!-- _view_table_usage->_view_column_usage -->
-<g id="edge78" class="edge"><title>_view_table_usage->_view_column_usage</title>
-<path style="fill:none;stroke:black;" d="M692,-108C692,-116 692,-125 692,-134"/>
-<polygon style="fill:black;stroke:black;" points="688.5,-134 692,-144 695.5,-134 688.5,-134"/>
+<g id="edge76" class="edge"><title>_view_table_usage->_view_column_usage</title>
+<path style="fill:none;stroke:black;" d="M542,-116C542,-125 542,-135 542,-144"/>
+<polygon style="fill:black;stroke:black;" points="538.5,-144 542,-154 545.5,-144 538.5,-144"/>
</g>
<!-- _constraint_table_usage -->
-<g id="node69" class="node"><title>_constraint_table_usage</title>
-<ellipse style="fill:none;stroke:black;" cx="308" cy="-18" rx="80.1777" ry="18"/>
-<text text-anchor="middle" x="308" y="-13" style="font-family:Nimbus Roman No9 L;font-weight:regular;font-size:11.34pt;">_constraint_table_usage</text>
+<g id="node68" class="node"><title>_constraint_table_usage</title>
+<ellipse style="fill:none;stroke:black;" cx="303" cy="-20" rx="80.799" ry="19.799"/>
+<text text-anchor="middle" x="303" y="-16" style="font-family:Nimbus Roman No9 L;font-weight:regular;font-size:11.34pt;">_constraint_table_usage</text>
</g>
<!-- _constraint_table_usage->_constraint_column_usage -->
-<g id="edge80" class="edge"><title>_constraint_table_usage->_constraint_column_usage</title>
-<path style="fill:none;stroke:black;" d="M308,-36C308,-44 308,-53 308,-62"/>
-<polygon style="fill:black;stroke:black;" points="304.5,-62 308,-72 311.5,-62 304.5,-62"/>
+<g id="edge78" class="edge"><title>_constraint_table_usage->_constraint_column_usage</title>
+<path style="fill:none;stroke:black;" d="M303,-40C303,-48 303,-57 303,-66"/>
+<polygon style="fill:black;stroke:black;" points="299.5,-66 303,-76 306.5,-66 299.5,-66"/>
</g>
</g>
</svg>
Modified: trunk/doc/C/libgda-4.0-sections.txt
==============================================================================
--- trunk/doc/C/libgda-4.0-sections.txt (original)
+++ trunk/doc/C/libgda-4.0-sections.txt Wed Mar 12 21:18:24 2008
@@ -1164,7 +1164,7 @@
<TITLE>GdaBatch</TITLE>
GdaBatch
gda_batch_new
-gda_batch_copy
+gda_batch_new_copy
gda_batch_add_statement
gda_batch_remove_statement
gda_batch_serialize
@@ -1364,9 +1364,13 @@
gda_meta_store_new
gda_meta_store_new_with_file
gda_meta_store_get_version
-gda_meta_store_get_internal_connection
gda_meta_store_extract
gda_meta_store_modify
+gda_meta_store_schema_get_structure
+gda_meta_store_get_attribute_value
+gda_meta_store_set_attribute_value
+gda_meta_store_schema_add_custom_object
+gda_meta_store_get_internal_connection
<SUBSECTION Standard>
GDA_IS_META_STORE
GDA_META_STORE
@@ -1380,8 +1384,8 @@
<FILE>gda-meta-struct</FILE>
<TITLE>GdaMetaStruct</TITLE>
GdaMetaStruct
+GdaMetaStructFeature
GdaMetaStructError
-GDA_META_STRUCT_ERROR
GdaMetaDbObjectType
GdaMetaDbObject
GDA_META_DB_OBJECT
@@ -1393,12 +1397,15 @@
GDA_META_TABLE_COLUMN
GdaMetaTableForeignKey
GDA_META_TABLE_FOREIGN_KEY
+GDA_META_STRUCT_ERROR
gda_meta_struct_new
gda_meta_struct_complement
GdaMetaSortType
gda_meta_struct_sort_db_objects
gda_meta_struct_get_db_object
gda_meta_struct_get_table_column
+GdaMetaGraphInfo
+gda_meta_struct_dump_as_graph
</SECTION>
<SECTION>
Modified: trunk/doc/C/libgda-4.0.types.in
==============================================================================
--- trunk/doc/C/libgda-4.0.types.in (original)
+++ trunk/doc/C/libgda-4.0.types.in Wed Mar 12 21:18:24 2008
@@ -58,3 +58,4 @@
gda_holder_get_type
gda_set_get_type
gda_meta_store_get_type
+gda_meta_struct_get_type
Modified: trunk/doc/C/tmpl/gda-batch.sgml
==============================================================================
--- trunk/doc/C/tmpl/gda-batch.sgml (original)
+++ trunk/doc/C/tmpl/gda-batch.sgml Wed Mar 12 21:18:24 2008
@@ -43,6 +43,15 @@
@Returns:
+<!-- ##### FUNCTION gda_batch_new_copy ##### -->
+<para>
+
+</para>
+
+ orig:
+ Returns:
+
+
<!-- ##### FUNCTION gda_batch_add_statement ##### -->
<para>
Modified: trunk/doc/C/tmpl/gda-meta-store.sgml
==============================================================================
--- trunk/doc/C/tmpl/gda-meta-store.sgml (original)
+++ trunk/doc/C/tmpl/gda-meta-store.sgml Wed Mar 12 21:18:24 2008
@@ -66,6 +66,7 @@
@gdametastore: the object which received the signal.
@arg1:
+ Returns:
<!-- ##### ARG GdaMetaStore:cnc ##### -->
<para>
@@ -87,6 +88,10 @@
@GDA_META_STORE_INTERNAL_ERROR:
@GDA_META_STORE_MODIFY_CONTENTS_ERROR:
@GDA_META_STORE_EXTRACT_SQL_ERROR:
+ GDA_META_STORE_ATTRIBUTE_NOT_FOUND_ERROR:
+ GDA_META_STORE_ATTRIBUTE_ERROR:
+ GDA_META_STORE_SCHEMA_OBJECT_CONFLICT_ERROR:
+ GDA_META_STORE_SCHEMA_OBJECT_DESCR_ERROR:
<!-- ##### STRUCT GdaMetaStoreChange ##### -->
<para>
@@ -143,38 +148,83 @@
@Returns:
-<!-- ##### FUNCTION gda_meta_store_get_internal_connection ##### -->
+<!-- ##### FUNCTION gda_meta_store_extract ##### -->
<para>
</para>
@store:
+ select_sql:
+ error:
+ Varargs:
@Returns:
-<!-- ##### FUNCTION gda_meta_store_extract ##### -->
+<!-- ##### FUNCTION gda_meta_store_modify ##### -->
<para>
</para>
@store:
- select_sql:
+ table_name:
+ new_data:
+ condition:
@error:
@Varargs:
@Returns:
-<!-- ##### FUNCTION gda_meta_store_modify ##### -->
+<!-- ##### FUNCTION gda_meta_store_schema_get_structure ##### -->
<para>
</para>
@store:
- table_name:
- new_data:
- condition:
@error:
- Varargs:
+ Returns:
+
+
+<!-- ##### FUNCTION gda_meta_store_get_attribute_value ##### -->
+<para>
+
+</para>
+
+ store:
+ att_name:
+ att_value:
+ error:
+ Returns:
+
+
+<!-- ##### FUNCTION gda_meta_store_set_attribute_value ##### -->
+<para>
+
+</para>
+
+ store:
+ att_name:
+ att_value:
+ error:
+ Returns:
+
+
+<!-- ##### FUNCTION gda_meta_store_schema_add_custom_object ##### -->
+<para>
+
+</para>
+
+ store:
+ xml_description:
+ error:
+ Returns:
+
+
+<!-- ##### FUNCTION gda_meta_store_get_internal_connection ##### -->
+<para>
+
+</para>
+
+ store:
@Returns:
Modified: trunk/doc/C/tmpl/gda-meta-struct.sgml
==============================================================================
--- trunk/doc/C/tmpl/gda-meta-struct.sgml (original)
+++ trunk/doc/C/tmpl/gda-meta-struct.sgml Wed Mar 12 21:18:24 2008
@@ -40,6 +40,40 @@
}
gda_meta_struct_free (mstruct);
</programlisting>
+ If now the database object type is not known, one can use the following code:
+ <programlisting>
+GdaMetaStruct *mstruct;
+GdaMetaDbObject *dbo;
+GValue *catalog, *schema, *name;
+
+/* Define name (and optionnally catalog and schema) */
+[...]
+
+mstruct = gda_meta_struct_new ();
+gda_meta_struct_complement (mstruct, store, GDA_META_DB_UNKNOWN, catalog, schema, name, NULL);
+dbo = gda_meta_struct_get_db_object (mstruct, catalog, schema, name);
+if (!dbo)
+ g_print ("Object not found\n");
+else {
+ if ((dbo->obj_type == GDA_META_DB_TABLE) || (dbo->obj_type == GDA_META_DB_VIEW)) {
+ if (dbo->obj_type == GDA_META_DB_TABLE)
+ g_print ("Is a table\n");
+ else if (dbo->obj_type == GDA_META_DB_VIEW) {
+ g_print ("Is a view, definition is:\n");
+ g_print ("%s\n", GDA_META_DB_OBJECT_GET_VIEW (dbo)->view_def);
+ }
+
+ GSList *list;
+ for (list = GDA_META_DB_OBJECT_GET_TABLE (dbo)->columns; list; list = list->next) {
+ GdaMetaTableColumn *tcol = GDA_META_TABLE_COLUMN (list->data);
+ g_print ("COLUMN: %s (%s)\n", tcol->column_name, tcol->column_type);
+ }
+ }
+ else
+ g_print ("Not a table or a view\n");
+}
+gda_meta_struct_free (mstruct);
+ </programlisting>
</para>
<!-- ##### SECTION See_Also ##### -->
@@ -55,25 +89,30 @@
</para>
- object:
- db_objects:
- priv:
-<!-- ##### ENUM GdaMetaStructError ##### -->
+<!-- ##### ARG GdaMetaStruct:features ##### -->
<para>
</para>
- GDA_META_STRUCT_UNKNOWN_OBJECT_ERROR:
- GDA_META_STRUCT_DUPLICATE_OBJECT_ERROR:
- GDA_META_STRUCT_INCOHERENCE_ERROR:
-
-<!-- ##### MACRO GDA_META_STRUCT_ERROR ##### -->
+<!-- ##### ENUM GdaMetaStructFeature ##### -->
<para>
</para>
+ GDA_META_STRUCT_FEATURE_NONE:
+ GDA_META_STRUCT_FEATURE_FOREIGN_KEYS:
+ GDA_META_STRUCT_FEATURE_VIEW_DEPENDENCIES:
+ GDA_META_STRUCT_FEATURE_ALL:
+<!-- ##### ENUM GdaMetaStructError ##### -->
+<para>
+
+</para>
+
+ GDA_META_STRUCT_UNKNOWN_OBJECT_ERROR:
+ GDA_META_STRUCT_DUPLICATE_OBJECT_ERROR:
+ GDA_META_STRUCT_INCOHERENCE_ERROR:
<!-- ##### ENUM GdaMetaDbObjectType ##### -->
<para>
@@ -169,11 +208,19 @@
@x:
+<!-- ##### MACRO GDA_META_STRUCT_ERROR ##### -->
+<para>
+
+</para>
+
+
+
<!-- ##### FUNCTION gda_meta_struct_new ##### -->
<para>
</para>
+ features:
@Returns:
@@ -234,3 +281,21 @@
@Returns:
+<!-- ##### ENUM GdaMetaGraphInfo ##### -->
+<para>
+
+</para>
+
+ GDA_META_GRAPH_COLUMNS:
+
+<!-- ##### FUNCTION gda_meta_struct_dump_as_graph ##### -->
+<para>
+
+</para>
+
+ mstruct:
+ info:
+ error:
+ Returns:
+
+
Modified: trunk/doc/C/tmpl/gda-server-provider.sgml
==============================================================================
--- trunk/doc/C/tmpl/gda-server-provider.sgml (original)
+++ trunk/doc/C/tmpl/gda-server-provider.sgml Wed Mar 12 21:18:24 2008
@@ -91,18 +91,18 @@
for more information.
</para>
- info:
- btypes:
+ _info:
+ _btypes:
+ _schemata:
@schemata:
+ _tables_views:
@tables_views:
- tables_views_s:
+ _columns:
@columns:
- columns_t:
- columns_c:
+ _constraints_tab:
@constraints_tab:
- constraints_tab_s:
+ _constraints_ref:
@constraints_ref:
- constraints_ref_c:
<!-- ##### USER_FUNCTION GdaServerProviderAsyncCallback ##### -->
<para>
Modified: trunk/libgda/gda-batch.c
==============================================================================
--- trunk/libgda/gda-batch.c (original)
+++ trunk/libgda/gda-batch.c Wed Mar 12 21:18:24 2008
@@ -150,7 +150,7 @@
/**
- * gda_batch_copy
+ * gda_batch_new_copy
* @orig: a #GdaBatch to make a copy of
*
* Copy constructor
@@ -158,7 +158,7 @@
* Returns: a the new copy of @orig
*/
GdaBatch *
-gda_batch_copy (GdaBatch *orig)
+gda_batch_new_copy (GdaBatch *orig)
{
GObject *obj;
GdaBatch *batch;
Modified: trunk/libgda/gda-config.c
==============================================================================
--- trunk/libgda/gda-config.c (original)
+++ trunk/libgda/gda-config.c Wed Mar 12 21:18:24 2008
@@ -724,7 +724,7 @@
/**
* gda_config_remove_dsn
- * @info: a pointer to a filled GdaDataSourceInfo structure
+ * @dsn_name: the name of the DSN to remove
* @error: a place to store errors, or %NULL
*
* Add or update a DSN from the definition in @info
Modified: trunk/libgda/gda-connection.c
==============================================================================
--- trunk/libgda/gda-connection.c (original)
+++ trunk/libgda/gda-connection.c Wed Mar 12 21:18:24 2008
@@ -1754,12 +1754,15 @@
#ifdef GDA_DEBUG
#define ASSERT_TABLE_NAME(x,y) g_assert (!strcmp ((x), (y)))
#define WARN_METHOD_NOT_IMPLEMENTED(prov,method) g_warning ("Provider '%s' does not implement the META method '%s()', please report the error to bugzilla.gnome.org", gda_server_provider_get_name (prov), (method))
+#define WARN_META_UPDATE_FAILURE(x,method) if (!(x)) g_print ("%s (meta method => %s) ERROR: %s\n", __FUNCTION__, (method), error && *error && (*error)->message ? (*error)->message : "???")
#else
#define ASSERT_TABLE_NAME(x,y)
#define WARN_METHOD_NOT_IMPLEMENTED(prov,method)
+#define WARN_META_UPDATE_FAILURE(x,method)
#endif
const gchar *tname = context->table_name;
GdaMetaStore *store;
+ gboolean retval;
if (*tname != '_')
return TRUE;
@@ -1772,67 +1775,61 @@
* - none
*/
ASSERT_TABLE_NAME (tname, "builtin_data_types");
- if (!PROV_CLASS (provider)->meta_funcs.btypes) {
- WARN_METHOD_NOT_IMPLEMENTED (provider, "btypes");
+ if (!PROV_CLASS (provider)->meta_funcs._btypes) {
+ WARN_METHOD_NOT_IMPLEMENTED (provider, "_btypes");
break;
}
- return PROV_CLASS (provider)->meta_funcs.btypes (provider, cnc, store, context, error);
+ retval = PROV_CLASS (provider)->meta_funcs._btypes (provider, cnc, store, context, error);
+ WARN_META_UPDATE_FAILURE (retval, "_btypes");
+ return retval;
}
case 'i':
/* _information_schema_catalog_name, params:
* - none
*/
ASSERT_TABLE_NAME (tname, "information_schema_catalog_name");
- if (!PROV_CLASS (provider)->meta_funcs.info) {
- WARN_METHOD_NOT_IMPLEMENTED (provider, "info");
+ if (!PROV_CLASS (provider)->meta_funcs._info) {
+ WARN_METHOD_NOT_IMPLEMENTED (provider, "_info");
break;
}
- return PROV_CLASS (provider)->meta_funcs.info (provider, cnc, store, context, error);
+ retval = PROV_CLASS (provider)->meta_funcs._info (provider, cnc, store, context, error);
+ WARN_META_UPDATE_FAILURE (retval, "_info");
+ return retval;
case 'c':
if ((tname[1] == 'o') && (tname[2] == 'l') && (tname[3] == 'u')) {
/* _columns, params:
- * - none
- * - @table_schema AND @table_name
- * - @table_schema AND @table_name AND @column_name
+ * -0- @table_catalog, @table_schema, @table_name
+ * -1- @character_set_catalog, @character_set_schema, @character_set_name
+ * -2- @collation_catalog, @collation_schema, @collation_name
*/
- const GValue *p_table_schema = NULL;
- const GValue *p_table_name = NULL;
- const GValue *p_column_name = NULL;
-
- if (check_parameters (context, error, 3,
- &p_table_schema, G_TYPE_STRING,
- &p_table_name, G_TYPE_STRING,
- &p_column_name, G_TYPE_STRING, NULL,
- "table_schema", &p_table_schema, "table_name", &p_table_name, "column_name", &p_column_name, NULL,
- "table_schema", &p_table_schema, "table_name", &p_table_name, NULL,
- NULL) < 0)
+ const GValue *catalog = NULL;
+ const GValue *schema = NULL;
+ const GValue *name = NULL;
+ gint i;
+ i = check_parameters (context, error, 3,
+ &catalog, G_TYPE_STRING,
+ &schema, G_TYPE_STRING,
+ &name, G_TYPE_STRING, NULL,
+ "table_catalog", &catalog, "table_schema", &schema, "table_name", &name, NULL,
+ "character_set_catalog", &catalog, "character_set_schema", &schema, "character_set_name", &name, NULL,
+ "collation_catalog", &catalog, "collation_schema", &schema, "collation_name", &name, NULL);
+ if (i < 0)
return FALSE;
ASSERT_TABLE_NAME (tname, "columns");
- if (p_table_schema) {
- if (p_column_name) {
- if (!PROV_CLASS (provider)->meta_funcs.columns_c) {
- WARN_METHOD_NOT_IMPLEMENTED (provider, "columns_c");
- break;
- }
- return PROV_CLASS (provider)->meta_funcs.columns_c (provider, cnc, store, context, error,
- p_table_schema, p_table_name, p_column_name);
- }
- else {
- if (!PROV_CLASS (provider)->meta_funcs.columns_t) {
- WARN_METHOD_NOT_IMPLEMENTED (provider, "columns_t");
- break;
- }
- return PROV_CLASS (provider)->meta_funcs.columns_t (provider, cnc, store, context, error,
- p_table_schema, p_table_name);
- }
- }
- else {
+ if (i == 0) {
if (!PROV_CLASS (provider)->meta_funcs.columns) {
WARN_METHOD_NOT_IMPLEMENTED (provider, "columns");
break;
}
- return PROV_CLASS (provider)->meta_funcs.columns (provider, cnc, store, context, error);
+ retval = PROV_CLASS (provider)->meta_funcs.columns (provider, cnc, store, context, error,
+ catalog, schema, name);
+ WARN_META_UPDATE_FAILURE (retval, "columns");
+ return retval;
+ }
+ else {
+ /* nothing to do */
+ return TRUE;
}
}
break;
@@ -1840,120 +1837,127 @@
case 'r':
if ((tname[1] == 'e') && (tname[2] == 'f')) {
/* _referential_constraints, params:
- * - none
- * - @constraint_schema AND @constraint_name
+ * -0- @table_catalog, @table_schema, @table_name, @constraint_name
+ * -0- @ref_table_catalog, @ref_table_schema, @ref_table_name, @ref_constraint_name
*/
- const GValue *p_constraint_schema = NULL;
- const GValue *p_constraint_name = NULL;
- if (check_parameters (context, error, 3,
- &p_constraint_schema, G_TYPE_STRING,
- &p_constraint_name, G_TYPE_STRING, NULL,
- "constraint_schema", &p_constraint_schema, "constraint_name", &p_constraint_name, NULL,
- NULL) < 0)
+ const GValue *catalog = NULL;
+ const GValue *schema = NULL;
+ const GValue *tabname = NULL;
+ const GValue *cname = NULL;
+ gint i;
+ i = check_parameters (context, error, 2,
+ &catalog, G_TYPE_STRING,
+ &schema, G_TYPE_STRING,
+ &tabname, G_TYPE_STRING,
+ &cname, G_TYPE_STRING, NULL,
+ "table_catalog", &catalog, "table_schema", &schema, "table_name", &tabname, "constraint_name", &cname, NULL,
+ "ref_table_catalog", &catalog, "ref_table_schema", &schema, "ref_table_name", &tabname, "ref_constraint_name", &cname, NULL);
+ if (i < 0)
return FALSE;
ASSERT_TABLE_NAME (tname, "referential_constraints");
- if (p_constraint_schema) {
- if (!PROV_CLASS (provider)->meta_funcs.constraints_ref_c) {
- WARN_METHOD_NOT_IMPLEMENTED (provider, "constraints_ref_c");
- break;
- }
- return PROV_CLASS (provider)->meta_funcs.constraints_ref_c (provider, cnc, store, context, error,
- p_constraint_schema, p_constraint_name);
- }
- else {
+ if (i == 0) {
if (!PROV_CLASS (provider)->meta_funcs.constraints_ref) {
WARN_METHOD_NOT_IMPLEMENTED (provider, "constraints_ref");
break;
}
- return PROV_CLASS (provider)->meta_funcs.constraints_ref (provider, cnc, store, context, error);
+ retval = PROV_CLASS (provider)->meta_funcs.constraints_ref (provider, cnc, store, context, error,
+ catalog, schema, tabname, cname);
+ WARN_META_UPDATE_FAILURE (retval, "constraints_ref");
+ return retval;
+ }
+ else {
+ /* nothing to do */
+ return TRUE;
}
}
break;
case 's': {
- /* _schemata, params:
- * - none
- * - @schema_name
+ /* _schemata, params:
+ * -0- @catalog_name, @schema_name
+ * -1- @catalog_name
*/
- GValue *p_schema_name = NULL;
- if (check_parameters (context, error, 2,
- &p_schema_name, G_TYPE_STRING, NULL,
- "schema_name", &p_schema_name, NULL,
- NULL) < 0)
+ GValue *catalog = NULL;
+ GValue *schema = NULL;
+ gint i;
+ i = check_parameters (context, error, 2,
+ &schema, G_TYPE_STRING, NULL,
+ "catalog_name", &catalog, "schema_name", &schema, NULL,
+ "catalog_name", &catalog, NULL);
+ if (i < 0)
return FALSE;
ASSERT_TABLE_NAME (tname, "schemata");
+
if (!PROV_CLASS (provider)->meta_funcs.schemata) {
WARN_METHOD_NOT_IMPLEMENTED (provider, "schemata");
break;
}
- return PROV_CLASS (provider)->meta_funcs.schemata (provider, cnc, store, context, error, p_schema_name);
+ retval = PROV_CLASS (provider)->meta_funcs.schemata (provider, cnc, store, context, error,
+ catalog, schema);
+ WARN_META_UPDATE_FAILURE (retval, "schemata");
+ return retval;
}
case 't':
if ((tname[1] == 'a') && (tname[2] == 'b') && (tname[3] == 'l') && (tname[4] == 'e') && (tname[5] == 's')) {
/* _tables, params:
- * - none
- * - @table_schema
- * - @table_schema AND @table_name
+ * -0- @table_catalog, @table_schema, @table_name
+ * -1- @table_catalog, @table_schema
*/
- const GValue *p_table_schema = NULL;
- const GValue *p_table_name = NULL;
- if (check_parameters (context, error, 3,
- &p_table_schema, G_TYPE_STRING,
- &p_table_name, G_TYPE_STRING, NULL,
- "table_schema", &p_table_schema, "table_name", &p_table_name, NULL,
- "table_schema", &p_table_schema, NULL,
- NULL) < 0)
+ const GValue *catalog = NULL;
+ const GValue *schema = NULL;
+ const GValue *name = NULL;
+ gint i;
+ i = check_parameters (context, error, 2,
+ &catalog, G_TYPE_STRING,
+ &schema, G_TYPE_STRING,
+ &name, G_TYPE_STRING, NULL,
+ "table_catalog", &catalog, "table_schema", &schema, "table_name", &name, NULL,
+ "table_catalog", &catalog, "table_schema", &schema, NULL);
+ if (i < 0)
return FALSE;
ASSERT_TABLE_NAME (tname, "tables");
- if (p_table_schema) {
- if (!PROV_CLASS (provider)->meta_funcs.tables_views_s) {
- WARN_METHOD_NOT_IMPLEMENTED (provider, "tables_views_s");
- break;
- }
- return PROV_CLASS (provider)->meta_funcs.tables_views_s (provider, cnc, store, context, error,
- p_table_schema, p_table_name);
- }
- else {
- if (!PROV_CLASS (provider)->meta_funcs.tables_views) {
- WARN_METHOD_NOT_IMPLEMENTED (provider, "tables_views");
- break;
- }
- return PROV_CLASS (provider)->meta_funcs.tables_views (provider, cnc, store, context, error);
+ if (!PROV_CLASS (provider)->meta_funcs.tables_views) {
+ WARN_METHOD_NOT_IMPLEMENTED (provider, "tables_views");
+ break;
}
+ retval = PROV_CLASS (provider)->meta_funcs.tables_views (provider, cnc, store, context, error,
+ catalog, schema, name);
+ WARN_META_UPDATE_FAILURE (retval, "tables_views");
+ return retval;
}
else if ((tname[1] == 'a') && (tname[2] == 'b') && (tname[3] == 'l') && (tname[4] == 'e') &&
(tname[5] == '_') && (tname[6] == 'c')) {
/* _tables_constraints, params:
- * - none
- * - @table_schema AND @table_name
+ * -0- @table_catalog, @table_schema, @table_name, @constraint_name
+ * -1- @table_catalog, @table_schema, @table_name
*/
- const GValue *p_table_schema = NULL;
- const GValue *p_table_name = NULL;
- if (check_parameters (context, error, 3,
- &p_table_schema, G_TYPE_STRING,
- &p_table_name, G_TYPE_STRING, NULL,
- "table_schema", &p_table_schema, "table_name", &p_table_name, NULL,
- NULL) < 0)
+ const GValue *catalog = NULL;
+ const GValue *schema = NULL;
+ const GValue *tabname = NULL;
+ const GValue *cname = NULL;
+ gint i;
+ i = check_parameters (context, error, 2,
+ &catalog, G_TYPE_STRING,
+ &schema, G_TYPE_STRING,
+ &cname, G_TYPE_STRING,
+ &tabname, G_TYPE_STRING, NULL,
+ "table_catalog", &catalog, "table_schema", &schema, "table_name", &tabname, "constraint_name", &cname, NULL,
+ "table_catalog", &catalog, "table_schema", &schema, "table_name", &tabname, NULL);
+
+ if (i < 0)
return FALSE;
ASSERT_TABLE_NAME (tname, "table_constraints");
- if (p_table_schema) {
- if (!PROV_CLASS (provider)->meta_funcs.constraints_tab_s) {
- WARN_METHOD_NOT_IMPLEMENTED (provider, "constraints_tab_s");
- break;
- }
- return PROV_CLASS (provider)->meta_funcs.constraints_tab_s (provider, cnc, store, context, error,
- p_table_schema, p_table_name);
- }
- else {
- if (!PROV_CLASS (provider)->meta_funcs.constraints_tab) {
- WARN_METHOD_NOT_IMPLEMENTED (provider, "constraints_tab");
- break;
- }
- return PROV_CLASS (provider)->meta_funcs.constraints_tab (provider, cnc, store, context, error);
+ if (!PROV_CLASS (provider)->meta_funcs.constraints_tab) {
+ WARN_METHOD_NOT_IMPLEMENTED (provider, "constraints_tab");
+ break;
}
+ retval = PROV_CLASS (provider)->meta_funcs.constraints_tab (provider, cnc, store, context, error,
+ catalog, schema, tabname, cname);
+ WARN_META_UPDATE_FAILURE (retval, "constraints_tab");
+ return retval;
}
break;
default:
@@ -1969,15 +1973,26 @@
gboolean error_set;
} DetailledCallbackData;
-static void
+static GError *
suggest_update_cb_detailled (GdaMetaStore *store, GdaMetaContext *suggest, DetailledCallbackData *data)
{
- if (data->error_set)
- return;
- if (!local_meta_update (data->prov, data->cnc, suggest, data->error))
+ if (data->error && *(data->error))
+ return *(data->error);
+
+ if (!local_meta_update (data->prov, data->cnc, suggest, data->error)) {
data->error_set = TRUE;
+
+ if (! (*(data->error)))
+ g_set_error (data->error, 0, 0,
+ _("Meta update error"));
+
+ return *(data->error);
+ }
+ return NULL;
}
+static gboolean gda_connection_update_meta_clean_first = TRUE;
+
/**
* gda_connection_update_meta_store
* @cnc: a #GdaConnection object.
@@ -2003,48 +2018,48 @@
g_assert (store);
/* prepare local context */
- if (!context) {
- GSList *tables, *list;
- tables = gda_meta_store_get_schema_tables (store);
- for (list = tables; list; list = list->next) {
- GdaMetaContext lcontext;
- memset (&lcontext, 0, sizeof (GdaMetaContext));
- lcontext.table_name = (gchar *) list->data;
- if (!local_meta_update (cnc->priv->provider_obj, cnc, &lcontext, error)) {
- retval = FALSE;
- break;
- }
- }
- g_slist_free (tables);
- }
- else {
- GdaMetaContext lcontext;
+ GdaMetaContext lcontext;
+ if (context) {
lcontext = *context;
/* alter local context because "_tables" and "_views" always go together so only
"_tables" should be updated and providers should always update "_tables" and "_views"
*/
if (!strcmp (lcontext.table_name, "_views"))
lcontext.table_name = "_tables";
-
- /* actual update */
- gulong signal_id;
- DetailledCallbackData cbd;
- GError *lerror = NULL;
-
- cbd.prov = cnc->priv->provider_obj;
- cbd.cnc = cnc;
- cbd.error = &lerror;
- cbd.error_set = FALSE;
- signal_id = g_signal_connect (store, "suggest_update",
- G_CALLBACK (suggest_update_cb_detailled), &cbd);
-
- retval = local_meta_update (cnc->priv->provider_obj, cnc, &lcontext, error);
-
- g_signal_handler_disconnect (store, signal_id);
- if (cbd.error_set) {
+ }
+ else {
+ memset (&lcontext, 0, sizeof (GdaMetaContext));
+ lcontext.table_name = "_builtin_data_types";
+ if (!gda_connection_update_meta_store (cnc, &lcontext, error))
+ return FALSE;
+ lcontext.table_name = "_udt";
+ if (!gda_connection_update_meta_store (cnc, &lcontext, error))
+ return FALSE;
+ lcontext.table_name = "_information_schema_catalog_name";
+ if (!gda_connection_update_meta_store (cnc, &lcontext, error))
+ return FALSE;
+ return TRUE;
+ }
+
+ /* actual update */
+ gulong signal_id;
+ DetailledCallbackData cbd;
+ GError *lerror = NULL;
+
+ cbd.prov = cnc->priv->provider_obj;
+ cbd.cnc = cnc;
+ cbd.error = &lerror;
+ cbd.error_set = FALSE;
+ signal_id = g_signal_connect (store, "suggest_update",
+ G_CALLBACK (suggest_update_cb_detailled), &cbd);
+
+ retval = local_meta_update (cnc->priv->provider_obj, cnc, &lcontext, NULL);
+
+ g_signal_handler_disconnect (store, signal_id);
+ if (cbd.error_set) {
+ if (lerror)
g_propagate_error (error, lerror);
- retval = FALSE;
- }
+ retval = FALSE;
}
return retval;
Modified: trunk/libgda/gda-connection.h
==============================================================================
--- trunk/libgda/gda-connection.h (original)
+++ trunk/libgda/gda-connection.h Wed Mar 12 21:18:24 2008
@@ -194,6 +194,7 @@
gchar *gda_connection_value_to_sql_string (GdaConnection *cnc, GValue *from);
gboolean gda_connection_supports_feature (GdaConnection *cnc, GdaConnectionFeature feature);
+GdaMetaStore *gda_connection_get_meta_store (GdaConnection *cnc);
gboolean gda_connection_update_meta_store (GdaConnection *cnc, GdaMetaContext *context, GError **error);
GdaDataModel *gda_connection_get_meta_store_data (GdaConnection *cnc, GdaConnectionMetaType meta_type,
GError **error, gint nb_filters, ...);
Modified: trunk/libgda/gda-data-model-import.c
==============================================================================
--- trunk/libgda/gda-data-model-import.c (original)
+++ trunk/libgda/gda-data-model-import.c Wed Mar 12 21:18:24 2008
@@ -1186,7 +1186,7 @@
xmlFree (str);
}
str = (gchar*)xmlTextReaderGetAttribute (reader, (xmlChar*)"nullok");
- spec->nullok = TRUE;
+ spec->nullok = FALSE;
if (str) {
spec->nullok = ((*str == 't') || (*str == 'T')) ? TRUE : FALSE;
xmlFree (str);
Modified: trunk/libgda/gda-data-model.c
==============================================================================
--- trunk/libgda/gda-data-model.c (original)
+++ trunk/libgda/gda-data-model.c Wed Mar 12 21:18:24 2008
@@ -1548,26 +1548,21 @@
break;
}
+ gboolean nullforced = FALSE;
isnull = (gchar*)xmlGetProp (xml_field, BAD_CAST "isnull");
if (isnull) {
- if ((*isnull == 'f') || (*isnull == 'F')) {
- g_free (isnull);
- isnull = NULL;
- }
+ if ((*isnull == 't') || (*isnull == 't'))
+ nullforced = TRUE;
+ g_free (isnull);
}
- if (!isnull) {
+ if (!nullforced) {
value = g_new0 (GValue, 1);
if (!gda_value_set_from_string (value, (gchar*)xmlNodeGetContent (xml_field), gdatype)) {
g_free (value);
- g_set_error (error, 0, 0, _("Cannot interpret string as a valid %s value"),
- gda_g_type_to_string (gdatype));
- retval = FALSE;
- break;
+ value = gda_value_new_null ();
}
}
- else
- g_free (isnull);
g_ptr_array_index (values, pos) = value;
if (this_lang)
Modified: trunk/libgda/gda-decl.h
==============================================================================
--- trunk/libgda/gda-decl.h (original)
+++ trunk/libgda/gda-decl.h Wed Mar 12 21:18:24 2008
@@ -98,6 +98,19 @@
typedef struct _GdaSqlParserPrivate GdaSqlParserPrivate;
/*
+ * Meta data
+ */
+typedef struct _GdaMetaStore GdaMetaStore;
+typedef struct _GdaMetaStoreClass GdaMetaStoreClass;
+typedef struct _GdaMetaStorePrivate GdaMetaStorePrivate;
+typedef struct _GdaMetaStoreClassPrivate GdaMetaStoreClassPrivate;
+
+typedef struct _GdaMetaStruct GdaMetaStruct;
+typedef struct _GdaMetaStructClass GdaMetaStructClass;
+typedef struct _GdaMetaStructPrivate GdaMetaStructPrivate;
+
+
+/*
* Win32 adaptations
*/
#ifdef G_OS_WIN32
Modified: trunk/libgda/gda-easy.c
==============================================================================
--- trunk/libgda/gda-easy.c (original)
+++ trunk/libgda/gda-easy.c Wed Mar 12 21:18:24 2008
@@ -373,16 +373,11 @@
if (!gda_server_operation_load_data_from_xml (op, root, error)) {
/* error */
- g_object_unref (op);
- xmlFreeDoc(parameters);
retval = FALSE;
}
- else {
- if (gda_server_provider_perform_operation (server, cnc, op, error))
- /* error */
- g_object_unref (op);
- xmlFreeDoc(parameters);
- return FALSE;
+ else if (!gda_server_provider_perform_operation (server, cnc, op, error)) {
+ /* error */
+ retval = FALSE;
}
g_object_unref (op);
xmlFreeDoc(parameters);
Modified: trunk/libgda/gda-marshal.list
==============================================================================
--- trunk/libgda/gda-marshal.list (original)
+++ trunk/libgda/gda-marshal.list Wed Mar 12 21:18:24 2008
@@ -40,3 +40,4 @@
VOID:ENUM,POINTER
BOOLEAN:INT
BOOLEAN:INT,INT
+POINTER:POINTER
Modified: trunk/libgda/gda-meta-store.c
==============================================================================
--- trunk/libgda/gda-meta-store.c (original)
+++ trunk/libgda/gda-meta-store.c Wed Mar 12 21:18:24 2008
@@ -35,6 +35,8 @@
#include <libxml/parser.h>
#include <libxml/tree.h>
#include <libgda/gda-util.h>
+#include <libgda/gda-meta-struct.h>
+#include <libgda/gda-connection.h>
/*
* Main static functions
@@ -63,7 +65,8 @@
enum {
STMT_GET_VERSION,
STMT_SET_VERSION,
-
+ STMT_DEL_ATT_VALUE,
+ STMT_SET_ATT_VALUE,
STMT_LAST
} PreStmtType;
@@ -191,6 +194,9 @@
GdaConnection *cnc;
gint version;
gboolean schema_ok;
+
+ GSList *custom_db_objects; /* list of DbObject structures */
+ GHashTable *custom_db_objects_hash; /* key = table name, value = a DbObject structure */
};
static void db_object_free (DbObject *dbobj);
@@ -281,19 +287,50 @@
return TRUE;
}
+static gboolean
+suggest_update_accumulator (GSignalInvocationHint *ihint,
+ GValue *return_accu,
+ const GValue *handler_return,
+ gpointer data)
+{
+ GError *error;
+
+ error = g_value_get_pointer (handler_return);
+ g_value_set_pointer (return_accu, error);
+
+ return error ? FALSE : TRUE; /* stop signal if 'thisvalue' is FALSE */
+}
+
+static GError *
+m_suggest_update (GdaMetaStore *store, GdaMetaContext *suggest)
+{
+ return NULL; /* defaults allows update suggest */
+}
+
static void
gda_meta_store_class_init (GdaMetaStoreClass *klass) {
GObjectClass *object_class = G_OBJECT_CLASS (klass);
parent_class = g_type_class_peek_parent (klass);
+ /**
+ * GdaMetaStore::suggest-update:
+ * @store: the #GdaMetaStore instance that emitted the signal
+ * @suggest: the suggested update, as a #GdaMetaContext structure
+ *
+ * This signal is emitted when the contents of a table should be updated (data updated or inserted;
+ * deleting data is done automatically).
+ *
+ * Returns: a new #GError error structure if there was an error when processing the
+ * signal, or %NULL if signal propagation should continue
+ **/
gda_meta_store_signals[SUGGEST_UPDATE] =
g_signal_new ("suggest_update",
G_TYPE_FROM_CLASS (object_class),
- G_SIGNAL_RUN_FIRST,
+ G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GdaMetaStoreClass, suggest_update),
- NULL, NULL,
- gda_marshal_VOID__POINTER, G_TYPE_NONE,
+ suggest_update_accumulator, NULL,
+ gda_marshal_POINTER__POINTER, G_TYPE_POINTER,
1, G_TYPE_POINTER);
gda_meta_store_signals[META_CHANGED] =
g_signal_new ("meta_changed",
@@ -304,7 +341,7 @@
gda_marshal_VOID__POINTER, G_TYPE_NONE,
1, G_TYPE_POINTER);
- klass->suggest_update = NULL;
+ klass->suggest_update = m_suggest_update;
klass->meta_changed = NULL;
/* Properties */
@@ -337,7 +374,14 @@
klass->cpriv->prep_stmts[STMT_GET_VERSION] =
compute_prepared_stmt (klass->cpriv->parser,
"SELECT att_value FROM _attributes WHERE att_name='_schema_version'");
+ klass->cpriv->prep_stmts[STMT_DEL_ATT_VALUE] =
+ compute_prepared_stmt (klass->cpriv->parser,
+ "DELETE FROM _attributes WHERE att_name = ##name::string");
+ klass->cpriv->prep_stmts[STMT_SET_ATT_VALUE] =
+ compute_prepared_stmt (klass->cpriv->parser,
+ "INSERT INTO _attributes VALUES (##name::string, ##value::string::null)");
+/*#define GDA_DEBUG_GRAPH*/
#ifdef GDA_DEBUG_GRAPH
#define INFORMATION_SCHEMA_GRAPH_FILE "information_schema.dot"
GString *string;
@@ -353,7 +397,7 @@
g_string_append_printf (string, "%s [ shape = ellipse ];\n", dbo->obj_name);
break;
default:
- g_string_append_printf (string, "%s [ shape = diamond ];\n", dbo->obj_name);
+ g_string_append_printf (string, "%s [ shape = note ];\n", dbo->obj_name);
break;
}
@@ -385,6 +429,9 @@
store->priv->cnc = NULL;
store->priv->schema_ok = FALSE;
store->priv->version = 0;
+
+ store->priv->custom_db_objects = NULL;
+ store->priv->custom_db_objects_hash = g_hash_table_new (g_str_hash, g_str_equal);
}
static GObject *
@@ -496,6 +543,11 @@
store = GDA_META_STORE (object);
if (store->priv) {
+ /* custom db objects */
+ g_hash_table_destroy (store->priv->custom_db_objects_hash);
+ g_slist_foreach (store->priv->custom_db_objects, (GFunc) db_object_free, NULL);
+ g_slist_free (store->priv->custom_db_objects);
+
/* internal connection */
if (store->priv->cnc) {
g_object_unref (G_OBJECT (store->priv->cnc));
@@ -723,15 +775,25 @@
if (! gda_server_operation_set_value_at (op, repl ? repl : "string", error,
"/FIELDS_A/@COLUMN_TYPE/%d", index))
goto onerror;
+ if (! gda_server_operation_set_value_at (op, NULL, error,
+ "/FIELDS_A/@COLUMN_SIZE/%d", index))
+ goto onerror;
if (! gda_server_operation_set_value_at (op, tcol->nullok ? "FALSE" : "TRUE", error,
"/FIELDS_A/@COLUMN_NNUL/%d", index))
goto onerror;
- repl = provider_specific_match (specific_hash, prov, NULL, "/FIELDS_A/@COLUMN_PKEY");
+ if (! gda_server_operation_set_value_at (op, "FALSE", error,
+ "/FIELDS_A/@COLUMN_AUTOINC/%d", index))
+ goto onerror;
+ repl = provider_specific_match (specific_hash, prov, "dummy", "/FIELDS_A/@COLUMN_PKEY");
if (repl) {
if (! gda_server_operation_set_value_at (op, tcol->pkey ? "TRUE" : "FALSE", error,
"/FIELDS_A/@COLUMN_PKEY/%d", index))
goto onerror;
}
+ else {
+ if (! gda_server_operation_set_value_at (op, "FALSE", error, "/FIELDS_A/@COLUMN_PKEY/%d", index))
+ goto onerror;
+ }
}
/* foreign keys */
@@ -1762,7 +1824,7 @@
const gchar *table_name, const gchar *condition, GError **error,
gint nvalues, const gchar **value_names, const GValue **values);
static gint find_row_in_model (GdaDataModel *find_in, GdaDataModel *data, gint row,
- gint *pk_cols, gint pk_cols_nb, GError **error);
+ gint *pk_cols, gint pk_cols_nb, gboolean *out_has_changed, GError **error);
static gboolean gda_meta_store_modify_v (GdaMetaStore *store, const gchar *table_name,
GdaDataModel *new_data, const gchar *condition, GError **error,
gint nvalues, const gchar **value_names, const GValue **values);
@@ -1864,7 +1926,7 @@
return retval;
}
-
+/*#define DEBUG_STORE_MODIFY*/
static gboolean
gda_meta_store_modify_v (GdaMetaStore *store, const gchar *table_name,
GdaDataModel *new_data, const gchar *condition, GError **error,
@@ -1906,7 +1968,7 @@
current_n_cols = gda_data_model_get_n_columns (current);
rows_to_del = g_new (gboolean, current_n_rows);
memset (rows_to_del, TRUE, sizeof (gboolean) * current_n_rows);
-#ifdef GDA_DEBUG_NO
+#ifdef DEBUG_STORE_MODIFY
g_print ("CURRENT:\n");
gda_data_model_dump (current, stdout);
#endif
@@ -1916,7 +1978,9 @@
started_transaction = gda_connection_begin_transaction (store->priv->cnc, NULL,
GDA_TRANSACTION_ISOLATION_UNKNOWN,
NULL);
+#ifdef DEBUG_STORE_MODIFY
g_print ("------- BEGIN\n");
+#endif
}
/* treat rows to insert / update */
@@ -1924,7 +1988,7 @@
gint new_n_rows, new_n_cols;
new_n_rows = gda_data_model_get_n_rows (new_data);
new_n_cols = gda_data_model_get_n_columns (new_data);
-#ifdef GDA_DEBUG_NO
+#ifdef DEBUG_STORE_MODIFY
g_print ("NEW:\n");
gda_data_model_dump (new_data, stdout);
#endif
@@ -1932,12 +1996,16 @@
for (i = 0; i < new_n_rows; i++) {
/* find existing row if necessary */
gint erow = -1;
- if (current)
+ gboolean has_changed = FALSE;
+ if (current) {
erow = find_row_in_model (current, new_data, i,
- schema_set->pk_cols_array, schema_set->pk_cols_nb, error);
- if (erow == -3)
- /* nothing to do */
- continue;
+ schema_set->pk_cols_array, schema_set->pk_cols_nb, &has_changed,
+ error);
+#ifdef DEBUG_STORE_MODIFY
+ g_print ("FIND row %d(/%d) returned row %d (%s)\n", i, new_n_rows - 1, erow,
+ has_changed ? "CHANGED" : "unchanged");
+#endif
+ }
if (erow < -1) {
retval = FALSE;
goto out;
@@ -1973,8 +2041,8 @@
/* execute INSERT or UPDATE statements */
if (erow == -1) {
/* INSERT: bind INSERT parameters */
-#ifdef GDA_DEBUG_NO
- g_print ("Insert for new row %d...\n", i);
+#ifdef DEBUG_STORE_MODIFY
+ g_print ("Insert new row %d into table %s\n", i, table_name);
#endif
if (gda_connection_statement_execute_non_select (store->priv->cnc,
schema_set->insert, schema_set->params,
@@ -1985,7 +2053,7 @@
if (change)
change->c_type = GDA_META_STORE_ADD;
}
- else {
+ else if (has_changed) {
/* also bind parameters with existing values */
for (j = 0; j < current_n_cols; j++) {
gchar *pid = g_strdup_printf ("-%d", j);
@@ -2003,8 +2071,8 @@
g_free (pid);
}
/* UPDATE */
-#ifdef GDA_DEBUG_NO
- g_print ("Update for new row %d (old row was %d)...\n", i, erow);
+#ifdef DEBUG_STORE_MODIFY
+ g_print ("Update for row %d (old row was %d) into table %s\n", i, erow, table_name);
#endif
if (gda_connection_statement_execute_non_select (store->priv->cnc,
schema_set->update, schema_set->params,
@@ -2016,6 +2084,9 @@
change->c_type = GDA_META_STORE_MODIFY;
rows_to_del [erow] = FALSE;
}
+ else
+ /* row has not changed */
+ rows_to_del [erow] = FALSE;
/* Dependencies update: reverse_fk_list */
GSList *list;
@@ -2032,7 +2103,7 @@
for (k = 0; k < tfk->cols_nb; k++)
context.column_values [k] = (GValue*) gda_data_model_get_value_at (new_data,
tfk->ref_pk_cols_array[k], i);
-#ifdef GDA_DEBUG
+#ifdef DEBUG_STORE_MODIFY
g_print ("Suggest update data into table '%s':", tfk->table_info->obj_name);
for (k = 0; k < tfk->cols_nb; k++) {
gchar *str;
@@ -2042,8 +2113,19 @@
}
g_print ("\n");
#endif
- g_signal_emit (store, gda_meta_store_signals[SUGGEST_UPDATE], 0, &context);
+ GError *suggest_reports_error = NULL;
+ g_signal_emit (store, gda_meta_store_signals[SUGGEST_UPDATE], 0, &context,
+ &suggest_reports_error);
g_free (context.column_values);
+ if (suggest_reports_error) {
+ /*g_print ("SUGGEST META UPDATE Returned FALSE: %s\n",
+ suggest_reports_error && suggest_reports_error->message ?
+ suggest_reports_error->message : "???");*/
+ retval = FALSE;
+ if (error && !(*error))
+ g_propagate_error (error, suggest_reports_error);
+ goto out;
+ }
}
}
}
@@ -2077,8 +2159,8 @@
}
g_free (pid);
}
-#ifdef GDA_DEBUG_NO
- g_print ("Delete for existing row %d...\n", i);
+#ifdef DEBUG_STORE_MODIFY
+ g_print ("Delete existing row %d from table %s\n", i, table_name);
#endif
/* reverse_fk_list */
GSList *list;
@@ -2112,7 +2194,9 @@
if (retval && started_transaction) {
retval = gda_connection_commit_transaction (store->priv->cnc, NULL, NULL);
+#ifdef DEBUG_STORE_MODIFY
g_print ("------- COMMIT\n");
+#endif
}
if (retval && all_changes)
g_signal_emit (store, gda_meta_store_signals[META_CHANGED], 0, all_changes);
@@ -2127,7 +2211,9 @@
g_object_unref (current);
if (!retval && started_transaction) {
gda_connection_rollback_transaction (store->priv->cnc, NULL, NULL);
+#ifdef DEBUG_STORE_MODIFY
g_print ("------- ROLLBACK\n");
+#endif
}
return retval;
}
@@ -2136,13 +2222,14 @@
* Find the row in @find_in from the values of @data at line @row, and columns pointed by
* the values of @pk_cols
*
- * Returns: -3 if found and no change need to be made,
+ * Returns:
* -2 on error,
* -1 if not found,
- * >0 if found and changes need to be made
+ * >=0 if found (if changes need to be made, then @out_has_changed is set to TRUE).
*/
static gint
-find_row_in_model (GdaDataModel *find_in, GdaDataModel *data, gint row, gint *pk_cols, gint pk_cols_nb, GError **error) {
+find_row_in_model (GdaDataModel *find_in, GdaDataModel *data, gint row, gint *pk_cols, gint pk_cols_nb,
+ gboolean *out_has_changed, GError **error) {
gint i, erow;
GSList *values = NULL;
@@ -2165,27 +2252,12 @@
const GValue *v1, *v2;
v1 = gda_data_model_get_value_at (find_in, i, erow);
v2 = gda_data_model_get_value_at (data, i, row);
- if (((!v1 || gda_value_is_null (v1)) && v2) ||
- (v1 && (!v2 || gda_value_is_null (v2)))) {
+ if (gda_value_compare_ext (v1, v2)) {
changed = TRUE;
break;
}
- else if (v1 && v2) {
- if (G_VALUE_TYPE (v1) != G_VALUE_TYPE (v2)) {
- g_set_error (error, GDA_META_STORE_ERROR, GDA_META_STORE_MODIFY_CONTENTS_ERROR,
- _("Data types differ for column %d (expected type '%s' and got '%s')"),
- i, g_type_name (G_VALUE_TYPE (v1)), g_type_name (G_VALUE_TYPE (v2)));
- erow = -2;
- break;
- }
- if (gda_value_compare (v1, v2)) {
- changed = TRUE;
- break;
- }
- }
}
- if (!changed && (erow >= 0))
- erow = -3;
+ *out_has_changed = changed;
}
}
@@ -2363,71 +2435,336 @@
}
/**
- * gda_meta_store_get_depending_tables
+ * gda_meta_store_schema_get_tables
* @store: a #GdaMetaStore object
- * @table_name: the name of a table present in @store
*
- * Get a list of the tables which depend on the table named @table_name.
+ * Get an ordered list of the tables @store knows about. The tables are ordered in a way that tables dependencies
+ * are respected: if table B has a foreign key on table A, then table A will be listed before table B in the returned
+ * list.
*
* Returns: a new list of tables names (as gchar*), the list must be freed when no longer needed,
* but the strings present in the list must not be modified.
*/
GSList *
-gda_meta_store_get_depending_tables (GdaMetaStore *store, const gchar *table_name)
+gda_meta_store_schema_get_tables (GdaMetaStore *store)
{
GSList *list, *ret;
GdaMetaStoreClass *klass;
- DbObject *dbobj;
- TableInfo *tinfo;
g_return_val_if_fail (GDA_IS_META_STORE (store), NULL);
- g_return_val_if_fail (table_name && *table_name, NULL);
klass = (GdaMetaStoreClass *) G_OBJECT_GET_CLASS (store);
- dbobj = g_hash_table_lookup (klass->cpriv->db_objects_hash, table_name);
- if (!dbobj) {
- g_warning ("Table '%s' is not known by the GdaMetaStore", table_name);
- return NULL;
+ for (ret = NULL, list = klass->cpriv->db_objects; list; list = list->next) {
+ DbObject *dbobj = DB_OBJECT (list->data);
+ if (dbobj->obj_type == GDA_SERVER_OPERATION_CREATE_TABLE)
+ ret = g_slist_prepend (ret, dbobj->obj_name);
}
- if (dbobj->obj_type != GDA_SERVER_OPERATION_CREATE_TABLE) {
- g_warning ("Table '%s' is not a database table in the GdaMetaStore", table_name);
+
+ return g_slist_reverse (ret);
+}
+
+
+/**
+ * gda_meta_store_schema_get_structure
+ * @store: a #GdaMetaStore object
+ * @error: a place to store errors, or %NULL
+ *
+ * Creates a new #GdaMetaStruct object representing @store's interal database structure.
+ *
+ * Returns: a new #GdaMetaStruct object, or %NULL if an error occurred
+ */
+GdaMetaStruct *
+gda_meta_store_schema_get_structure (GdaMetaStore *store, GError **error)
+{
+ GdaMetaStruct *mstruct;
+ GdaMetaStore *pstore;
+ GdaDataModel *model;
+ gint i, nrows;
+
+ g_return_val_if_fail (GDA_IS_META_STORE (store), NULL);
+
+ /* make sure the private connection's meta store is up to date */
+ if (! gda_connection_update_meta_store (store->priv->cnc, NULL, error))
+ return NULL;
+
+ /* create a GdaMetaStruct */
+ pstore = gda_connection_get_meta_store (store->priv->cnc);
+ model = gda_meta_store_extract (pstore, "SELECT table_catalog, table_schema, table_name FROM _tables", error, NULL);
+ if (!model)
return NULL;
+
+ mstruct = gda_meta_struct_new (GDA_META_STRUCT_FEATURE_ALL);
+ nrows = gda_data_model_get_n_rows (model);
+ for (i = 0; i < nrows; i++) {
+ if (!gda_meta_struct_complement (mstruct, pstore, GDA_META_DB_UNKNOWN,
+ gda_data_model_get_value_at (model, 0, i),
+ gda_data_model_get_value_at (model, 1, i),
+ gda_data_model_get_value_at (model, 2, i), error)) {
+ g_object_unref (mstruct);
+ g_object_unref (model);
+ return NULL;
+ }
}
+ g_object_unref (model);
- tinfo = TABLE_INFO (dbobj);
- for (ret = NULL, list = tinfo->reverse_fk_list; list; list = list->next) {
- TableFKey *tfk = (TableFKey*) list->data;
- ret = g_slist_prepend (ret, tfk->table_info->obj_name);
+ /* complement the meta struct with some info about dependencies */
+ GSList *list;
+ GdaMetaStoreClass *klass;
+
+ klass = (GdaMetaStoreClass *) G_OBJECT_GET_CLASS (pstore);
+ for (list = klass->cpriv->db_objects; list; list = list->next) {
+ DbObject *dbobj = DB_OBJECT (list->data);
+ if (dbobj->obj_type == GDA_SERVER_OPERATION_CREATE_TABLE) {
+ GdaMetaDbObject *mdbo;
+ GSList *dep_list;
+ GValue *value;
+
+ g_value_set_string ((value = gda_value_new (G_TYPE_STRING)), dbobj->obj_name);
+ mdbo = gda_meta_struct_get_db_object (mstruct, NULL, NULL, value);
+ gda_value_free (value);
+ if (!mdbo)
+ continue;
+ for (dep_list = dbobj->depend_list; dep_list; dep_list = dep_list->next) {
+ GdaMetaDbObject *dep_mdbo;
+ g_value_set_string ((value = gda_value_new (G_TYPE_STRING)), DB_OBJECT (dep_list->data)->obj_name);
+ dep_mdbo = gda_meta_struct_get_db_object (mstruct, NULL, NULL, value);
+ gda_value_free (value);
+ if (dep_mdbo && !g_slist_find (mdbo->depend_list, dep_mdbo)) {
+ /* FIXME: dependencies are added using the mdbo->depend_list list, and not as
+ * real foreign key */
+ mdbo->depend_list = g_slist_append (mdbo->depend_list, dep_mdbo);
+ }
+ }
+ }
}
+
+ return mstruct;
+}
- return g_slist_reverse (ret);
+/**
+ * gda_meta_store_get_attribute_value
+ * @store: a #GdaMetaStore object
+ * @att_name: name of the attribute to get
+ * @att_value: the place to store the attribute value
+ * @error: a place to store errors, or %NULL
+ *
+ * The #GdaMetaStore object maintains a list of (name,value) attributes (attributes names starting with a '_'
+ * character are for intarnal use only and cannot be altered). This method and the gda_meta_store_set_attribute_value()
+ * method allows the user to add, set or remove attributes specific to their usage.
+ *
+ * This method allows to get the value of a attribute stored in @store. The returned attribute value is
+ * placed at @att_value, the caller is responsible to free that string.
+ *
+ * If there is no attribute named @att_name then @att_value is set to %NULL
+ * and @error will contain the GDA_META_STORE_ATTRIBUTE_NOT_FOUND_ERROR error code, and FALSE is returned.
+ *
+ * Returns: TRUE if no error occurred
+ */
+gboolean
+gda_meta_store_get_attribute_value (GdaMetaStore *store, const gchar *att_name, gchar **att_value, GError **error)
+{
+ GdaDataModel *model;
+ GValue *value;
+ gint nrows;
+ g_return_val_if_fail (GDA_IS_META_STORE (store), FALSE);
+ g_return_val_if_fail (att_name && *att_name, FALSE);
+ g_return_val_if_fail (att_value, FALSE);
+
+ *att_value = NULL;
+ g_value_set_string ((value = gda_value_new (G_TYPE_STRING)), att_name);
+ model = gda_meta_store_extract (store, "SELECT att_value FROM _attributes WHERE att_name = ##n::string", error,
+ "n", value, NULL);
+ gda_value_free (value);
+ if (!model)
+ return FALSE;
+ nrows = gda_data_model_get_n_rows (model);
+ if (nrows < 1)
+ g_set_error (error, GDA_META_STORE_ERROR, GDA_META_STORE_ATTRIBUTE_NOT_FOUND_ERROR,
+ _("Attribute '%s' not found"), att_name);
+ else if (nrows > 1)
+ g_set_error (error, GDA_META_STORE_ERROR, GDA_META_STORE_ATTRIBUTE_ERROR,
+ _("Attribute '%s' has %d values"), att_name, nrows);
+ else {
+ value = (GValue*) gda_data_model_get_value_at (model, 0, 0);
+ if (value && (G_VALUE_TYPE (value) == G_TYPE_STRING)) {
+ const gchar *val;
+ val = g_value_get_string (value);
+ if (val)
+ *att_value = g_strdup (val);
+ }
+ return TRUE;
+ }
+ return FALSE;
}
/**
- * gda_meta_store_get_schema_tables
+ * gda_meta_store_set_attribute_value
* @store: a #GdaMetaStore object
+ * @att_name: name of the attribute to set
+ * @att_value: value of the attribute to set, or %NULL to unset the attribute
+ * @error: a place to store errors, or %NULL
*
- * Get an ordered list of the tables @store knows about. The tables are ordered in a way that tables dependencies
- * are respected: if table B has a foreign key on table A, then table A will be listed before table B in the returned
- * list.
+ * Set the value of the attribute named @att_name to @att_value; see gda_meta_store_get_attribute_value() for
+ * more information.
*
- * Returns: a new list of tables names (as gchar*), the list must be freed when no longer needed,
- * but the strings present in the list must not be modified.
+ * Returns: TRUE if no error occurred
*/
-GSList *
-gda_meta_store_get_schema_tables (GdaMetaStore *store)
+gboolean
+gda_meta_store_set_attribute_value (GdaMetaStore *store, const gchar *att_name,
+ const gchar *att_value, GError **error)
{
- GSList *list, *ret;
GdaMetaStoreClass *klass;
+ static GdaSet *set = NULL;
+ gboolean started_transaction = FALSE;
- g_return_val_if_fail (GDA_IS_META_STORE (store), NULL);
+ g_return_val_if_fail (GDA_IS_META_STORE (store), FALSE);
+ g_return_val_if_fail (att_name && *att_name, FALSE);
+
+ if (*att_name == '_') {
+ g_set_error (error, GDA_META_STORE_ERROR, GDA_META_STORE_ATTRIBUTE_ERROR,
+ _("Attributes names starting with a '_' are reserved for internal usage"));
+ return FALSE;
+ }
klass = (GdaMetaStoreClass *) G_OBJECT_GET_CLASS (store);
- for (ret = NULL, list = klass->cpriv->db_objects; list; list = list->next) {
- DbObject *dbobj = DB_OBJECT (list->data);
- if (dbobj->obj_type == GDA_SERVER_OPERATION_CREATE_TABLE)
- ret = g_slist_prepend (ret, dbobj->obj_name);
+ if (!set) {
+ if (!gda_statement_get_parameters (klass->cpriv->prep_stmts [STMT_SET_ATT_VALUE], &set, error))
+ return FALSE;
}
- return g_slist_reverse (ret);
+ if (!gda_set_set_holder_value (set, "name", att_name)) {
+ g_set_error (error, GDA_META_STORE_ERROR, GDA_META_STORE_ATTRIBUTE_ERROR,
+ _("Internal GdaMetaStore error"));
+ return FALSE;
+ }
+
+ /* start a transaction if possible */
+ if (! gda_connection_get_transaction_status (store->priv->cnc))
+ started_transaction = gda_connection_begin_transaction (store->priv->cnc, NULL,
+ GDA_TRANSACTION_ISOLATION_UNKNOWN,
+ NULL);
+ else
+ g_warning (_("Could not start a transaction because one already started, this could lead to GdaMetaStore "
+ "attributes problems"));
+
+ /* delete existing attribute */
+ if (gda_connection_statement_execute_non_select (store->priv->cnc,
+ klass->cpriv->prep_stmts [STMT_DEL_ATT_VALUE], set,
+ NULL, error) == -1)
+ goto onerror;
+
+ if (att_value) {
+ /* set new attribute */
+ if (!gda_set_set_holder_value (set, "value", att_value)) {
+ g_set_error (error, GDA_META_STORE_ERROR, GDA_META_STORE_ATTRIBUTE_ERROR,
+ _("Internal GdaMetaStore error"));
+ goto onerror;
+ }
+ if (gda_connection_statement_execute_non_select (store->priv->cnc,
+ klass->cpriv->prep_stmts [STMT_SET_ATT_VALUE], set,
+ NULL, error) == -1)
+ goto onerror;
+ }
+ if (started_transaction)
+ gda_connection_commit_transaction (store->priv->cnc, NULL, NULL);
+ return TRUE;
+
+ onerror:
+ if (started_transaction)
+ gda_connection_rollback_transaction (store->priv->cnc, NULL, NULL);
+ return FALSE;
+}
+
+/**
+ * gda_meta_store_schema_add_custom_object
+ * @store: a #GdaMetaStore object
+ * @xml_description: an XML description of the table or view to add to @store
+ * @error: a place to store errors, or %NULL
+ *
+ * The internal database used by @store can be 'augmented' with some user-defined database objects
+ * (such as tables or views). This method allows one to add a new database object.
+ *
+ * If the internal database already contains the object, then:
+ * <itemizedlist>
+ * <listitem><para>if the object is equal to the provided description then TRUE is returned</para></listitem>
+ * <listitem><para>if the object exists but differs from the provided description, then FALSE is returned,
+ * with the GDA_META_STORE_SCHEMA_OBJECT_CONFLICT_ERROR error code</para></listitem>
+ * </itemizedlist>
+ *
+ * Returns: TRUE if the new object has sucessfully been added
+ */
+gboolean
+gda_meta_store_schema_add_custom_object (GdaMetaStore *store, const gchar *xml_description, GError **error)
+{
+ xmlDocPtr doc;
+ xmlNodePtr node;
+ GdaMetaStoreClass *klass;
+ DbObject *dbo = NULL;
+ GValue *value;
+ GdaMetaStore *pstore;
+ GdaMetaStruct *mstruct;
+
+ g_return_val_if_fail (GDA_IS_META_STORE (store), FALSE);
+ g_return_val_if_fail (xml_description && *xml_description, FALSE);
+
+ /* load XML description */
+ doc = xmlParseDoc (BAD_CAST xml_description);
+ if (!doc) {
+ g_set_error (error, GDA_META_STORE_ERROR, GDA_META_STORE_SCHEMA_OBJECT_DESCR_ERROR,
+ _("Could not parse XML description of custom database object to add"));
+ return FALSE;
+ }
+ node = xmlDocGetRootElement (doc);
+
+ klass = (GdaMetaStoreClass *) G_OBJECT_GET_CLASS (store);
+
+ /* create DbObject structure from XML description */
+ /* FIXME: create the DbObject but store it into @store->priv instead of klass->cpriv */
+ if (!strcmp ((gchar *) node->name, "table")) {
+ xmlChar *prop;
+ prop = xmlGetProp (node, BAD_CAST "name");
+ if (!prop)
+ g_set_error (error, GDA_META_STORE_ERROR, GDA_META_STORE_SCHEMA_OBJECT_DESCR_ERROR,
+ _("Missing custom database object name"));
+ else if (*prop == '_')
+ g_set_error (error, GDA_META_STORE_ERROR, GDA_META_STORE_SCHEMA_OBJECT_DESCR_ERROR,
+ _("Custom database object names starting with a '_' are reserved for internal usage"));
+ else
+ dbo = create_table_object (klass, node, error);
+ }
+ else if (!strcmp ((gchar *) node->name, "view")) {
+ xmlChar *prop;
+ prop = xmlGetProp (node, BAD_CAST "name");
+ if (!prop)
+ g_set_error (error, GDA_META_STORE_ERROR, GDA_META_STORE_SCHEMA_OBJECT_DESCR_ERROR,
+ _("Missing custom database object name"));
+ else if (*prop == '_')
+ g_set_error (error, GDA_META_STORE_ERROR, GDA_META_STORE_SCHEMA_OBJECT_DESCR_ERROR,
+ _("Custom database object names starting with a '_' are reserved for internal usage"));
+ else
+ dbo = create_view_object (klass, node, error);
+ }
+
+ xmlFreeDoc (doc);
+
+ if (!dbo)
+ return FALSE;
+
+ /* check for an already existing database object with the same name */
+ g_print ("Obj name: %s\n", dbo->obj_name);
+
+ /* make sure the private connection's meta store is up to date */
+ if (! gda_connection_update_meta_store (store->priv->cnc, NULL, error))
+ return FALSE;
+
+ /* create a GdaMetaStruct */
+ pstore = gda_connection_get_meta_store (store->priv->cnc);
+ mstruct = gda_meta_struct_new (GDA_META_STRUCT_FEATURE_ALL);
+ g_value_set_string ((value = gda_value_new (G_TYPE_STRING)), dbo->obj_name);
+ if (!gda_meta_struct_complement (mstruct, pstore, GDA_META_DB_UNKNOWN,
+ NULL, NULL, value, error))
+ return FALSE;
+ gda_value_free (value);
+
+ return TRUE;
}
Modified: trunk/libgda/gda-meta-store.h
==============================================================================
--- trunk/libgda/gda-meta-store.h (original)
+++ trunk/libgda/gda-meta-store.h Wed Mar 12 21:18:24 2008
@@ -24,6 +24,7 @@
#include <glib-object.h>
#include <libgda/gda-enums.h>
#include <libgda/gda-data-model.h>
+#include <libgda/gda-decl.h>
G_BEGIN_DECLS
@@ -32,11 +33,6 @@
#define GDA_META_STORE_CLASS(klass) G_TYPE_CHECK_CLASS_CAST (klass, gda_meta_store_get_type (), GdaMetaStoreClass)
#define GDA_IS_META_STORE(obj) G_TYPE_CHECK_INSTANCE_TYPE (obj, gda_meta_store_get_type ())
-typedef struct _GdaMetaStore GdaMetaStore;
-typedef struct _GdaMetaStoreClass GdaMetaStoreClass;
-typedef struct _GdaMetaStorePrivate GdaMetaStorePrivate;
-typedef struct _GdaMetaStoreClassPrivate GdaMetaStoreClassPrivate;
-
/* error reporting */
extern GQuark gda_meta_store_error_quark (void);
#define GDA_META_STORE_ERROR gda_meta_store_error_quark ()
@@ -46,7 +42,11 @@
GDA_META_STORE_UNSUPPORTED_PROVIDER,
GDA_META_STORE_INTERNAL_ERROR,
GDA_META_STORE_MODIFY_CONTENTS_ERROR,
- GDA_META_STORE_EXTRACT_SQL_ERROR
+ GDA_META_STORE_EXTRACT_SQL_ERROR,
+ GDA_META_STORE_ATTRIBUTE_NOT_FOUND_ERROR,
+ GDA_META_STORE_ATTRIBUTE_ERROR,
+ GDA_META_STORE_SCHEMA_OBJECT_CONFLICT_ERROR,
+ GDA_META_STORE_SCHEMA_OBJECT_DESCR_ERROR
} GdaMetaStoreError;
/*
@@ -87,8 +87,9 @@
GdaMetaStoreClassPrivate *cpriv;
/* signals the changes */
- void (*suggest_update)(GdaMetaStore *store, GdaMetaContext *suggest);
- void (*meta_changed) (GdaMetaStore *store, GSList *changes);
+ void (*reset) (GdaMetaStore *store, GdaMetaContext *suggest);
+ GError *(*suggest_update)(GdaMetaStore *store, GdaMetaContext *suggest);
+ void (*meta_changed) (GdaMetaStore *store, GSList *changes);
};
GType gda_meta_store_get_type (void) G_GNUC_CONST;
@@ -98,14 +99,24 @@
GdaConnection *gda_meta_store_get_internal_connection (GdaMetaStore *store);
GdaDataModel *gda_meta_store_extract (GdaMetaStore *store, const gchar *select_sql, GError **error, ...);
-
gboolean gda_meta_store_modify (GdaMetaStore *store, const gchar *table_name,
GdaDataModel *new_data, const gchar *condition, GError **error, ...);
gboolean gda_meta_store_modify_with_context (GdaMetaStore *store, GdaMetaContext *context,
GdaDataModel *new_data, GError **error);
GdaDataModel *gda_meta_store_create_modify_data_model (GdaMetaStore *store, const gchar *table_name);
-GSList *gda_meta_store_get_depending_tables (GdaMetaStore *store, const gchar *table_name);
-GSList *gda_meta_store_get_schema_tables (GdaMetaStore *store);
+
+GdaMetaStruct *gda_meta_store_schema_get_structure (GdaMetaStore *store, GError **error);
+
+gboolean gda_meta_store_get_attribute_value (GdaMetaStore *store, const gchar *att_name,
+ gchar **att_value, GError **error);
+gboolean gda_meta_store_set_attribute_value (GdaMetaStore *store, const gchar *att_name,
+ const gchar *att_value, GError **error);
+
+gboolean gda_meta_store_schema_add_custom_object (GdaMetaStore *store, const gchar *xml_description,
+ GError **error);
+
+/* TO REMOVE */
+GSList *gda_meta_store_schema_get_tables (GdaMetaStore *store);
G_END_DECLS
Modified: trunk/libgda/gda-meta-struct.c
==============================================================================
--- trunk/libgda/gda-meta-struct.c (original)
+++ trunk/libgda/gda-meta-struct.c Wed Mar 12 21:18:24 2008
@@ -44,6 +44,7 @@
struct _GdaMetaStructPrivate {
GHashTable *index; /* key = [catalog].[schema].[name], value = a GdaMetaDbObject */
+ guint features;
};
static void gda_meta_db_object_free (GdaMetaDbObject *dbo);
@@ -102,11 +103,11 @@
object_class->set_property = gda_meta_struct_set_property;
object_class->get_property = gda_meta_struct_get_property;
g_object_class_install_property (object_class, PROP_FEATURES,
- g_param_spec_int ("fetures", _ ("Features to compute"), NULL,
- GDA_META_STRUCT_FEATURE_ALL, G_MAXINT,
- GDA_META_STRUCT_FEATURE_ALL,
- (G_PARAM_WRITABLE | G_PARAM_READABLE |
- G_PARAM_CONSTRUCT_ONLY)));
+ g_param_spec_uint ("features", _ ("Features to compute"), NULL,
+ GDA_META_STRUCT_FEATURE_NONE, G_MAXINT,
+ GDA_META_STRUCT_FEATURE_ALL,
+ (G_PARAM_WRITABLE | G_PARAM_READABLE |
+ G_PARAM_CONSTRUCT_ONLY)));
/* virtual methods */
object_class->finalize = gda_meta_struct_finalize;
@@ -122,13 +123,15 @@
/**
* gda_meta_struct_new
+ * @features: the kind of information the new #GdaMetaStruct object will compute (the more features, the more time
+ * it takes to run)
*
* Returns: the newly created #GdaMetaStruct object
*/
GdaMetaStruct *
-gda_meta_struct_new (void)
+gda_meta_struct_new (GdaMetaStructFeature features)
{
- return (GdaMetaStruct*) g_object_new (GDA_TYPE_META_STRUCT, NULL);
+ return (GdaMetaStruct*) g_object_new (GDA_TYPE_META_STRUCT, "features", features, NULL);
}
static void
@@ -163,7 +166,7 @@
if (mstruct->priv) {
switch (param_id) {
case PROP_FEATURES:
- TO_IMPLEMENT;
+ mstruct->priv->features = g_value_get_uint (value);
break;
default:
break;
@@ -183,7 +186,7 @@
if (mstruct->priv) {
switch (param_id) {
case PROP_FEATURES:
- TO_IMPLEMENT;
+ g_value_set_uint (value, mstruct->priv->features);
break;
default:
break;
@@ -193,7 +196,7 @@
static void
-compute_view_dependencies (GdaMetaStruct *mstruct, GdaMetaDbObject *view_dbobj, GdaSqlStatement *sqlst)
+compute_view_dependencies (GdaMetaStruct *mstruct, GdaMetaStore *store, GdaMetaDbObject *view_dbobj, GdaSqlStatement *sqlst)
{
if (sqlst->stmt_type == GDA_SQL_STATEMENT_SELECT) {
GdaSqlStatementSelect *selst;
@@ -202,28 +205,51 @@
for (targets = selst->from->targets; targets; targets = targets->next) {
GdaSqlSelectTarget *t = (GdaSqlSelectTarget *) targets->data;
GValue *catalog, *schema, *name;
- GdaMetaDbObject *ref_obj;
+ GdaMetaDbObject *ref_obj, *tmp_obj;
+ GdaMetaStruct *m2;
+ GValue *vname;
if (!t->table_name)
continue;
- /* FIXME: compute catalog, schema, name using t->table_name */
- /*
+
+ m2 = gda_meta_struct_new (GDA_META_STRUCT_FEATURE_NONE);
+ g_value_set_string ((vname = gda_value_new (G_TYPE_STRING)), t->table_name);
+ if (! (tmp_obj = gda_meta_struct_complement (m2, store, GDA_META_DB_TABLE, NULL, NULL, vname, NULL)))
+ tmp_obj = gda_meta_struct_complement (m2, store, GDA_META_DB_VIEW, NULL, NULL, vname, NULL);
+ gda_value_free (vname);
+
+ if (!tmp_obj) {
+ /* could not find dependency */
+ g_object_unref (m2);
+ continue;
+ }
+
+ /* the dependency exists, and is identified by tmp_obj->obj_catalog, tmp_obj->obj_schema
+ * and tmp_obj->obj_name */
+ g_value_set_string ((catalog = gda_value_new (G_TYPE_STRING)), tmp_obj->obj_catalog);
+ g_value_set_string ((schema = gda_value_new (G_TYPE_STRING)), tmp_obj->obj_schema);
+ g_value_set_string ((name = gda_value_new (G_TYPE_STRING)), tmp_obj->obj_name);
ref_obj = gda_meta_struct_get_db_object (mstruct, catalog, schema, name);
if (!ref_obj) {
gchar *str;
ref_obj = g_new0 (GdaMetaDbObject, 1);
ref_obj->obj_type = GDA_META_DB_UNKNOWN;
- ref_obj->obj_catalog = g_strdup (g_value_get_string (fk_catalog));
- ref_obj->obj_schema = g_strdup (g_value_get_string (fk_schema));
- ref_obj->obj_name = g_strdup (g_value_get_string (fk_name));
+ ref_obj->obj_catalog = g_strdup (tmp_obj->obj_catalog);
+ ref_obj->obj_schema = g_strdup (tmp_obj->obj_schema);
+ ref_obj->obj_name = g_strdup (tmp_obj->obj_name);
+
mstruct->db_objects = g_slist_append (mstruct->db_objects, ref_obj);
- str = g_strdup_printf ("%s.%s.%s", g_value_get_string (fk_catalog),
- g_value_get_string (fk_schema),
- g_value_get_string (fk_name));
+ str = g_strdup_printf ("%s.%s.%s", tmp_obj->obj_catalog,
+ tmp_obj->obj_schema, tmp_obj->obj_name);
g_hash_table_insert (mstruct->priv->index, str, ref_obj);
}
+ g_assert (ref_obj);
+ g_object_unref (m2);
+ gda_value_free (catalog);
+ gda_value_free (schema);
+ gda_value_free (name);
+
view_dbobj->depend_list = g_slist_append (view_dbobj->depend_list, ref_obj);
- */
}
}
else if (sqlst->stmt_type == GDA_SQL_STATEMENT_COMPOUND) {
@@ -231,26 +257,30 @@
GSList *list;
cst = (GdaSqlStatementCompound*) (sqlst->contents);
for (list = cst->stmt_list; list; list = list->next)
- compute_view_dependencies (mstruct, view_dbobj, (GdaSqlStatement*) list->data);
+ compute_view_dependencies (mstruct, store, view_dbobj, (GdaSqlStatement*) list->data);
}
else
g_assert_not_reached ();
}
static gboolean determine_db_object_from_schema_and_name (GdaMetaStruct *mstruct, GdaMetaStore *store,
- GdaMetaDbObjectType type, GValue **out_catalog,
+ GdaMetaDbObjectType *int_out_type, GValue **out_catalog,
GValue **out_short_name, GValue **out_full_name,
GValue **out_owner, const GValue *schema, const GValue *name);
static gboolean determine_db_object_from_short_name (GdaMetaStruct *mstruct, GdaMetaStore *store,
- GdaMetaDbObjectType type, GValue **out_catalog,
+ GdaMetaDbObjectType *int_out_type, GValue **out_catalog,
GValue **out_schema, GValue **out_name, GValue **out_short_name,
GValue **out_full_name, GValue **out_owner, const GValue *name);
+static gboolean determine_db_object_from_missing_type (GdaMetaStruct *mstruct, GdaMetaStore *store,
+ GdaMetaDbObjectType *out_type, GValue **out_short_name,
+ GValue **out_full_name, GValue **out_owner, const GValue *catalog,
+ const GValue *schema, const GValue *name);
/**
* gda_meta_struct_complement
* @mstruct: a #GdaMetaStruct object
* @store: the #GdaMetaStore to use
- * @type: the type of object to add
+ * @type: the type of object to add (which can be GDA_META_DB_UNKNOWN)
* @catalog: the catalog the object belongs to (as a G_TYPE_STRING GValue), or %NULL
* @schema: the schema the object belongs to (as a G_TYPE_STRING GValue), or %NULL
* @name: the object's name (as a G_TYPE_STRING GValue), not %NULL
@@ -273,17 +303,18 @@
GError **error)
{
GdaMetaDbObject *dbo = NULL;
+ GdaMetaDbObjectType real_type = type;
GValue *real_catalog = NULL, *real_schema = NULL, *real_name = NULL;
GValue *short_name = NULL, *full_name=NULL, *owner=NULL;
g_return_val_if_fail (GDA_IS_META_STORE (store), NULL);
- g_return_val_if_fail (mstruct, NULL);
+ g_return_val_if_fail (GDA_IS_META_STRUCT (mstruct), NULL);
g_return_val_if_fail (name && (G_VALUE_TYPE (name) == G_TYPE_STRING), NULL);
if (!catalog) {
if (schema) {
g_return_val_if_fail (schema && (G_VALUE_TYPE (schema) == G_TYPE_STRING), NULL);
- if (! determine_db_object_from_schema_and_name (mstruct, store, type, &real_catalog,
+ if (! determine_db_object_from_schema_and_name (mstruct, store, &real_type, &real_catalog,
&short_name, &full_name, &owner,
schema, name)) {
g_set_error (error, GDA_META_STRUCT_ERROR, GDA_META_STRUCT_UNKNOWN_OBJECT_ERROR,
@@ -294,7 +325,7 @@
catalog = real_catalog;
}
else {
- if (! determine_db_object_from_short_name (mstruct, store, type, &real_catalog,
+ if (! determine_db_object_from_short_name (mstruct, store, &real_type, &real_catalog,
&real_schema, &real_name,
&short_name, &full_name, &owner, name)) {
g_set_error (error, GDA_META_STRUCT_ERROR, GDA_META_STRUCT_UNKNOWN_OBJECT_ERROR,
@@ -307,8 +338,19 @@
schema = real_schema;
}
}
- g_return_val_if_fail (catalog && (G_VALUE_TYPE (catalog) == G_TYPE_STRING), NULL);
- g_return_val_if_fail (schema && (G_VALUE_TYPE (schema) == G_TYPE_STRING), NULL);
+ else if (type == GDA_META_DB_UNKNOWN) {
+ g_return_val_if_fail (catalog && (G_VALUE_TYPE (catalog) == G_TYPE_STRING), NULL);
+ g_return_val_if_fail (schema && (G_VALUE_TYPE (schema) == G_TYPE_STRING), NULL);
+
+ if (! determine_db_object_from_missing_type (mstruct, store, &real_type, &short_name, &full_name, &owner,
+ catalog, schema, name)) {
+ g_set_error (error, GDA_META_STRUCT_ERROR, GDA_META_STRUCT_UNKNOWN_OBJECT_ERROR,
+ _("Could not find object named '%s.%s.%s'"), g_value_get_string (catalog),
+ g_value_get_string (schema), g_value_get_string (name));
+ return NULL;
+ }
+ }
+ type = real_type;
/* create new GdaMetaDbObject or get already existing one */
dbo = gda_meta_struct_get_db_object (mstruct, catalog, schema, name);
@@ -372,7 +414,8 @@
mv->is_updatable = g_value_get_boolean (gda_data_model_get_value_at (model, 1, 0));
/* view's dependencies, from its definition */
- if (mv->view_def && *mv->view_def) {
+ if ((mstruct->priv->features & GDA_META_STRUCT_FEATURE_VIEW_DEPENDENCIES) &&
+ mv->view_def && *mv->view_def) {
static GdaSqlParser *parser = NULL;
GdaStatement *stmt;
const gchar *remain;
@@ -384,7 +427,7 @@
(gda_statement_get_statement_type (stmt) == GDA_SQL_STATEMENT_COMPOUND))) {
GdaSqlStatement *sqlst;
g_object_get (G_OBJECT (stmt), "structure", &sqlst, NULL);
- compute_view_dependencies (mstruct, dbo, sqlst);
+ compute_view_dependencies (mstruct, store, dbo, sqlst);
gda_sql_statement_free (sqlst);
g_object_unref (stmt);
@@ -400,10 +443,7 @@
}
case GDA_META_DB_TABLE: {
/* columns */
- gchar *sql = "SELECT c.column_name, c.data_type, c.gtype, c.is_nullable, t.table_short_name, t.table_full_name, "
- "c.column_default, t.table_owner FROM _columns as c NATURAL JOIN _tables as t WHERE table_catalog = ##tc::string "
- "AND table_schema = ##ts::string AND table_name = ##tname::string "
- "ORDER BY ordinal_position";
+ gchar *sql = "SELECT c.column_name, c.data_type, c.gtype, c.is_nullable, t.table_short_name, t.table_full_name, c.column_default, t.table_owner FROM _columns as c NATURAL JOIN _tables as t WHERE table_catalog = ##tc::string AND table_schema = ##ts::string AND table_name = ##tname::string ORDER BY ordinal_position";
GdaMetaTable *mt;
GdaDataModel *model;
gint i, nrows;
@@ -448,19 +488,19 @@
g_object_unref (model);
/* primary key */
- sql = "SELECT constraint_catalog, constraint_schema, constraint_name FROM _table_constraints WHERE constraint_type='PRIMARY KEY' AND table_catalog = ##tc::string AND table_schema = ##ts::string AND table_name = ##tname::string";
+ sql = "SELECT constraint_name FROM _table_constraints WHERE constraint_type='PRIMARY KEY' AND table_catalog = ##tc::string AND table_schema = ##ts::string AND table_name = ##tname::string";
model = gda_meta_store_extract (store, sql, error, "tc", catalog, "ts", schema, "tname", name, NULL);
if (!model)
goto onerror;
nrows = gda_data_model_get_n_rows (model);
- if (nrows >= 1) {
+ if (0 && nrows >= 1) {
GdaDataModel *pkmodel;
sql = "SELECT column_name FROM _key_column_usage WHERE constraint_catalog = ##cc::string AND constraint_schema = ##cs::string AND constraint_name = ##cname::string ORDER BY ordinal_position";
pkmodel = gda_meta_store_extract (store, sql, error,
"cc", gda_data_model_get_value_at (model, 0, 0),
"cs", gda_data_model_get_value_at (model, 1, 0),
- "cname", gda_data_model_get_value_at (model, 2, 0), NULL);
+ "cname", gda_data_model_get_value_at (model, 0, 0), NULL);
if (!pkmodel) {
g_object_unref (model);
goto onerror;
@@ -488,45 +528,47 @@
g_object_unref (model);
/* foreign keys */
- sql = "SELECT t.table_catalog, t.table_schema, t.table_name FROM _tables as f INNER JOIN _table_constraints as tc ON (tc.table_catalog=f.table_catalog AND tc.table_schema=f.table_schema AND tc.table_name=f.table_name) INNER JOIN _referential_constraints as rc ON (rc.constraint_catalog = tc.constraint_catalog AND rc.constraint_schema=tc.constraint_schema AND rc.constraint_name=tc.constraint_name) INNER JOIN _table_constraints as tc2 ON (rc.unique_constraint_catalog = tc2.constraint_catalog AND rc.unique_constraint_schema=tc2.constraint_schema AND rc.unique_constraint_name=tc2.constraint_name) INNER JOIN _tables as t ON (tc2.table_catalog=t.table_catalog AND tc2.table_schema=t.table_schema AND tc2.table_name=t.table_name) WHERE f.table_catalog = ##tc::string AND f.table_schema = ##ts::string AND f.table_name = ##tname::string";
- model = gda_meta_store_extract (store, sql, error, "tc", catalog, "ts", schema, "tname", name, NULL);
- if (!model)
- goto onerror;
-
- nrows = gda_data_model_get_n_rows (model);
- for (i = 0; i < nrows; i++) {
- GdaMetaTableForeignKey *tfk;
- const GValue *fk_catalog, *fk_schema, *fk_name;
-
- fk_catalog = gda_data_model_get_value_at (model, 0, i);
- fk_schema = gda_data_model_get_value_at (model, 1, i);
- fk_name = gda_data_model_get_value_at (model, 2, i);
- tfk = g_new0 (GdaMetaTableForeignKey, 1);
- tfk->meta_table = dbo;
- tfk->depend_on = gda_meta_struct_get_db_object (mstruct, fk_catalog, fk_schema, fk_name);
- if (!tfk->depend_on) {
- gchar *str;
- tfk->depend_on = g_new0 (GdaMetaDbObject, 1);
- tfk->depend_on->obj_type = GDA_META_DB_UNKNOWN;
- tfk->depend_on->obj_catalog = g_strdup (g_value_get_string (fk_catalog));
- tfk->depend_on->obj_schema = g_strdup (g_value_get_string (fk_schema));
- tfk->depend_on->obj_name = g_strdup (g_value_get_string (fk_name));
- mstruct->db_objects = g_slist_append (mstruct->db_objects, tfk->depend_on);
- str = g_strdup_printf ("%s.%s.%s", g_value_get_string (fk_catalog),
- g_value_get_string (fk_schema),
- g_value_get_string (fk_name));
- g_hash_table_insert (mstruct->priv->index, str, tfk->depend_on);
+ if (mstruct->priv->features & GDA_META_STRUCT_FEATURE_FOREIGN_KEYS) {
+ sql = "SELECT ref_table_catalog, ref_table_schema, ref_table_name FROM _referential_constraints WHERE table_catalog = ##tc::string AND table_schema = ##ts::string AND table_name = ##tname::string";
+ model = gda_meta_store_extract (store, sql, error, "tc", catalog, "ts", schema, "tname", name, NULL);
+ if (!model)
+ goto onerror;
+
+ nrows = gda_data_model_get_n_rows (model);
+ for (i = 0; i < nrows; i++) {
+ GdaMetaTableForeignKey *tfk;
+ const GValue *fk_catalog, *fk_schema, *fk_name;
+
+ fk_catalog = gda_data_model_get_value_at (model, 0, i);
+ fk_schema = gda_data_model_get_value_at (model, 1, i);
+ fk_name = gda_data_model_get_value_at (model, 2, i);
+ tfk = g_new0 (GdaMetaTableForeignKey, 1);
+ tfk->meta_table = dbo;
+ tfk->depend_on = gda_meta_struct_get_db_object (mstruct, fk_catalog, fk_schema, fk_name);
+ if (!tfk->depend_on) {
+ gchar *str;
+ tfk->depend_on = g_new0 (GdaMetaDbObject, 1);
+ tfk->depend_on->obj_type = GDA_META_DB_UNKNOWN;
+ tfk->depend_on->obj_catalog = g_strdup (g_value_get_string (fk_catalog));
+ tfk->depend_on->obj_schema = g_strdup (g_value_get_string (fk_schema));
+ tfk->depend_on->obj_name = g_strdup (g_value_get_string (fk_name));
+ mstruct->db_objects = g_slist_append (mstruct->db_objects, tfk->depend_on);
+ str = g_strdup_printf ("%s.%s.%s", g_value_get_string (fk_catalog),
+ g_value_get_string (fk_schema),
+ g_value_get_string (fk_name));
+ g_hash_table_insert (mstruct->priv->index, str, tfk->depend_on);
+ }
+ dbo->depend_list = g_slist_append (dbo->depend_list, tfk->depend_on);
+
+ /* FIXME: compute @cols_nb, and all the @*_array members (ref_pk_cols_array must be
+ * initialized with -1 values everywhere */
+
+ mt->fk_list = g_slist_prepend (mt->fk_list, tfk);
}
- dbo->depend_list = g_slist_append (dbo->depend_list, tfk->depend_on);
-
- /* FIXME: compute @cols_nb, and all the @*_array members (ref_pk_cols_array must be
- * initialized with -1 values everywhere */
-
- mt->fk_list = g_slist_prepend (mt->fk_list, tfk);
+ mt->fk_list = g_slist_reverse (mt->fk_list);
+ g_object_unref (model);
+ /* Note: mt->reverse_fk_list is not determined here */
}
- mt->fk_list = g_slist_reverse (mt->fk_list);
- g_object_unref (model);
- /* Note: mt->reverse_fk_list is not determined here */
break;
}
@@ -542,7 +584,7 @@
g_value_get_string (name));
g_hash_table_insert (mstruct->priv->index, str, dbo);
}
- if (dbo) {
+ if (dbo && (mstruct->priv->features & GDA_META_STRUCT_FEATURE_FOREIGN_KEYS)) {
/* compute GdaMetaTableForeignKey's @ref_pk_cols_array arrays and GdaMetaTable' @reverse_fk_list lists*/
GSList *list;
for (list = mstruct->db_objects; list; list = list->next) {
@@ -666,6 +708,8 @@
GSList *pass_list;
GSList *ordered_list = NULL;
+ g_return_val_if_fail (GDA_IS_META_STRUCT (mstruct), FALSE);
+
switch (sort_type) {
case GDA_META_SORT_ALHAPETICAL:
mstruct->db_objects = g_slist_sort (mstruct->db_objects, (GCompareFunc) db_object_sort_func);
@@ -696,13 +740,16 @@
/**
* gda_meta_struct_get_db_object
* @mstruct: a #GdaMetaStruct object
- * @catalog: the catalog the object belongs to (as a G_TYPE_STRING GValue)
- * @schema: the schema the object belongs to (as a G_TYPE_STRING GValue)
- * @name: the object's name (as a G_TYPE_STRING GValue)
+ * @catalog: the catalog the object belongs to (as a G_TYPE_STRING GValue), or %NULL
+ * @schema: the schema the object belongs to (as a G_TYPE_STRING GValue), or %NULL
+ * @name: the object's name (as a G_TYPE_STRING GValue), not %NULL
*
* Tries to locate the #GdaMetaDbObject structure representing the database object named after
* @catalog, @schema and @name.
*
+ * If one or both of @catalog and @schema are %NULL, and more than one database object matches the name, then
+ * the return value is also %NULL.
+ *
* Returns: the #GdaMetaDbObject or %NULL if not found
*/
GdaMetaDbObject *
@@ -711,16 +758,55 @@
gchar *key;
GdaMetaDbObject *dbo;
- g_return_val_if_fail (mstruct, NULL);
- g_return_val_if_fail (catalog && (G_VALUE_TYPE (catalog) == G_TYPE_STRING), NULL);
- g_return_val_if_fail (schema && (G_VALUE_TYPE (schema) == G_TYPE_STRING), NULL);
+ g_return_val_if_fail (GDA_IS_META_STRUCT (mstruct), NULL);
g_return_val_if_fail (name && (G_VALUE_TYPE (name) == G_TYPE_STRING), NULL);
- key = g_strdup_printf ("%s.%s.%s", g_value_get_string (catalog), g_value_get_string (schema),
- g_value_get_string (name));
- dbo = g_hash_table_lookup (mstruct->priv->index, key);
- g_free (key);
- return dbo;
+ if (catalog && schema) {
+ g_return_val_if_fail (G_VALUE_TYPE (catalog) == G_TYPE_STRING, NULL);
+ g_return_val_if_fail (G_VALUE_TYPE (schema) == G_TYPE_STRING, NULL);
+
+ key = g_strdup_printf ("%s.%s.%s", g_value_get_string (catalog), g_value_get_string (schema),
+ g_value_get_string (name));
+ dbo = g_hash_table_lookup (mstruct->priv->index, key);
+ g_free (key);
+ return dbo;
+ }
+ else {
+ /* walk through all the objects, and pick the ones with a matching name */
+ GSList *list;
+ GSList *matching = NULL;
+ const gchar *obj_name = g_value_get_string (name);
+ const gchar *obj_schema = NULL, *obj_catalog = NULL;
+ if (catalog) {
+ g_return_val_if_fail (G_VALUE_TYPE (catalog) == G_TYPE_STRING, NULL);
+ obj_catalog = g_value_get_string (catalog);
+ }
+ if (schema) {
+ g_return_val_if_fail (G_VALUE_TYPE (schema) == G_TYPE_STRING, NULL);
+ obj_schema = g_value_get_string (schema);
+ }
+
+ for (list = mstruct->db_objects; list; list = list->next) {
+ GdaMetaDbObject *dbo;
+ dbo = GDA_META_DB_OBJECT (list->data);
+ if (!strcmp (dbo->obj_name, obj_name) &&
+ (!obj_schema || !strcmp (dbo->obj_schema, obj_schema)) &&
+ (!obj_catalog || !strcmp (dbo->obj_catalog, obj_catalog)))
+ matching = g_slist_prepend (matching, dbo);
+ }
+
+ if (matching && !matching->next) {
+ GdaMetaDbObject *dbo = GDA_META_DB_OBJECT (matching->data);
+ g_slist_free (matching);
+ return dbo;
+ }
+ else {
+ /* none or more than one found => return NULL */
+ if (matching)
+ g_slist_free (matching);
+ return NULL;
+ }
+ }
}
/**
@@ -738,7 +824,7 @@
{
GSList *list;
const gchar *cname;
- g_return_val_if_fail (mstruct, NULL);
+ g_return_val_if_fail (GDA_IS_META_STRUCT (mstruct), NULL);
g_return_val_if_fail (table, NULL);
g_return_val_if_fail (col_name && (G_VALUE_TYPE (col_name) == G_TYPE_STRING), NULL);
cname = g_value_get_string (col_name);
@@ -752,23 +838,135 @@
}
/**
- * gda_meta_struct_free
+ * gda_meta_struct_dump_as_graph
* @mstruct: a #GdaMetaStruct object
- *
- * Releases any memory associated to @mstruct.
+ * @info: informs what kind of information to show in the resulting graph
+ * @error: a place to store errors, or %NULL
+ *
+ * Creates a new graph (in the GraphViz syntax) representation of @mstruct.
+ *
+ * Returns: a new string, or %NULL if an error occurred.
*/
-void
-gda_meta_struct_free (GdaMetaStruct *mstruct)
+gchar *
+gda_meta_struct_dump_as_graph (GdaMetaStruct *mstruct, GdaMetaGraphInfo info, GError **error)
{
- if (!mstruct)
- return;
+ GString *string;
+ gchar *result;
- g_slist_foreach (mstruct->db_objects, (GFunc) gda_meta_db_object_free, NULL);
- g_slist_free (mstruct->db_objects);
- g_hash_table_destroy (mstruct->priv->index);
- g_free (mstruct);
-}
+ g_return_val_if_fail (GDA_IS_META_STRUCT (mstruct), NULL);
+
+ string = g_string_new ("digraph G {\nrankdir = BT;\nnode [shape = plaintext];\n");
+ GSList *dbo_list;
+ for (dbo_list = mstruct->db_objects; dbo_list; dbo_list = dbo_list->next) {
+ gchar *objname, *fullname;
+ GdaMetaDbObject *dbo = GDA_META_DB_OBJECT (dbo_list->data);
+ GSList *list;
+ gboolean use_html = (info & GDA_META_GRAPH_COLUMNS) ? TRUE : FALSE;
+
+ /* obj human readable name, and full name */
+ fullname = g_strdup_printf ("%s.%s.%s", dbo->obj_catalog, dbo->obj_schema, dbo->obj_name);
+ if (dbo->obj_short_name)
+ objname = g_strdup (dbo->obj_short_name);
+ else
+ objname = g_strdup_printf ("%s.%s", dbo->obj_schema, dbo->obj_name);
+
+ /* node */
+ switch (dbo->obj_type) {
+ case GDA_META_DB_UNKNOWN:
+ break;
+ case GDA_META_DB_TABLE:
+ if (use_html) {
+ g_string_append_printf (string, "\"%s\" [label=<<TABLE BORDER=\"1\" CELLBORDER=\"0\" CELLSPACING=\"0\">", fullname);
+ g_string_append_printf (string, "<TR><TD COLSPAN=\"2\" BGCOLOR=\"grey\" BORDER=\"1\">%s</TD></TR>", objname);
+ }
+ else
+ g_string_append_printf (string, "\"%s\" [ shape = box label = \"%s\" ]", fullname, objname);
+ break;
+ case GDA_META_DB_VIEW:
+ if (use_html) {
+ g_string_append_printf (string, "\"%s\" [label=<<TABLE BORDER=\"1\" CELLBORDER=\"0\" CELLSPACING=\"0\">", fullname);
+ g_string_append_printf (string, "<TR><TD BGCOLOR=\"yellow\" BORDER=\"1\">%s</TD></TR>", objname);
+ }
+ else
+ g_string_append_printf (string, "\"%s\" [ shape = ellipse, label = \"%s\" ]", fullname, objname);
+ break;
+ default:
+ TO_IMPLEMENT;
+ g_string_append_printf (string, "\"%s\" [ shape = note label = \"%s\" ]", fullname, objname);
+ break;
+ }
+
+ /* columns, only for tables */
+ if (dbo->obj_type == GDA_META_DB_TABLE) {
+ GdaMetaTable *mt = GDA_META_DB_OBJECT_GET_TABLE (dbo);
+ GSList *depend_dbo_list = NULL;
+ if (info & GDA_META_GRAPH_COLUMNS) {
+ for (list = mt->columns; list; list = list->next) {
+ GdaMetaTableColumn *tcol = GDA_META_TABLE_COLUMN (list->data);
+ GString *extra = g_string_new ("");
+ if (tcol->pkey)
+ g_string_append_printf (extra, "key");
+ g_string_append_printf (string, "<TR><TD ALIGN=\"left\">%s</TD><TD ALIGN=\"right\">%s</TD></TR>",
+ tcol->column_name, extra->str);
+ g_string_free (extra, TRUE);
+ }
+ }
+ if (use_html)
+ g_string_append (string, "</TABLE>>];\n");
+ /* foreign keys */
+ for (list = mt->fk_list; list; list = list->next) {
+ GdaMetaTableForeignKey *tfk = GDA_META_TABLE_FOREIGN_KEY (list->data);
+ if (tfk->depend_on->obj_type != GDA_META_DB_UNKNOWN) {
+ g_string_append_printf (string, "\"%s\" -> \"%s.%s.%s\";\n", fullname,
+ tfk->depend_on->obj_catalog, tfk->depend_on->obj_schema,
+ tfk->depend_on->obj_name);
+ depend_dbo_list = g_slist_prepend (depend_dbo_list, tfk->depend_on);
+ }
+ }
+
+ /* dependencies other than foreign keys */
+ for (list = dbo->depend_list; list; list = list->next) {
+ if (!g_slist_find (depend_dbo_list, list->data)) {
+ GdaMetaDbObject *dep_dbo = GDA_META_DB_OBJECT (list->data);
+ if (dep_dbo->obj_type != GDA_META_DB_UNKNOWN)
+ g_string_append_printf (string, "\"%s\" -> \"%s.%s.%s\";\n",
+ fullname,
+ dep_dbo->obj_catalog, dep_dbo->obj_schema,
+ dep_dbo->obj_name);
+ }
+ }
+
+ g_slist_free (depend_dbo_list);
+ }
+ else if (dbo->obj_type == GDA_META_DB_VIEW) {
+ GdaMetaTable *mt = GDA_META_DB_OBJECT_GET_TABLE (dbo);
+ if (info & GDA_META_GRAPH_COLUMNS) {
+ for (list = mt->columns; list; list = list->next) {
+ GdaMetaTableColumn *tcol = GDA_META_TABLE_COLUMN (list->data);
+ g_string_append_printf (string, "<TR><TD ALIGN=\"left\">%s</TD></TR>", tcol->column_name);
+ }
+ }
+ if (use_html)
+ g_string_append (string, "</TABLE>>];\n");
+ /* dependencies */
+ for (list = dbo->depend_list; list; list = list->next) {
+ GdaMetaDbObject *ddbo = GDA_META_DB_OBJECT (list->data);
+ if (ddbo->obj_type != GDA_META_DB_UNKNOWN)
+ g_string_append_printf (string, "\"%s\" -> \"%s.%s.%s\";\n", fullname,
+ ddbo->obj_catalog, ddbo->obj_schema,
+ ddbo->obj_name);
+ }
+ }
+ g_free (objname);
+ g_free (fullname);
+ }
+ g_string_append_c (string, '}');
+
+ result = string->str;
+ g_string_free (string, FALSE);
+ return result;
+}
static void
gda_meta_db_object_free (GdaMetaDbObject *dbo)
@@ -838,7 +1036,7 @@
static gboolean
determine_db_object_from_schema_and_name (GdaMetaStruct *mstruct, GdaMetaStore *store,
- GdaMetaDbObjectType type, GValue **out_catalog,
+ GdaMetaDbObjectType *in_out_type, GValue **out_catalog,
GValue **out_short_name,
GValue **out_full_name, GValue **out_owner,
const GValue *schema, const GValue *name)
@@ -848,9 +1046,26 @@
*out_full_name = NULL;
*out_owner = NULL;
- switch (type) {
- case GDA_META_DB_UNKNOWN:
+ switch (*in_out_type) {
+ case GDA_META_DB_UNKNOWN: {
+ GdaMetaDbObjectType type = GDA_META_DB_TABLE;
+ if (determine_db_object_from_schema_and_name (mstruct, store, &type, out_catalog,
+ out_short_name, out_full_name, out_owner,
+ schema, name)) {
+ *in_out_type = GDA_META_DB_TABLE;
+ return TRUE;
+ }
+ type = GDA_META_DB_VIEW;
+ if (determine_db_object_from_schema_and_name (mstruct, store, &type, out_catalog,
+ out_short_name, out_full_name, out_owner,
+ schema, name)) {
+ *in_out_type = GDA_META_DB_VIEW;
+ return TRUE;
+ }
+ return FALSE;
break;
+ }
+
case GDA_META_DB_TABLE: {
const gchar *sql = "SELECT table_catalog, table_short_name, table_full_name, table_owner FROM _tables as t WHERE table_schema = ##ts::string AND table_short_name = ##tname::string AND table_name NOT IN (SELECT v.table_name FROM _views as v WHERE v.table_catalog=t.table_catalog AND v.table_schema=t.table_schema)";
GdaDataModel *model;
@@ -871,6 +1086,7 @@
g_object_unref (model);
return TRUE;
}
+
case GDA_META_DB_VIEW:{
const gchar *sql = "SELECT table_catalog, table_short_name, table_full_name, table_owner FROM _tables NATURAL JOIN _views WHERE table_schema = ##ts::string AND table_short_name = ##tname::string";
GdaDataModel *model;
@@ -900,7 +1116,7 @@
static gboolean
determine_db_object_from_short_name (GdaMetaStruct *mstruct, GdaMetaStore *store,
- GdaMetaDbObjectType type, GValue **out_catalog,
+ GdaMetaDbObjectType *in_out_type, GValue **out_catalog,
GValue **out_schema, GValue **out_name, GValue **out_short_name,
GValue **out_full_name, GValue **out_owner, const GValue *name)
{
@@ -912,9 +1128,24 @@
*out_owner = NULL;
/* general lookup */
- switch (type) {
- case GDA_META_DB_UNKNOWN:
+ switch (*in_out_type) {
+ case GDA_META_DB_UNKNOWN: {
+ GdaMetaDbObjectType type = GDA_META_DB_TABLE;
+ if (determine_db_object_from_short_name (mstruct, store, &type, out_catalog, out_schema, out_name,
+ out_short_name, out_full_name, out_owner, name)) {
+ *in_out_type = GDA_META_DB_TABLE;
+ return TRUE;
+ }
+ type = GDA_META_DB_VIEW;
+ if (determine_db_object_from_short_name (mstruct, store, &type, out_catalog, out_schema, out_name,
+ out_short_name, out_full_name, out_owner, name)) {
+ *in_out_type = GDA_META_DB_VIEW;
+ return TRUE;
+ }
+ return FALSE;
break;
+ }
+
case GDA_META_DB_TABLE: {
const gchar *sql = "SELECT table_catalog, table_schema, table_name, table_short_name, table_full_name, table_owner FROM _tables as t WHERE table_short_name = ##tname::string AND table_name NOT IN (SELECT v.table_name FROM _views as v WHERE v.table_catalog=t.table_catalog AND v.table_schema=t.table_schema)";
GdaDataModel *model;
@@ -937,6 +1168,7 @@
g_object_unref (model);
return TRUE;
}
+
case GDA_META_DB_VIEW:{
const gchar *sql = "SELECT table_catalog, table_schema, table_name, table_short_name, table_full_name, table_owner FROM _tables NATURAL JOIN _views WHERE table_short_name = ##tname::string";
GdaDataModel *model;
@@ -978,7 +1210,7 @@
*ptr = 0;
g_value_set_string ((sv = gda_value_new (G_TYPE_STRING)), tmp);
g_value_set_string ((nv = gda_value_new (G_TYPE_STRING)), ptr + 1);
- retval = determine_db_object_from_schema_and_name (mstruct, store, type, out_catalog,
+ retval = determine_db_object_from_schema_and_name (mstruct, store, in_out_type, out_catalog,
out_short_name, out_full_name, out_owner,
sv, nv);
if (retval) {
@@ -996,3 +1228,40 @@
return FALSE;
}
+
+static gboolean
+determine_db_object_from_missing_type (GdaMetaStruct *mstruct, GdaMetaStore *store,
+ GdaMetaDbObjectType *out_type, GValue **out_short_name,
+ GValue **out_full_name, GValue **out_owner, const GValue *catalog,
+ const GValue *schema, const GValue *name)
+{
+ /* try as a view first */
+ const gchar *sql = "SELECT table_short_name, table_full_name, table_owner FROM _tables NATURAL JOIN _views WHERE table_catalog = ##tc::string AND table_schema = ##ts::string AND table_name = ##tname::string";
+ GdaDataModel *model;
+
+ model = gda_meta_store_extract (store, sql, NULL, "tc", catalog, "ts", schema, "tname", name, NULL);
+ if (model && (gda_data_model_get_n_rows (model) == 1)) {
+ *out_type = GDA_META_DB_VIEW;
+ *out_short_name = gda_value_copy (gda_data_model_get_value_at (model, 0, 0));
+ *out_full_name = gda_value_copy (gda_data_model_get_value_at (model, 1, 0));
+ *out_owner = gda_value_copy (gda_data_model_get_value_at (model, 2, 0));
+ g_object_unref (model);
+ return TRUE;
+ }
+ if (model) g_object_unref (model);
+
+ /* try as a table */
+ sql = "SELECT table_short_name, table_full_name, table_owner FROM _tables WHERE table_catalog = ##tc::string AND table_schema = ##ts::string AND table_name = ##tname::string";
+ model = gda_meta_store_extract (store, sql, NULL, "tc", catalog, "ts", schema, "tname", name, NULL);
+ if (model && (gda_data_model_get_n_rows (model) == 1)) {
+ *out_type = GDA_META_DB_TABLE;
+ *out_short_name = gda_value_copy (gda_data_model_get_value_at (model, 0, 0));
+ *out_full_name = gda_value_copy (gda_data_model_get_value_at (model, 1, 0));
+ *out_owner = gda_value_copy (gda_data_model_get_value_at (model, 2, 0));
+ g_object_unref (model);
+ return TRUE;
+ }
+ if (model) g_object_unref (model);
+
+ return FALSE;
+}
Modified: trunk/libgda/gda-meta-struct.h
==============================================================================
--- trunk/libgda/gda-meta-struct.h (original)
+++ trunk/libgda/gda-meta-struct.h Wed Mar 12 21:18:24 2008
@@ -24,6 +24,7 @@
#include <glib-object.h>
#include <libgda/gda-data-model.h>
#include <libgda/gda-meta-store.h>
+#include <libgda/gda-decl.h>
G_BEGIN_DECLS
@@ -32,10 +33,6 @@
#define GDA_META_STRUCT_CLASS(klass) G_TYPE_CHECK_CLASS_CAST (klass, gda_meta_struct_get_type (), GdaMetaStructClass)
#define GDA_IS_META_STRUCT(obj) G_TYPE_CHECK_INSTANCE_TYPE (obj, gda_meta_struct_get_type ())
-typedef struct _GdaMetaStruct GdaMetaStruct;
-typedef struct _GdaMetaStructClass GdaMetaStructClass;
-typedef struct _GdaMetaStructPrivate GdaMetaStructPrivate;
-
/* error reporting */
extern GQuark gda_meta_struct_error_quark (void);
#define GDA_META_STRUCT_ERROR gda_meta_struct_error_quark ()
@@ -74,9 +71,12 @@
* Controls which features are computed about database objects
*/
typedef enum {
- GDA_META_STRUCT_FEATURE_ALL,
- GDA_META_STRUCT_FEATURE_FOREIGN_KEYS,
- GDA_META_STRUCT_FEATURE_VIEW_DEPENDENCIES
+ GDA_META_STRUCT_FEATURE_NONE = 0,
+ GDA_META_STRUCT_FEATURE_FOREIGN_KEYS = 1 << 0,
+ GDA_META_STRUCT_FEATURE_VIEW_DEPENDENCIES = 1 << 1,
+
+ GDA_META_STRUCT_FEATURE_ALL = GDA_META_STRUCT_FEATURE_FOREIGN_KEYS |
+ GDA_META_STRUCT_FEATURE_VIEW_DEPENDENCIES
} GdaMetaStructFeature;
/*
@@ -103,7 +103,7 @@
GSList *fk_list; /* list of GdaMetaTableForeignKey where @gda_meta_table == this GdaMetaDbObject */
} GdaMetaTable;
-/*
+/**
* Complements the GdaMetaDbObject structure, for views only
* contains more information than for tables
*/
@@ -113,7 +113,7 @@
gboolean is_updatable;
} GdaMetaView;
-/*
+/*
* Struture to hold information about each object
* which can be created in the internal GdaMetaStore's connection.
* It is available for tables, views, triggers, ...
@@ -162,7 +162,7 @@
GType gda_meta_struct_get_type (void) G_GNUC_CONST;
-GdaMetaStruct *gda_meta_struct_new (void);
+GdaMetaStruct *gda_meta_struct_new (GdaMetaStructFeature features);
GdaMetaDbObject *gda_meta_struct_complement (GdaMetaStruct *mstruct, GdaMetaStore *store, GdaMetaDbObjectType type,
const GValue *catalog, const GValue *schema, const GValue *name,
GError **error);
@@ -172,6 +172,12 @@
GdaMetaTableColumn *gda_meta_struct_get_table_column (GdaMetaStruct *mstruct, GdaMetaTable *table,
const GValue *col_name);
+typedef enum {
+ GDA_META_GRAPH_COLUMNS = 1 << 0
+} GdaMetaGraphInfo;
+
+gchar *gda_meta_struct_dump_as_graph (GdaMetaStruct *mstruct, GdaMetaGraphInfo info, GError **error);
+
G_END_DECLS
#endif
Modified: trunk/libgda/gda-server-operation.c
==============================================================================
--- trunk/libgda/gda-server-operation.c (original)
+++ trunk/libgda/gda-server-operation.c Wed Mar 12 21:18:24 2008
@@ -1953,8 +1953,11 @@
param = gda_set_get_holder (opnode->d.plist, extension);
if (param) {
GValue *v;
- v = gda_value_new_from_string (value,
- gda_holder_get_g_type (param));
+ if (value)
+ v = gda_value_new_from_string (value,
+ gda_holder_get_g_type (param));
+ else
+ v = gda_value_new_null ();
if (!gda_holder_take_value (param, v)) {
g_set_error (error, 0, 0,
_("Could not set parameter '%s' to value '%s'"),
@@ -1995,8 +1998,11 @@
if (allok) {
GValue *gvalue;
- gvalue = gda_value_new_from_string (value,
- gda_column_get_g_type (column));
+ if (value)
+ gvalue = gda_value_new_from_string (value,
+ gda_column_get_g_type (column));
+ else
+ gvalue = gda_value_new_null ();
allok = gda_data_model_set_value_at (opnode->d.model,
gda_column_get_position (column),
row, gvalue, error);
@@ -2009,8 +2015,11 @@
}
case GDA_SERVER_OPERATION_NODE_PARAM: {
GValue *v;
- v = gda_value_new_from_string (value,
- gda_holder_get_g_type (opnode->d.param));
+ if (value)
+ v = gda_value_new_from_string (value,
+ gda_holder_get_g_type (opnode->d.param));
+ else
+ v = gda_value_new_null ();
if (!gda_holder_take_value (opnode->d.param, v)) {
g_set_error (error, 0, 0,
_("Could not set parameter '%s' to value '%s'"),
Modified: trunk/libgda/gda-server-provider.h
==============================================================================
--- trunk/libgda/gda-server-provider.h (original)
+++ trunk/libgda/gda-server-provider.h Wed Mar 12 21:18:24 2008
@@ -63,24 +63,39 @@
};
typedef struct {
- gboolean (*info) (GdaServerProvider *, GdaConnection *, GdaMetaStore *, GdaMetaContext *, GError **);
- gboolean (*btypes) (GdaServerProvider *, GdaConnection *, GdaMetaStore *, GdaMetaContext *, GError **);
- gboolean (*schemata) (GdaServerProvider *, GdaConnection *, GdaMetaStore *, GdaMetaContext *, GError **,
- const GValue *schema_name);
- gboolean (*tables_views) (GdaServerProvider *, GdaConnection *, GdaMetaStore *, GdaMetaContext *, GError **);
- gboolean (*tables_views_s)(GdaServerProvider *, GdaConnection *, GdaMetaStore *, GdaMetaContext *, GError **,
- const GValue *table_schema, const GValue *table_name);
- gboolean (*columns) (GdaServerProvider *, GdaConnection *, GdaMetaStore *, GdaMetaContext *, GError **);
- gboolean (*columns_t) (GdaServerProvider *, GdaConnection *, GdaMetaStore *, GdaMetaContext *, GError **,
- const GValue *table_schema, const GValue *table_name);
- gboolean (*columns_c) (GdaServerProvider *, GdaConnection *, GdaMetaStore *, GdaMetaContext *, GError **,
- const GValue *table_schema, const GValue *table_name, const GValue *column_name);
- gboolean (*constraints_tab)(GdaServerProvider *, GdaConnection *, GdaMetaStore *, GdaMetaContext *, GError **);
- gboolean (*constraints_tab_s)(GdaServerProvider *, GdaConnection *, GdaMetaStore *, GdaMetaContext *, GError **,
- const GValue *table_schema, const GValue *table_name);
- gboolean (*constraints_ref)(GdaServerProvider *, GdaConnection *, GdaMetaStore *, GdaMetaContext *, GError **);
- gboolean (*constraints_ref_c)(GdaServerProvider *, GdaConnection *, GdaMetaStore *, GdaMetaContext *, GError **,
- const GValue *constraint_schema, const GValue *constraint_name);
+ /* _information_schema_catalog_name */
+ gboolean (*_info) (GdaServerProvider *, GdaConnection *, GdaMetaStore *, GdaMetaContext *, GError **);
+
+ /* _builtin_data_types */
+ gboolean (*_btypes) (GdaServerProvider *, GdaConnection *, GdaMetaStore *, GdaMetaContext *, GError **);
+
+
+ /* _schemata */
+ gboolean (*_schemata) (GdaServerProvider *, GdaConnection *, GdaMetaStore *, GdaMetaContext *, GError **);
+ gboolean (*schemata) (GdaServerProvider *, GdaConnection *, GdaMetaStore *, GdaMetaContext *, GError **,
+ const GValue *catalog_name, const GValue *schema_name_n);
+
+ /* _tables or _views */
+ gboolean (*_tables_views) (GdaServerProvider *, GdaConnection *, GdaMetaStore *, GdaMetaContext *, GError **);
+ gboolean (*tables_views) (GdaServerProvider *, GdaConnection *, GdaMetaStore *, GdaMetaContext *, GError **,
+ const GValue *table_catalog, const GValue *table_schema, const GValue *table_name_n);
+
+ /* _columns */
+ gboolean (*_columns) (GdaServerProvider *, GdaConnection *, GdaMetaStore *, GdaMetaContext *, GError **);
+ gboolean (*columns) (GdaServerProvider *, GdaConnection *, GdaMetaStore *, GdaMetaContext *, GError **,
+ const GValue *table_catalog, const GValue *table_schema, const GValue *table_name);
+
+ /* _table_constraints */
+ gboolean (*_constraints_tab) (GdaServerProvider *, GdaConnection *, GdaMetaStore *, GdaMetaContext *, GError **);
+ gboolean (*constraints_tab) (GdaServerProvider *, GdaConnection *, GdaMetaStore *, GdaMetaContext *, GError **,
+ const GValue *table_catalog, const GValue *table_schema, const GValue *table_name,
+ const GValue *constraint_name_n);
+
+ /* _referential_constraints */
+ gboolean (*_constraints_ref) (GdaServerProvider *, GdaConnection *, GdaMetaStore *, GdaMetaContext *, GError **);
+ gboolean (*constraints_ref) (GdaServerProvider *, GdaConnection *, GdaMetaStore *, GdaMetaContext *, GError **,
+ const GValue *table_catalog, const GValue *table_schema, const GValue *table_name,
+ const GValue *constraint_name);
} GdaServerProviderMeta;
typedef void (*GdaServerProviderAsyncCallback) (GdaServerProvider *provider, GdaConnection *cnc, guint task_id,
Modified: trunk/libgda/gda-value.c
==============================================================================
--- trunk/libgda/gda-value.c (original)
+++ trunk/libgda/gda-value.c Wed Mar 12 21:18:24 2008
@@ -1798,7 +1798,7 @@
g_return_val_if_fail (value1 && value2, -1);
g_return_val_if_fail (G_VALUE_TYPE (value1) == G_VALUE_TYPE (value2), -1);
- type = G_VALUE_TYPE(value1);
+ type = G_VALUE_TYPE (value1);
if (value1 == value2)
return 0;
@@ -1868,10 +1868,19 @@
return (v1 > v2) ? 1 : -1;
}
- else if (type == GDA_TYPE_GEOMETRIC_POINT)
- return memcmp (gda_value_get_geometric_point(value1) ,
- gda_value_get_geometric_point(value2),
- sizeof (GdaGeometricPoint));
+ else if (type == GDA_TYPE_GEOMETRIC_POINT) {
+ const GdaGeometricPoint *p1, *p2;
+ p1 = gda_value_get_geometric_point (value1);
+ p2 = gda_value_get_geometric_point (value2);
+ if (p1 && p2)
+ return memcmp (p1, p2, sizeof (GdaGeometricPoint));
+ else if (p1)
+ return 1;
+ else if (p2)
+ return -1;
+ else
+ return 0;
+ }
else if (type == G_TYPE_OBJECT) {
if (g_value_get_object (value1) == g_value_get_object (value2))
@@ -1958,15 +1967,34 @@
return retval;
}
- else if (type == GDA_TYPE_TIME)
- return memcmp (gda_value_get_time(value1), gda_value_get_time(value2),
- sizeof (GdaTime));
-
- else if (type == GDA_TYPE_TIMESTAMP)
- return memcmp (gda_value_get_timestamp(value1),
- gda_value_get_timestamp(value2),
- sizeof (GdaTimestamp));
-
+ else if (type == GDA_TYPE_TIME) {
+ const GdaTime *t1, *t2;
+ t1 = gda_value_get_time (value1);
+ t2 = gda_value_get_time (value2);
+ if (t1 && t2)
+ return memcmp (t1, t2, sizeof (GdaTime));
+ else if (t1)
+ return 1;
+ else if (t2)
+ return -1;
+ else
+ return 0;
+ }
+
+ else if (type == GDA_TYPE_TIMESTAMP) {
+ const GdaTimestamp *ts1, *ts2;
+ ts1 = gda_value_get_timestamp (value1);
+ ts2 = gda_value_get_timestamp (value2);
+ if (ts1 && ts2)
+ return memcmp (ts1, ts2, sizeof (GdaTimestamp));
+ else if (ts1)
+ return 1;
+ else if (ts2)
+ return -1;
+ else
+ return 0;
+ }
+
else if (type == G_TYPE_CHAR)
return (g_value_get_char (value1) > g_value_get_char (value2)) ? 1 :
((g_value_get_char (value1) == g_value_get_char (value2)) ? 0 : -1);
Modified: trunk/libgda/information_schema.xml
==============================================================================
--- trunk/libgda/information_schema.xml (original)
+++ trunk/libgda/information_schema.xml Wed Mar 12 21:18:24 2008
@@ -69,6 +69,10 @@
<column name="udt_full_name"/>
<column name="udt_internal" type="boolean"/>
<column name="udt_owner" nullok="TRUE"/>
+ <fkey ref_table="_schemata">
+ <part column="udt_catalog" ref_column="catalog_name"/>
+ <part column="udt_schema" ref_column="schema_name"/>
+ </fkey>
<unique>
<column name="udt_full_name"/>
</unique>
@@ -330,14 +334,15 @@
</table>
<table name="_table_constraints">
- <column name="constraint_catalog" pkey="TRUE"/>
- <column name="constraint_schema" pkey="TRUE"/>
+ <column name="constraint_catalog" nullok="TRUE" descr="Name of the catalog that contains the constraint"/>
+ <column name="constraint_schema" nullok="TRUE" descr="Name of the schema that contains the constraint"/>
+
<column name="constraint_name" pkey="TRUE"/>
- <column name="table_catalog"/>
- <column name="table_schema"/>
- <column name="table_name"/>
+ <column name="table_catalog" pkey="TRUE"/>
+ <column name="table_schema" pkey="TRUE"/>
+ <column name="table_name" pkey="TRUE"/>
<column name="constraint_type" descr="CHECK, FOREIGN KEY, PRIMARY KEY or UNIQUE"/>
- <column name="check_clause" nullok="TRUE"/>
+ <column name="check_clause" nullok="TRUE" descr="The check expression if the constraint is a check constraint, NULL otherwise"/>
<column name="is_deferrable" type="boolean" nullok="TRUE"/>
<column name="initially_deferred" type="boolean" nullok="TRUE"/>
<fkey ref_table="_tables">
@@ -345,46 +350,48 @@
<part column="table_schema"/>
<part column="table_name"/>
</fkey>
- <fkey ref_table="_schemata">
- <part column="constraint_catalog" ref_column="catalog_name"/>
- <part column="constraint_schema" ref_column="schema_name"/>
- </fkey>
</table>
<table name="_referential_constraints">
- <column name="constraint_catalog" pkey="TRUE"/>
- <column name="constraint_schema" pkey="TRUE"/>
+ <column name="table_catalog" pkey="TRUE"/>
+ <column name="table_schema" pkey="TRUE"/>
+ <column name="table_name" pkey="TRUE"/>
<column name="constraint_name" pkey="TRUE"/>
- <column name="unique_constraint_catalog"/>
- <column name="unique_constraint_schema"/>
- <column name="unique_constraint_name"/>
+
+ <column name="ref_table_catalog"/>
+ <column name="ref_table_schema"/>
+ <column name="ref_table_name"/>
+ <column name="ref_constraint_name"/>
+
<column name="match_option" nullok="TRUE"/>
<column name="update_rule" nullok="TRUE"/>
<column name="delete_rule" nullok="TRUE"/>
<fkey ref_table="_table_constraints">
- <part column="constraint_catalog"/>
- <part column="constraint_schema"/>
+ <part column="table_catalog"/>
+ <part column="table_schema"/>
+ <part column="table_name"/>
<part column="constraint_name"/>
</fkey>
<fkey ref_table="_table_constraints">
- <part column="unique_constraint_catalog" ref_column="constraint_catalog"/>
- <part column="unique_constraint_schema" ref_column="constraint_schema"/>
- <part column="unique_constraint_name" ref_column="constraint_name"/>
+ <part column="ref_table_catalog" ref_column="table_catalog"/>
+ <part column="ref_table_schema" ref_column="table_schema"/>
+ <part column="ref_table_name" ref_column="table_name"/>
+ <part column="ref_constraint_name" ref_column="constraint_name"/>
</fkey>
</table>
<table name="_key_column_usage">
- <column name="constraint_catalog" pkey="TRUE"/>
- <column name="constraint_schema" pkey="TRUE"/>
+ <column name="table_catalog" pkey="TRUE"/>
+ <column name="table_schema" pkey="TRUE"/>
+ <column name="table_name" pkey="TRUE"/>
<column name="constraint_name" pkey="TRUE"/>
- <column name="table_catalog"/>
- <column name="table_schema"/>
- <column name="table_name"/>
- <column name="column_name"/>
+ <column name="column_name" pkey="TRUE"/>
+
<column name="ordinal_position" type="gint" pkey="TRUE"/>
<fkey ref_table="_table_constraints">
- <part column="constraint_catalog"/>
- <part column="constraint_schema"/>
+ <part column="table_catalog"/>
+ <part column="table_schema"/>
+ <part column="table_name"/>
<part column="constraint_name"/>
</fkey>
<fkey ref_table="_columns">
@@ -396,16 +403,15 @@
</table>
<table name="_check_column_usage">
- <column name="constraint_catalog" pkey="TRUE"/>
- <column name="constraint_schema" pkey="TRUE"/>
+ <column name="table_catalog" pkey="TRUE"/>
+ <column name="table_schema" pkey="TRUE"/>
+ <column name="table_name" pkey="TRUE"/>
<column name="constraint_name" pkey="TRUE"/>
- <column name="table_catalog"/>
- <column name="table_schema"/>
- <column name="table_name"/>
- <column name="column_name"/>
+ <column name="column_name" pkey="TRUE"/>
<fkey ref_table="_table_constraints">
- <part column="constraint_catalog"/>
- <part column="constraint_schema"/>
+ <part column="table_catalog"/>
+ <part column="table_schema"/>
+ <part column="table_name"/>
<part column="constraint_name"/>
</fkey>
<fkey ref_table="_columns">
@@ -420,9 +426,6 @@
<column name="view_catalog" pkey="TRUE"/>
<column name="view_schema" pkey="TRUE"/>
<column name="view_name" pkey="TRUE"/>
- <column name="table_catalog" pkey="TRUE"/>
- <column name="table_schema" pkey="TRUE"/>
- <column name="table_name" pkey="TRUE"/>
<column name="column_name" pkey="TRUE"/>
<fkey ref_table="_views">
<part column="view_catalog" ref_column="table_catalog"/>
@@ -430,20 +433,22 @@
<part column="view_name" ref_column="table_name"/>
</fkey>
<fkey ref_table="_columns">
- <part column="table_catalog"/>
- <part column="table_schema"/>
- <part column="table_name"/>
- <part column="column_name"/>
+ <part column="view_catalog" ref_column="table_catalog"/>
+ <part column="view_schema" ref_column="table_schema"/>
+ <part column="view_name" ref_column="table_name"/>
+ <part column="column_name" ref_column="column_name"/>
</fkey>
</table>
<table name="_domain_constraints">
- <column name="constraint_catalog" pkey="TRUE"/>
- <column name="constraint_schema" pkey="TRUE"/>
+ <column name="constraint_catalog" nullok="TRUE" descr="Name of the catalog that contains the constraint"/>
+ <column name="constraint_schema" nullok="TRUE" descr="Name of the schema that contains the constraint"/>
+
<column name="constraint_name" pkey="TRUE"/>
- <column name="domain_catalog"/>
- <column name="domain_schema"/>
- <column name="domain_name"/>
+ <column name="domain_catalog" pkey="TRUE"/>
+ <column name="domain_schema" pkey="TRUE"/>
+ <column name="domain_name" pkey="TRUE"/>
+
<column name="check_clause" nullok="TRUE"/>
<column name="is_deferrable" type="boolean" nullok="TRUE"/>
<column name="initially_deferred" type="boolean" nullok="TRUE"/>
@@ -500,34 +505,5 @@
domain_catalog, domain_schema, domain_name , NULL, NULL, NULL FROM _domains</definition>
</view>
- <view name="_constraint_column_usage">
- <definition>SELECT table_catalog, table_schema, table_name, column_name, constraint_catalog, constraint_schema, constraint_name
-FROM _key_column_usage
-UNION
-SELECT table_catalog, table_schema, table_name, column_name, constraint_catalog, constraint_schema, constraint_name
-FROM _check_column_usage</definition>
- </view>
-
- <view name="_constraint_table_usage">
- <definition>SELECT DISTINCT table_catalog, table_schema, table_name, constraint_catalog, constraint_schema, constraint_name
-FROM _constraint_column_usage</definition>
- </view>
-
- <view name="_view_table_usage">
- <definition>SELECT DISTINCT view_catalog, view_schema, view_name, table_catalog, table_schema, table_name
-FROM _view_column_usage</definition>
- </view>
-
- <view name="_domain_column_usage">
- <definition>SELECT d.domain_catalog, d.domain_schema, d.domain_name,
- c.table_catalog, c.table_schema, c.table_name, c.column_name
-FROM _domains d INNER JOIN _columns c ON (c.data_type=d.domain_full_name)</definition>
- </view>
-
- <view name="_check_constraints">
- <definition>SELECT constraint_catalog, constraint_schema, constraint_name, check_clause FROM _table_constraints
- UNION
- SELECT constraint_catalog, constraint_schema, constraint_name, check_clause FROM _domain_constraints</definition>
- </view>
</schema>
Modified: trunk/libgda/libgda-array.dtd
==============================================================================
--- trunk/libgda/libgda-array.dtd (original)
+++ trunk/libgda/libgda-array.dtd Wed Mar 12 21:18:24 2008
@@ -31,6 +31,7 @@
<!ELEMENT gda_value (#PCDATA)>
<!ATTLIST gda_value
+ isnull NMTOKEN #IMPLIED
xml:lang CDATA #IMPLIED>
<!ELEMENT gda_array_value (#PCDATA)>
Modified: trunk/libgda/sqlite/gda-sqlite-meta.c
==============================================================================
--- trunk/libgda/sqlite/gda-sqlite-meta.c (original)
+++ trunk/libgda/sqlite/gda-sqlite-meta.c Wed Mar 12 21:18:24 2008
@@ -185,8 +185,8 @@
gboolean
_gda_sqlite_meta_schemata (GdaServerProvider *prov, GdaConnection *cnc,
- GdaMetaStore *store, GdaMetaContext *context, GError **error,
- const GValue *schema_name)
+ GdaMetaStore *store, GdaMetaContext *context, GError **error,
+ const GValue *catalog_name, const GValue *schema_name_n)
{
GdaDataModel *model, *tmpmodel;
gboolean retval = TRUE;
@@ -204,8 +204,8 @@
const GValue *cvalue;
cvalue = gda_data_model_get_value_at (tmpmodel, 1, i);
- if (!schema_name ||
- !gda_value_compare_ext (schema_name, cvalue)) {
+ if (!schema_name_n ||
+ !gda_value_compare_ext (schema_name_n, cvalue)) {
const gchar *cstr;
GValue *v1;
@@ -318,56 +318,10 @@
return retval;
}
-gboolean
-_gda_sqlite_meta_tables_views (GdaServerProvider *prov, GdaConnection *cnc,
- GdaMetaStore *store, GdaMetaContext *context, GError **error)
-{
- GdaDataModel *tables_model, *views_model;
- gboolean retval = TRUE;
- tables_model = gda_meta_store_create_modify_data_model (store, "_tables");
- g_assert (tables_model);
- views_model = gda_meta_store_create_modify_data_model (store, "_views");
- g_assert (views_model);
-
- GdaDataModel *sh_model;
- sh_model = gda_connection_get_meta_store_data (cnc, GDA_CONNECTION_META_NAMESPACES, error, 0);
- if (!sh_model)
- retval = TRUE;
- else {
- gint nrows, i;
- nrows = gda_data_model_get_n_rows (sh_model);
- for (i = 0; i < nrows; i++) {
- const GValue *p_table_schema = gda_data_model_get_value_at (sh_model, 0, i);
- if (!fill_tables_views_model (cnc, tables_model, views_model, p_table_schema, NULL, error)) {
- retval = FALSE;
- break;
- }
- }
- g_object_unref (sh_model);
- }
-
- GdaMetaContext c2;
- c2 = *context; /* copy contents, just because we need to modify @context->table_name */
- if (retval) {
- c2.table_name = "_tables";
- retval = gda_meta_store_modify_with_context (store, &c2, tables_model, error);
- }
- if (retval) {
- c2.table_name = "_views";
- retval = gda_meta_store_modify_with_context (store, &c2, views_model, error);
- }
- g_object_unref (tables_model);
- g_object_unref (views_model);
-
- return retval;
-}
-
-
-
gboolean
-_gda_sqlite_meta_tables_views_s (GdaServerProvider *prov, GdaConnection *cnc,
- GdaMetaStore *store, GdaMetaContext *context, GError **error,
- const GValue *table_schema, const GValue *table_name)
+_gda_sqlite_meta_tables_views (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error,
+ const GValue *table_catalog, const GValue *table_schema, const GValue *table_name_n)
{
GdaDataModel *tables_model, *views_model;
gboolean retval = TRUE;
@@ -376,7 +330,7 @@
views_model = gda_meta_store_create_modify_data_model (store, "_views");
g_assert (views_model);
- if (! fill_tables_views_model (cnc, tables_model, views_model, table_schema, table_name, error))
+ if (! fill_tables_views_model (cnc, tables_model, views_model, table_schema, table_name_n, error))
retval = FALSE;
GdaMetaContext c2;
@@ -399,7 +353,7 @@
fill_columns_model (GdaConnection *cnc, SqliteConnectionData *cdata,
GdaDataModel *mod_model,
const GValue *p_table_schema, const GValue *p_table_name,
- const GValue *p_column_name, GError **error)
+ GError **error)
{
GdaDataModel *tmpmodel;
gboolean retval = TRUE;
@@ -439,11 +393,6 @@
GType gtype = 0;
this_col_pname = gda_data_model_get_value_at (tmpmodel, 1, i);
- if (p_column_name &&
- gda_value_compare_ext (p_column_name, this_col_pname))
- continue;
-
-
this_table_name = g_value_get_string (p_table_name);
g_assert (this_table_name);
if (!strcmp (this_table_name, "sqlite_sequence"))
@@ -454,10 +403,12 @@
this_table_name, this_col_name,
&pzDataType, &pzCollSeq, &pNotNull, &pPrimaryKey, &pAutoinc)
!= SQLITE_OK) {
- g_set_error (error, 0, 0,
- _("Internal error"));
- retval = FALSE;
- break;
+ /* may fail because we have a view and not a table => use @tmpmodel to fetch info. */
+ pzDataType = g_value_get_string (gda_data_model_get_value_at (tmpmodel, 2, i));
+ pzCollSeq = NULL;
+ pNotNull = g_value_get_int (gda_data_model_get_value_at (tmpmodel, 3, i));
+ pPrimaryKey = g_value_get_boolean (gda_data_model_get_value_at (tmpmodel, 5, i));
+ pAutoinc = 0;
}
v1 = gda_value_copy (gda_data_model_get_value_at (tmpmodel, 0, i));
@@ -469,18 +420,24 @@
g_value_set_int (v1, g_value_get_int (v1) + 1);
- if (pzDataType)
- gtype = GPOINTER_TO_INT (g_hash_table_lookup (cdata->types, pzDataType));
- if (gtype == 0) {
- g_warning ("Internal error: could not get GType for DBMS type '%s'", pzDataType);
- g_value_set_string ((v6 = gda_value_new (G_TYPE_STRING)), "string");
+ if (pzDataType) {
+ gchar *tmp = g_strdup (pzDataType);
+ gchar *ptr;
+ for (ptr = tmp; *ptr && (*ptr != '(') && (*ptr != '['); ptr++);
+ if (*ptr)
+ *ptr = 0;
+ gtype = GPOINTER_TO_INT (g_hash_table_lookup (cdata->types, tmp));
+ g_free (tmp);
}
+ if (gtype == 0)
+ /* default to string if nothing else */
+ g_value_set_string ((v6 = gda_value_new (G_TYPE_STRING)), "string");
else
g_value_set_string ((v6 = gda_value_new (G_TYPE_STRING)), g_type_name (gtype));
if (! append_a_row (mod_model, error, 25,
- FALSE, catalog_value,
- FALSE, p_table_schema,
- FALSE, p_table_name,
+ FALSE, catalog_value, /* table_catalog */
+ FALSE, p_table_schema, /* table_schema */
+ FALSE, p_table_name, /* table_name */
FALSE, this_col_pname, /* column name */
TRUE, v1, /* ordinal_position */
FALSE, gda_data_model_get_value_at (tmpmodel, 4, i), /* column default */
@@ -512,57 +469,8 @@
gboolean
_gda_sqlite_meta_columns (GdaServerProvider *prov, GdaConnection *cnc,
- GdaMetaStore *store, GdaMetaContext *context, GError **error)
-{
- gboolean retval = TRUE;
- GdaDataModel *mod_model = NULL;
- SqliteConnectionData *cdata;
-
- cdata = (SqliteConnectionData*) gda_connection_internal_get_provider_data (cnc);
- if (!cdata)
- return FALSE;
-
- mod_model = gda_meta_store_create_modify_data_model (store, context->table_name);
- g_assert (mod_model);
-
- GdaDataModel *tmpmodel;
-
- tmpmodel = gda_connection_get_meta_store_data (cnc, GDA_CONNECTION_META_TABLES, error, 0);
- if (!tmpmodel)
- retval = TRUE;
- else {
- gint nrows, i;
- nrows = gda_data_model_get_n_rows (tmpmodel);
- for (i = 0; i < nrows; i++) {
- const GValue *p_table_name = gda_data_model_get_value_at (tmpmodel, 0, i);
- const GValue *p_table_schema = gda_data_model_get_value_at (tmpmodel, 1, i);
- if (!fill_columns_model (cnc, cdata, mod_model, p_table_schema, p_table_name, NULL, error)) {
- retval = FALSE;
- break;
- }
- }
- g_object_unref (tmpmodel);
- }
-
- if (retval)
- retval = gda_meta_store_modify_with_context (store, context, mod_model, error);
- g_object_unref (mod_model);
-
- return retval;
-}
-
-gboolean
-_gda_sqlite_meta_columns_t (GdaServerProvider *prov, GdaConnection *cnc,
- GdaMetaStore *store, GdaMetaContext *context, GError **error,
- const GValue *table_schema, const GValue *table_name)
-{
- return _gda_sqlite_meta_columns_c (prov, cnc, store, context, error, table_schema, table_name, NULL);
-}
-
-gboolean
-_gda_sqlite_meta_columns_c (GdaServerProvider *prov, GdaConnection *cnc,
- GdaMetaStore *store, GdaMetaContext *context, GError **error,
- const GValue *table_schema, const GValue *table_name, const GValue *column_name)
+ GdaMetaStore *store, GdaMetaContext *context, GError **error,
+ const GValue *table_catalog, const GValue *table_schema, const GValue *table_name)
{
gboolean retval = TRUE;
GdaDataModel *mod_model = NULL;
@@ -575,7 +483,7 @@
mod_model = gda_meta_store_create_modify_data_model (store, context->table_name);
g_assert (mod_model);
- retval = fill_columns_model (cnc, cdata, mod_model, table_schema, table_name, column_name, error);
+ retval = fill_columns_model (cnc, cdata, mod_model, table_schema, table_name, error);
if (retval)
retval = gda_meta_store_modify_with_context (store, context, mod_model, error);
g_object_unref (mod_model);
@@ -583,39 +491,26 @@
return retval;
}
-gboolean
-_gda_sqlite_meta_constraints_tab (GdaServerProvider *prov, GdaConnection *cnc,
- GdaMetaStore *store, GdaMetaContext *context, GError **error)
-{
- TO_IMPLEMENT;
- return TRUE;
-}
-
gboolean
-_gda_sqlite_meta_constraints_tab_s (GdaServerProvider *prov, GdaConnection *cnc,
- GdaMetaStore *store, GdaMetaContext *context, GError **error,
- const GValue *table_schema, const GValue *table_name)
+_gda_sqlite_meta_constraints_tab (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error,
+ const GValue *table_catalog, const GValue *table_schema, const GValue *table_name,
+ const GValue *constraint_name_n)
{
- TO_IMPLEMENT;
+ /* not implemented in SQLite */
return TRUE;
}
gboolean
_gda_sqlite_meta_constraints_ref (GdaServerProvider *prov, GdaConnection *cnc,
- GdaMetaStore *store, GdaMetaContext *context, GError **error)
+ GdaMetaStore *store, GdaMetaContext *context, GError **error,
+ const GValue *table_catalog, const GValue *table_schema, const GValue *table_name,
+ const GValue *constraint_name)
{
- TO_IMPLEMENT;
+ /* not implemented in SQLite */
return TRUE;
}
-gboolean
-_gda_sqlite_meta_constraints_ref_c (GdaServerProvider *prov, GdaConnection *cnc,
- GdaMetaStore *store, GdaMetaContext *context, GError **error,
- const GValue *table_schema, const GValue *table_name)
-{
- TO_IMPLEMENT;
- return TRUE;
-}
/*
* @...: a list of TRUE/FALSE, GValue* -- if TRUE then the following GValue must be freed
Modified: trunk/libgda/sqlite/gda-sqlite-meta.h
==============================================================================
--- trunk/libgda/sqlite/gda-sqlite-meta.h (original)
+++ trunk/libgda/sqlite/gda-sqlite-meta.h Wed Mar 12 21:18:24 2008
@@ -31,29 +31,18 @@
GdaMetaStore *store, GdaMetaContext *context, GError **error);
gboolean _gda_sqlite_meta_btypes (GdaServerProvider *prov, GdaConnection *cnc,
GdaMetaStore *store, GdaMetaContext *context, GError **error);
-gboolean _gda_sqlite_meta_schemata (GdaServerProvider *prov, GdaConnection *cnc,
- GdaMetaStore *store, GdaMetaContext *context, GError **error,
- const GValue *schema_name);
-gboolean _gda_sqlite_meta_tables_views (GdaServerProvider *prov, GdaConnection *cnc,
- GdaMetaStore *store, GdaMetaContext *context, GError **error);
-gboolean _gda_sqlite_meta_tables_views_s (GdaServerProvider *prov, GdaConnection *cnc,
- GdaMetaStore *store, GdaMetaContext *context, GError **error,
- const GValue *table_schema, const GValue *table_name);
-gboolean _gda_sqlite_meta_columns (GdaServerProvider *prov, GdaConnection *cnc,
- GdaMetaStore *store, GdaMetaContext *context, GError **error);
-gboolean _gda_sqlite_meta_columns_t (GdaServerProvider *prov, GdaConnection *cnc,
- GdaMetaStore *store, GdaMetaContext *context, GError **error,
- const GValue *table_schema, const GValue *table_name);
-gboolean _gda_sqlite_meta_columns_c (GdaServerProvider *prov, GdaConnection *cnc,
- GdaMetaStore *store, GdaMetaContext *context, GError **error,
- const GValue *table_schema, const GValue *table_name, const GValue *column_name);
-gboolean _gda_sqlite_meta_constraints_tab (GdaServerProvider *, GdaConnection *, GdaMetaStore *, GdaMetaContext *, GError **);
-gboolean _gda_sqlite_meta_constraints_tab_s (GdaServerProvider *, GdaConnection *, GdaMetaStore *, GdaMetaContext *, GError **,
- const GValue *table_schema, const GValue *table_name);
-
-gboolean _gda_sqlite_meta_constraints_ref (GdaServerProvider *, GdaConnection *, GdaMetaStore *, GdaMetaContext *, GError **);
-gboolean _gda_sqlite_meta_constraints_ref_c (GdaServerProvider *, GdaConnection *, GdaMetaStore *, GdaMetaContext *, GError **,
- const GValue *table_schema, const GValue *table_name);
+gboolean _gda_sqlite_meta_schemata (GdaServerProvider *, GdaConnection *, GdaMetaStore *, GdaMetaContext *, GError **,
+ const GValue *catalog_name, const GValue *schema_name_n);
+gboolean _gda_sqlite_meta_tables_views (GdaServerProvider *, GdaConnection *, GdaMetaStore *, GdaMetaContext *, GError **,
+ const GValue *table_catalog, const GValue *table_schema, const GValue *table_name_n);
+gboolean _gda_sqlite_meta_columns (GdaServerProvider *, GdaConnection *, GdaMetaStore *, GdaMetaContext *, GError **,
+ const GValue *table_catalog, const GValue *table_schema, const GValue *table_name);
+gboolean _gda_sqlite_meta_constraints_tab (GdaServerProvider *, GdaConnection *, GdaMetaStore *, GdaMetaContext *, GError **,
+ const GValue *table_catalog, const GValue *table_schema, const GValue *table_name,
+ const GValue *constraint_name_n);
+gboolean _gda_sqlite_meta_constraints_ref (GdaServerProvider *, GdaConnection *, GdaMetaStore *, GdaMetaContext *, GError **,
+ const GValue *table_catalog, const GValue *table_schema, const GValue *table_name,
+ const GValue *constraint_name);
G_END_DECLS
#endif
Modified: trunk/libgda/sqlite/gda-sqlite-provider.c
==============================================================================
--- trunk/libgda/sqlite/gda-sqlite-provider.c (original)
+++ trunk/libgda/sqlite/gda-sqlite-provider.c Wed Mar 12 21:18:24 2008
@@ -227,18 +227,13 @@
provider_class->statement_execute = gda_sqlite_provider_statement_execute;
memset (&(provider_class->meta_funcs), 0, sizeof (GdaServerProviderMeta));
- provider_class->meta_funcs.info = _gda_sqlite_meta_info;
- provider_class->meta_funcs.btypes = _gda_sqlite_meta_btypes;
+ provider_class->meta_funcs._info = _gda_sqlite_meta_info;
+ provider_class->meta_funcs._btypes = _gda_sqlite_meta_btypes;
provider_class->meta_funcs.schemata = _gda_sqlite_meta_schemata;
provider_class->meta_funcs.tables_views = _gda_sqlite_meta_tables_views;
- provider_class->meta_funcs.tables_views_s = _gda_sqlite_meta_tables_views_s;
provider_class->meta_funcs.columns = _gda_sqlite_meta_columns;
- provider_class->meta_funcs.columns_t = _gda_sqlite_meta_columns_t;
- provider_class->meta_funcs.columns_c = _gda_sqlite_meta_columns_c;
provider_class->meta_funcs.constraints_tab = _gda_sqlite_meta_constraints_tab;
- provider_class->meta_funcs.constraints_tab_s = _gda_sqlite_meta_constraints_tab_s;
provider_class->meta_funcs.constraints_ref = _gda_sqlite_meta_constraints_ref;
- provider_class->meta_funcs.constraints_ref_c = _gda_sqlite_meta_constraints_ref_c;
}
static void
@@ -479,7 +474,6 @@
GdaQuarkList *params, GdaQuarkList *auth,
guint *task_id, GdaServerProviderAsyncCallback async_cb, gpointer cb_data)
{
- static gint nb_opened = 1;
gchar *filename = NULL;
const gchar *dirname = NULL, *dbname = NULL;
const gchar *is_virtual = NULL;
@@ -581,12 +575,11 @@
opening_cdata = cdata;
#endif
- errmsg = sqlite3_open (filename, &cdata->connection);
- g_print ("SQLite opened %d connection(s)\n", nb_opened++);
-
if (filename)
cdata->file = g_strdup (filename);
+ errmsg = sqlite3_open (filename, &cdata->connection);
+
if (errmsg != SQLITE_OK) {
gda_connection_add_event_string (cnc, sqlite3_errmsg (cdata->connection));
gda_sqlite_free_cnc_data (cdata);
@@ -596,6 +589,7 @@
#endif
return FALSE;
}
+
gda_connection_internal_set_provider_data (cnc, cdata, (GDestroyNotify) gda_sqlite_free_cnc_data);
/* use extended result codes */
Modified: trunk/libgda/sqlite/utils.c
==============================================================================
--- trunk/libgda/sqlite/utils.c (original)
+++ trunk/libgda/sqlite/utils.c Wed Mar 12 21:18:24 2008
@@ -73,6 +73,22 @@
return aff;
}
+static guint
+nocase_str_hash (gconstpointer v)
+{
+ guint ret;
+ gchar *up = g_ascii_strup ((gchar *) v, -1);
+ ret = g_str_hash ((gconstpointer) up);
+ g_free (up);
+ return ret;
+}
+
+static gboolean
+nocase_str_equal (gconstpointer v1, gconstpointer v2)
+{
+ return g_ascii_strcasecmp ((gchar *) v1, (gchar *) v2) == 0 ? TRUE : FALSE;
+}
+
void
_gda_sqlite_update_types_hash (SqliteConnectionData *cdata)
{
@@ -82,7 +98,7 @@
types = cdata->types;
if (!types) {
- types = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); /* key= type name, value= gda type */
+ types = g_hash_table_new_full (nocase_str_hash, nocase_str_equal, g_free, NULL); /* key= type name, value= gda type */
cdata->types = types;
}
@@ -93,6 +109,7 @@
g_hash_table_insert (types, g_strdup ("timestamp"), GINT_TO_POINTER (GDA_TYPE_TIMESTAMP));
g_hash_table_insert (types, g_strdup ("real"), GINT_TO_POINTER (G_TYPE_DOUBLE));
g_hash_table_insert (types, g_strdup ("text"), GINT_TO_POINTER (G_TYPE_STRING));
+ g_hash_table_insert (types, g_strdup ("string"), GINT_TO_POINTER (G_TYPE_STRING));
g_hash_table_insert (types, g_strdup ("blob"), GINT_TO_POINTER (GDA_TYPE_BINARY));
/* HACK: force SQLite to reparse the schema and thus discover new tables if necessary */
Modified: trunk/po/POTFILES.in
==============================================================================
--- trunk/po/POTFILES.in (original)
+++ trunk/po/POTFILES.in Wed Mar 12 21:18:24 2008
@@ -1,3 +1,4 @@
+doc/C/prov-writing.xml
libgda/gda-batch.c
libgda/gda-config.c
libgda/gda-connection.c
@@ -110,6 +111,7 @@
providers/mysql/mysql_specs_drop_view.xml.in
providers/mysql/mysql_specs_dsn.xml.in
providers/mysql/mysql_specs_rename_table.xml.in
+providers/odbc/gda-odbc-provider.c
providers/odbc/gda-odbc-recordset.c
providers/odbc/libmain.c
providers/odbc/odbc_specs_dsn.xml.in
@@ -158,9 +160,12 @@
providers/sqlite/sqlite_specs_drop_view.xml.in
providers/sqlite/sqlite_specs_dsn.xml.in
providers/sqlite/sqlite_specs_rename_table.xml.in
+providers/sybase/gda-sybase-provider.c
providers/sybase/gda-sybase-recordset.c
+providers/sybase/gda-sybase-types.c
providers/sybase/libmain.c
providers/sybase/sybase_specs_dsn.xml.in
+providers/sybase/utils.c
providers/xbase/gda-xbase-provider.c
providers/xbase/libmain.c
providers/xbase/xbase_specs_dsn.xml.in
Modified: trunk/po/POTFILES.skip
==============================================================================
--- trunk/po/POTFILES.skip (original)
+++ trunk/po/POTFILES.skip Wed Mar 12 21:18:24 2008
@@ -1,3 +1,7 @@
+libgda/sql-parser/delimiter.c
+libgda/sql-parser/parser.c
+libgda/sqlite/sqlite-src/sqlite3.c
+providers/postgres/parser.c
providers/skel-implementation/capi/capi_specs_create_table.xml.in
providers/skel-implementation/capi/capi_specs_dsn.xml.in
providers/skel-implementation/capi/gda-capi-blob-op.c
Modified: trunk/providers/postgres/gda-postgres-ddl.c
==============================================================================
--- trunk/providers/postgres/gda-postgres-ddl.c (original)
+++ trunk/providers/postgres/gda-postgres-ddl.c Wed Mar 12 21:18:24 2008
@@ -25,8 +25,79 @@
#include "gda-postgres-ddl.h"
gchar *
+gda_postgres_render_CREATE_DB (GdaServerProvider *provider, GdaConnection *cnc,
+ GdaServerOperation *op, GError **error)
+{
+ GString *string;
+ const GValue *value;
+ gchar *sql = NULL;
+
+ string = g_string_new ("CREATE DATABASE ");
+
+ value = gda_server_operation_get_value_at (op, "/DB_DEF_P/DB_NAME");
+ g_assert (value && G_VALUE_HOLDS (value, G_TYPE_STRING));
+ g_string_append_printf (string, "\"%s\"", g_value_get_string (value));
+
+ value = gda_server_operation_get_value_at (op, "/DB_DEF_P/OWNER");
+ if (value && G_VALUE_HOLDS (value, G_TYPE_STRING) && g_value_get_string (value)) {
+ g_string_append (string, " OWNER ");
+ g_string_append (string, g_value_get_string (value));
+ }
+
+ value = gda_server_operation_get_value_at (op, "/DB_DEF_P/TEMPLATE");
+ if (value && G_VALUE_HOLDS (value, G_TYPE_STRING) && g_value_get_string (value)) {
+ g_string_append (string, " TEMPLATE ");
+ g_string_append (string, g_value_get_string (value));
+ }
+
+ value = gda_server_operation_get_value_at (op, "/DB_DEF_P/DB_CSET");
+ if (value && G_VALUE_HOLDS (value, G_TYPE_STRING) && g_value_get_string (value)) {
+ GdaDataHandler *dh;
+ gchar *str;
+
+ dh = gda_server_provider_get_data_handler_gtype (provider, cnc, G_TYPE_STRING);
+ str = gda_data_handler_get_sql_from_value (dh, value);
+
+ g_string_append (string, " ENCODING ");
+ g_string_append (string, str);
+ g_free (str);
+ }
+
+ value = gda_server_operation_get_value_at (op, "/DB_DEF_P/TABLESPACE");
+ if (value && G_VALUE_HOLDS (value, G_TYPE_STRING) && g_value_get_string (value)) {
+ g_string_append (string, " TABLESPACE ");
+ g_string_append (string, g_value_get_string (value));
+ }
+
+ sql = string->str;
+ g_string_free (string, FALSE);
+
+ return sql;
+}
+
+gchar *
+gda_postgres_render_DROP_DB (GdaServerProvider *provider, GdaConnection *cnc,
+ GdaServerOperation *op, GError **error)
+{
+ GString *string;
+ const GValue *value;
+ gchar *sql = NULL;
+
+ string = g_string_new ("DROP DATABASE ");
+
+ value = gda_server_operation_get_value_at (op, "/DB_DESC_P/DB_NAME");
+ g_assert (value && G_VALUE_HOLDS (value, G_TYPE_STRING));
+ g_string_append_printf (string, "\"%s\"", g_value_get_string (value));
+
+ sql = string->str;
+ g_string_free (string, FALSE);
+
+ return sql;
+}
+
+gchar *
gda_postgres_render_CREATE_TABLE (GdaServerProvider *provider, GdaConnection *cnc,
- GdaServerOperation *op, GError **error)
+ GdaServerOperation *op, GError **error)
{
GString *string;
const GValue *value;
@@ -39,8 +110,11 @@
gint nbpkfields = 0;
gchar *sql = NULL;
- /* CREATE TABLE */
- string = g_string_new ("CREATE TABLE ");
+ string = g_string_new ("CREATE ");
+ value = gda_server_operation_get_value_at (op, "/TABLE_DEF_P/TABLE_TEMP");
+ if (value && G_VALUE_HOLDS (value, G_TYPE_BOOLEAN) && g_value_get_boolean (value))
+ g_string_append (string, "TEMP ");
+ g_string_append (string, "TABLE ");
value = gda_server_operation_get_value_at (op, "/TABLE_DEF_P/TABLE_NAME");
g_assert (value && G_VALUE_HOLDS (value, G_TYPE_STRING));
@@ -74,9 +148,12 @@
g_string_append (string, ", ");
value = gda_server_operation_get_value_at (op, "/FIELDS_A/@COLUMN_NAME/%d", i);
+ g_string_append_c (string, '\"');
g_string_append (string, g_value_get_string (value));
+ g_string_append_c (string, '\"');
g_string_append_c (string, ' ');
-
+
+
value = gda_server_operation_get_value_at (op, "/FIELDS_A/@COLUMN_AUTOINC/%d", i);
if (value)
g_string_append (string, "serial");
@@ -85,6 +162,17 @@
g_string_append (string, g_value_get_string (value));
}
+ value = gda_server_operation_get_value_at (op, "/FIELDS_A/@COLUMN_SIZE/%d", i);
+ if (value && G_VALUE_HOLDS (value, G_TYPE_UINT)) {
+ g_string_append_printf (string, "(%d", g_value_get_uint (value));
+
+ value = gda_server_operation_get_value_at (op, "/FIELDS_A/@COLUMN_SCALE/%d", i);
+ if (value && G_VALUE_HOLDS (value, G_TYPE_UINT))
+ g_string_append_printf (string, ",%d)", g_value_get_uint (value));
+ else
+ g_string_append (string, ")");
+ }
+
value = gda_server_operation_get_value_at (op, "/FIELDS_A/@COLUMN_DEFAULT/%d", i);
if (value && G_VALUE_HOLDS (value, G_TYPE_STRING)) {
const gchar *str = g_value_get_string (value);
@@ -97,7 +185,7 @@
value = gda_server_operation_get_value_at (op, "/FIELDS_A/@COLUMN_NNUL/%d", i);
if (value && G_VALUE_HOLDS (value, G_TYPE_BOOLEAN) && g_value_get_boolean (value))
g_string_append (string, " NOT NULL");
-
+
value = gda_server_operation_get_value_at (op, "/FIELDS_A/@COLUMN_UNIQUE/%d", i);
if (value && G_VALUE_HOLDS (value, G_TYPE_BOOLEAN) && g_value_get_boolean (value))
g_string_append (string, " UNIQUE");
@@ -118,6 +206,33 @@
}
}
}
+
+ /* LIKE inheritance */
+ nrows = gda_server_operation_get_sequence_size (op, "/TABLE_PARENTS_S");
+ for (i = 0; i < nrows; i++) {
+ value = gda_server_operation_get_value_at (op, "/TABLE_PARENTS_S/%d/TABLE_PARENT_COPY", i);
+ if (value && G_VALUE_HOLDS (value, G_TYPE_BOOLEAN) && !g_value_get_boolean (value)) {
+ value = gda_server_operation_get_value_at (op, "/TABLE_PARENTS_S/%d/TABLE_PARENT_TABLE", i);
+ if (value && G_VALUE_HOLDS (value, G_TYPE_STRING)) {
+ const gchar *str = g_value_get_string (value);
+ if (str && *str) {
+ hasfields = TRUE;
+ if (first)
+ first = FALSE;
+ else
+ g_string_append (string, ", ");
+
+ g_string_append (string, "LIKE ");
+ g_string_append (string, str);
+ value = gda_server_operation_get_value_at (op,
+ "/TABLE_PARENTS_S/%d/TABLE_PARENT_COPY_DEFAULTS", i);
+ if (value && G_VALUE_HOLDS (value, G_TYPE_BOOLEAN) &&
+ g_value_get_boolean (value))
+ g_string_append (string, " INCLUDING DEFAULTS");
+ }
+ }
+ }
+ }
}
/* composed primary key */
@@ -128,20 +243,397 @@
while (list) {
if (list != pkfields)
g_string_append (string, ", ");
+ g_string_append_c (string, '\"');
g_string_append (string, g_value_get_string ((GValue*) list->data));
+ g_string_append_c (string, '\"');
list = list->next;
}
g_string_append_c (string, ')');
}
+ /* foreign keys */
+ if (allok) {
+ GdaServerOperationNode *node;
+
+ first = TRUE;
+ node = gda_server_operation_get_node_info (op, "/FKEY_S");
+ if (node) {
+ nrows = gda_server_operation_get_sequence_size (op, "/FKEY_S");
+ for (i = 0; i < nrows; i++) {
+ gint nbfields, j;
+
+ g_string_append (string, ", FOREIGN KEY (");
+ node = gda_server_operation_get_node_info (op, "/FKEY_S/%d/FKEY_FIELDS_A", i);
+ if (!node || ((nbfields = gda_data_model_get_n_rows (node->model)) == 0)) {
+ allok = FALSE;
+ g_set_error (error, 0, 0, _("No field specified in foreign key constraint"));
+ }
+ else {
+ for (j = 0; j < nbfields; j++) {
+ if (j != 0)
+ g_string_append (string, ", ");
+ value = gda_server_operation_get_value_at (op,
+ "/FKEY_S/%d/FKEY_FIELDS_A/@FK_FIELD/%d", i, j);
+ if (value && G_VALUE_HOLDS (value, G_TYPE_STRING) && g_value_get_string (value))
+ {
+ g_string_append_c (string, '\"');
+ g_string_append (string, g_value_get_string (value));
+ g_string_append_c (string, '\"');
+ }
+ else {
+ allok = FALSE;
+ g_set_error (error, 0, 0,
+ _("Empty field specified in foreign key constraint"));
+ }
+ }
+ }
+ g_string_append (string, ") REFERENCES ");
+ value = gda_server_operation_get_value_at (op, "/FKEY_S/%d/FKEY_REF_TABLE", i);
+ if (value && G_VALUE_HOLDS (value, G_TYPE_STRING) && g_value_get_string (value))
+ g_string_append (string, g_value_get_string (value));
+ else {
+ allok = FALSE;
+ g_set_error (error, 0, 0, _("No referenced table specified in foreign key constraint"));
+ }
+
+ g_string_append (string, " (");
+ for (j = 0; j < nbfields; j++) {
+ if (j != 0)
+ g_string_append (string, ", ");
+ value = gda_server_operation_get_value_at (op,
+ "/FKEY_S/%d/FKEY_FIELDS_A/@FK_REF_PK_FIELD/%d", i, j);
+ if (value && G_VALUE_HOLDS (value, G_TYPE_STRING) && g_value_get_string (value))
+ {
+ g_string_append_c (string, '\"');
+ g_string_append (string, g_value_get_string (value));
+ g_string_append_c (string, '\"');
+ }
+ else {
+ allok = FALSE;
+ g_set_error (error, 0, 0,
+ _("Empty referenced field specified in foreign key constraint"));
+ }
+ }
+ g_string_append_c (string, ')');
+ value = gda_server_operation_get_value_at (op, "/FKEY_S/%d/FKEY_MATCH_TYPE", i);
+ if (value && G_VALUE_HOLDS (value, G_TYPE_STRING) && g_value_get_string (value))
+ g_string_append_printf (string, " %s", g_value_get_string (value));
+ value = gda_server_operation_get_value_at (op, "/FKEY_S/%d/FKEY_ONUPDATE", i);
+ if (value && G_VALUE_HOLDS (value, G_TYPE_STRING) && g_value_get_string (value))
+ g_string_append_printf (string, " ON UPDATE %s", g_value_get_string (value));
+ value = gda_server_operation_get_value_at (op, "/FKEY_S/%d/FKEY_ONDELETE", i);
+ if (value && G_VALUE_HOLDS (value, G_TYPE_STRING) && g_value_get_string (value))
+ g_string_append_printf (string, " ON DELETE %s", g_value_get_string (value));
+ value = gda_server_operation_get_value_at (op, "/FKEY_S/%d/FKEY_DEFERRABLE", i);
+ if (value && G_VALUE_HOLDS (value, G_TYPE_STRING) && g_value_get_string (value))
+ g_string_append_printf (string, " %s", g_value_get_string (value));
+ }
+ }
+ }
+
g_string_append (string, ")");
+ /* INHERITS */
+ first = TRUE;
+ nrows = gda_server_operation_get_sequence_size (op, "/TABLE_PARENTS_S");
+ for (i = 0; i < nrows; i++) {
+ value = gda_server_operation_get_value_at (op, "/TABLE_PARENTS_S/%d/TABLE_PARENT_COPY", i);
+ if (value && G_VALUE_HOLDS (value, G_TYPE_BOOLEAN) && g_value_get_boolean (value)) {
+ value = gda_server_operation_get_value_at (op, "/TABLE_PARENTS_S/%d/TABLE_PARENT_TABLE", i);
+ if (value && G_VALUE_HOLDS (value, G_TYPE_STRING)) {
+ const gchar *str = g_value_get_string (value);
+ if (str && *str) {
+ hasfields = TRUE;
+ if (first) {
+ g_string_append (string, " INHERITS ");
+ first = FALSE;
+ }
+ else
+ g_string_append (string, ", ");
+ g_string_append (string, str);
+ }
+ }
+ }
+ }
+
if (!hasfields) {
allok = FALSE;
g_set_error (error, 0, 0, _("Table to create must have at least one row"));
}
+
+ if (allok) {
+ value = gda_server_operation_get_value_at (op, "/TABLE_DEF_P/TABLE_WITH_OIDS");
+ if (value && G_VALUE_HOLDS (value, G_TYPE_BOOLEAN) && g_value_get_boolean (value))
+ g_string_append (string, " WITH OIDS");
+ }
+
g_slist_free (pkfields);
+
+ sql = string->str;
+ g_string_free (string, FALSE);
+
+ return sql;
+}
+
+gchar *
+gda_postgres_render_DROP_TABLE (GdaServerProvider *provider, GdaConnection *cnc,
+ GdaServerOperation *op, GError **error)
+{
+ GString *string;
+ const GValue *value;
+ gchar *sql = NULL;
+
+ string = g_string_new ("DROP TABLE ");
+
+ value = gda_server_operation_get_value_at (op, "/TABLE_DESC_P/TABLE_NAME");
+ g_assert (value && G_VALUE_HOLDS (value, G_TYPE_STRING));
+ g_string_append (string, g_value_get_string (value));
+
+ value = gda_server_operation_get_value_at (op, "/TABLE_DESC_P/REFERENCED_ACTION");
+ if (value && G_VALUE_HOLDS (value, G_TYPE_STRING)) {
+ g_string_append_c (string, ' ');
+ g_string_append (string, g_value_get_string (value));
+ }
+
+ sql = string->str;
+ g_string_free (string, FALSE);
+
+ return sql;
+}
+
+gchar *
+gda_postgres_render_RENAME_TABLE (GdaServerProvider *provider, GdaConnection *cnc,
+ GdaServerOperation *op, GError **error)
+{
+ GString *string;
+ const GValue *value;
+ gchar *sql = NULL;
+
+ string = g_string_new ("ALTER TABLE ");
+
+ value = gda_server_operation_get_value_at (op, "/TABLE_DESC_P/TABLE_NAME");
+ g_assert (value && G_VALUE_HOLDS (value, G_TYPE_STRING));
+ g_string_append (string, g_value_get_string (value));
+
+ value = gda_server_operation_get_value_at (op, "/TABLE_DESC_P/TABLE_NEW_NAME");
+ g_assert (value && G_VALUE_HOLDS (value, G_TYPE_STRING));
+ g_string_append (string, " RENAME TO ");
+ g_string_append (string, g_value_get_string (value));
+
+ sql = string->str;
+ g_string_free (string, FALSE);
+
+ return sql;
+}
+
+
+gchar *
+gda_postgres_render_ADD_COLUMN (GdaServerProvider *provider, GdaConnection *cnc,
+ GdaServerOperation *op, GError **error)
+{
+ GString *string;
+ const GValue *value;
+ gchar *sql = NULL;
+
+ string = g_string_new ("ALTER TABLE ");
+
+ value = gda_server_operation_get_value_at (op, "/COLUMN_DEF_P/TABLE_ONLY");
+ if (value && G_VALUE_HOLDS (value, G_TYPE_BOOLEAN) && g_value_get_boolean (value))
+ g_string_append (string, "ONLY ");
+
+ value = gda_server_operation_get_value_at (op, "/COLUMN_DEF_P/TABLE_NAME");
+ g_assert (value && G_VALUE_HOLDS (value, G_TYPE_STRING));
+ g_string_append (string, g_value_get_string (value));
+
+ g_string_append (string, " ADD COLUMN ");
+
+ value = gda_server_operation_get_value_at (op, "/COLUMN_DEF_P/COLUMN_NAME");
+ g_assert (value && G_VALUE_HOLDS (value, G_TYPE_STRING));
+ g_string_append (string, g_value_get_string (value));
+
+ value = gda_server_operation_get_value_at (op, "/COLUMN_DEF_P/COLUMN_TYPE");
+ g_assert (value && G_VALUE_HOLDS (value, G_TYPE_STRING));
+ g_string_append_c (string, ' ');
+ g_string_append (string, g_value_get_string (value));
+
+ value = gda_server_operation_get_value_at (op, "/COLUMN_DEF_P/COLUMN_SIZE");
+ if (value && G_VALUE_HOLDS (value, G_TYPE_UINT)) {
+ g_string_append_printf (string, "(%d", g_value_get_uint (value));
+
+ value = gda_server_operation_get_value_at (op, "/COLUMN_DEF_P/COLUMN_SCALE");
+ if (value && G_VALUE_HOLDS (value, G_TYPE_UINT))
+ g_string_append_printf (string, ",%d)", g_value_get_uint (value));
+ else
+ g_string_append (string, ")");
+ }
+
+ value = gda_server_operation_get_value_at (op, "/COLUMN_DEF_P/COLUMN_DEFAULT");
+ if (value && G_VALUE_HOLDS (value, G_TYPE_STRING)) {
+ const gchar *str = g_value_get_string (value);
+ if (str && *str) {
+ g_string_append (string, " DEFAULT ");
+ g_string_append (string, str);
+ }
+ }
+
+ value = gda_server_operation_get_value_at (op, "/COLUMN_DEF_P/COLUMN_NNUL");
+ if (value && G_VALUE_HOLDS (value, G_TYPE_BOOLEAN) && g_value_get_boolean (value))
+ g_string_append (string, " NOT NULL");
+
+ value = gda_server_operation_get_value_at (op, "/COLUMN_DEF_P/COLUMN_UNIQUE");
+ if (value && G_VALUE_HOLDS (value, G_TYPE_BOOLEAN) && g_value_get_boolean (value))
+ g_string_append (string, " UNIQUE");
+
+ value = gda_server_operation_get_value_at (op, "/COLUMN_DEF_P/COLUMN_PKEY");
+ if (value && G_VALUE_HOLDS (value, G_TYPE_BOOLEAN) && g_value_get_boolean (value))
+ g_string_append (string, " PRIMARY KEY");
+
+ value = gda_server_operation_get_value_at (op, "/COLUMN_DEF_P/COLUMN_CHECK");
+ if (value && G_VALUE_HOLDS (value, G_TYPE_STRING)) {
+ const gchar *str = g_value_get_string (value);
+ if (str && *str) {
+ g_string_append (string, " CHECK (");
+ g_string_append (string, str);
+ g_string_append_c (string, ')');
+ }
+ }
+
+ sql = string->str;
+ g_string_free (string, FALSE);
+
+ return sql;
+}
+
+gchar *
+gda_postgres_render_DROP_COLUMN (GdaServerProvider *provider, GdaConnection *cnc,
+ GdaServerOperation *op, GError **error)
+{
+ GString *string;
+ const GValue *value;
+ gchar *sql = NULL;
+
+ string = g_string_new ("ALTER TABLE ");
+
+ value = gda_server_operation_get_value_at (op, "/COLUMN_DESC_P/TABLE_NAME");
+ g_assert (value && G_VALUE_HOLDS (value, G_TYPE_STRING));
+ g_string_append (string, g_value_get_string (value));
+
+ value = gda_server_operation_get_value_at (op, "/COLUMN_DESC_P/COLUMN_NAME");
+ g_assert (value && G_VALUE_HOLDS (value, G_TYPE_STRING));
+ g_string_append (string, " DROP COLUMN ");
+ g_string_append (string, g_value_get_string (value));
+
+ value = gda_server_operation_get_value_at (op, "/COLUMN_DESC_P/REFERENCED_ACTION");
+ if (value && G_VALUE_HOLDS (value, G_TYPE_STRING)) {
+ const gchar *str = g_value_get_string (value);
+ if (str && *str) {
+ g_string_append_c (string, ' ');
+ g_string_append (string, str);
+ }
+ }
+
+ sql = string->str;
+ g_string_free (string, FALSE);
+
+ return sql;
+}
+
+
+gchar *
+gda_postgres_render_CREATE_INDEX (GdaServerProvider *provider, GdaConnection *cnc,
+ GdaServerOperation *op, GError **error)
+{
+ GString *string;
+ const GValue *value;
+ gchar *sql = NULL;
+ GdaServerOperationNode *node;
+ gint nrows, i;
+
+ string = g_string_new ("CREATE ");
+
+ value = gda_server_operation_get_value_at (op, "/INDEX_DEF_P/INDEX_TYPE");
+ if (value && G_VALUE_HOLDS (value, G_TYPE_STRING) &&
+ g_value_get_string (value) && *g_value_get_string (value)) {
+ g_string_append (string, g_value_get_string (value));
+ g_string_append_c (string, ' ');
+ }
+
+ g_string_append (string, "INDEX ");
+
+ value = gda_server_operation_get_value_at (op, "/INDEX_DEF_P/INDEX_NAME");
+ g_assert (value && G_VALUE_HOLDS (value, G_TYPE_STRING));
+ g_string_append (string, g_value_get_string (value));
+
+ g_string_append (string, " ON ");
+
+ value = gda_server_operation_get_value_at (op, "/INDEX_DEF_P/INDEX_ON_TABLE");
+ g_assert (value && G_VALUE_HOLDS (value, G_TYPE_STRING));
+ g_string_append (string, g_value_get_string (value));
+
+ value = gda_server_operation_get_value_at (op, "/INDEX_DEF_P/INDEX_METHOD");
+ if (value && G_VALUE_HOLDS (value, G_TYPE_STRING) && g_value_get_string (value)) {
+ g_string_append (string, " USING ");
+ g_string_append (string, g_value_get_string (value));
+ }
+
+ /* fields or expressions the index is on */
+ g_string_append (string, " (");
+ node = gda_server_operation_get_node_info (op, "/INDEX_FIELDS_S");
+ g_assert (node);
+ nrows = gda_server_operation_get_sequence_size (op, "/INDEX_FIELDS_S");
+ for (i = 0; i < nrows; i++) {
+ value = gda_server_operation_get_value_at (op, "/INDEX_FIELDS_S/%d/INDEX_FIELD", i);
+ if (value && G_VALUE_HOLDS (value, G_TYPE_STRING) && g_value_get_string (value)) {
+ if (i != 0)
+ g_string_append (string, ", ");
+ g_string_append_c (string, '\"');
+ g_string_append (string, g_value_get_string (value));
+ g_string_append_c (string, '\"');
+ }
+ }
+
+ g_string_append (string, ")");
+
+ /* options */
+ value = gda_server_operation_get_value_at (op, "/INDEX_DEF_P/INDEX_TABLESPACE");
+ if (value && G_VALUE_HOLDS (value, G_TYPE_STRING) && g_value_get_string (value)) {
+ g_string_append (string, " TABLESPACE ");
+ g_string_append (string, g_value_get_string (value));
+ }
+
+ value = gda_server_operation_get_value_at (op, "/INDEX_DEF_P/INDEX_PREDICATE");
+ if (value && G_VALUE_HOLDS (value, G_TYPE_STRING) && g_value_get_string (value)) {
+ g_string_append (string, " WHERE ");
+ g_string_append (string, g_value_get_string (value));
+ }
+
+ sql = string->str;
+ g_string_free (string, FALSE);
+
+ return sql;
+}
+
+gchar *
+gda_postgres_render_DROP_INDEX (GdaServerProvider *provider, GdaConnection *cnc,
+ GdaServerOperation *op, GError **error)
+{
+ GString *string;
+ const GValue *value;
+ gchar *sql = NULL;
+
+ string = g_string_new ("DROP INDEX ");
+
+ value = gda_server_operation_get_value_at (op, "/INDEX_DESC_P/INDEX_NAME");
+ g_assert (value && G_VALUE_HOLDS (value, G_TYPE_STRING));
+ g_string_append (string, g_value_get_string (value));
+
+ value = gda_server_operation_get_value_at (op, "/INDEX_DESC_P/REFERENCED_ACTION");
+ if (value && G_VALUE_HOLDS (value, G_TYPE_STRING)) {
+ g_string_append_c (string, ' ');
+ g_string_append (string, g_value_get_string (value));
+ }
+
sql = string->str;
g_string_free (string, FALSE);
Modified: trunk/providers/postgres/gda-postgres-meta.c
==============================================================================
--- trunk/providers/postgres/gda-postgres-meta.c (original)
+++ trunk/providers/postgres/gda-postgres-meta.c Wed Mar 12 21:18:24 2008
@@ -41,16 +41,15 @@
typedef enum {
I_STMT_CATALOG,
I_STMT_BTYPES,
- I_STMT_SCHEMATA,
+ I_STMT_SCHEMAS,
+ I_STMT_SCHEMA_NAMED,
I_STMT_TABLES,
+ I_STMT_TABLE_NAMED,
I_STMT_VIEWS,
- I_STMT_TABLES_S,
- I_STMT_VIEWS_S,
- I_STMT_ALLCOLUMNS,
+ I_STMT_VIEW_NAMED,
I_STMT_COLUMNS_OF_TABLE,
- I_STMT_ALL_TABLES_CONSTRAINTS,
- I_STMT_TABLE_CONSTRAINTS,
- I_STMT_ALL_REF_CONSTRAINTS,
+ I_STMT_TABLES_CONSTRAINTS,
+ I_STMT_TABLES_CONSTRAINT_NAMED,
I_STMT_REF_CONSTRAINTS
} InternalStatementItem;
@@ -61,30 +60,39 @@
static gchar *internal_sql[] = {
/* I_STMT_CATALOG */
"SELECT pg_catalog.current_database()",
+
/* I_STMT_BTYPES */
"SELECT t.typname, 'pg_catalog.' || t.typname, 'gchararray', pg_catalog.obj_description(t.oid), NULL, CASE WHEN t.typname ~ '^_' THEN TRUE WHEN typtype = 'p' THEN TRUE WHEN t.typname in ('any', 'anyarray', 'anyelement', 'cid', 'cstring', 'int2vector', 'internal', 'language_handler', 'oidvector', 'opaque', 'record', 'refcursor', 'regclass', 'regoper', 'regoperator', 'regproc', 'regprocedure', 'regtype', 'SET', 'smgr', 'tid', 'trigger', 'unknown', 'void', 'xid', 'oid', 'aclitem') THEN TRUE ELSE FALSE END, CAST (t.oid AS int8) FROM pg_catalog.pg_type t, pg_catalog.pg_user u, pg_catalog.pg_namespace n WHERE t.typowner=u.usesysid AND n.oid = t.typnamespace AND pg_catalog.pg_type_is_visible(t.oid) AND (typtype='b' OR typtype='p')",
- /* I_STMT_SCHEMATA */
- "SELECT catalog_name, schema_name, schema_owner, CASE WHEN schema_name ~'^pg_' THEN TRUE WHEN schema_name ='information_schema' THEN TRUE ELSE FALSE END FROM information_schema.schemata",
+
+ /* I_STMT_SCHEMAS */
+ "SELECT catalog_name, schema_name, schema_owner, CASE WHEN schema_name ~'^pg_' THEN TRUE WHEN schema_name ='information_schema' THEN TRUE ELSE FALSE END FROM information_schema.schemata WHERE catalog_name = ##cat::string",
+
+ /* I_STMT_SCHEMA_NAMED */
+ "SELECT catalog_name, schema_name, schema_owner, CASE WHEN schema_name ~'^pg_' THEN TRUE WHEN schema_name ='information_schema' THEN TRUE ELSE FALSE END FROM information_schema.schemata WHERE catalog_name = ##cat::string AND schema_name = ##name::string",
+
/* I_STMT_TABLES */
- "SELECT current_database()::information_schema.sql_identifier AS table_catalog, nc.nspname::information_schema.sql_identifier AS table_schema, c.relname::information_schema.sql_identifier AS table_name, CASE WHEN nc.oid = pg_my_temp_schema() THEN 'LOCAL TEMPORARY'::text WHEN c.relkind = 'r' THEN 'BASE TABLE' WHEN c.relkind = 'v' THEN 'VIEW' ELSE NULL::text END::information_schema.character_data AS table_type, CASE WHEN c.relkind = 'r' THEN TRUE ELSE FALSE END, pg_catalog.obj_description(c.oid), CASE WHEN pg_catalog.pg_table_is_visible(c.oid) IS TRUE AND nc.nspname!='pg_catalog' THEN c.relname ELSE coalesce (nc.nspname || '.', '') || c.relname END, coalesce (nc.nspname || '.', '') || c.relname, o.rolname FROM pg_namespace nc, pg_class c, pg_authid o WHERE c.relnamespace = nc.oid AND (c.relkind = ANY (ARRAY['r', 'v'])) AND NOT pg_is_other_temp_schema(nc.oid) AND (pg_has_role(c.relowner, 'USAGE'::text) OR has_table_privilege(c.oid, 'SELECT'::text) OR has_table_privilege(c.oid,
'INSERT'::text) OR has_table_privilege(c.oid, 'UPDATE'::text) OR has_table_privilege(c.oid, 'DELETE'::text) OR has_table_privilege(c.oid, 'REFERENCES'::text) OR has_table_privilege(c.oid, 'TRIGGER'::text)) AND o.oid=c.relowner",
+ "SELECT current_database()::information_schema.sql_identifier AS table_catalog, nc.nspname::information_schema.sql_identifier AS table_schema, c.relname::information_schema.sql_identifier AS table_name, CASE WHEN nc.oid = pg_my_temp_schema() THEN 'LOCAL TEMPORARY'::text WHEN c.relkind = 'r' THEN 'BASE TABLE' WHEN c.relkind = 'v' THEN 'VIEW' ELSE NULL::text END::information_schema.character_data AS table_type, CASE WHEN c.relkind = 'r' THEN TRUE ELSE FALSE END, pg_catalog.obj_description(c.oid), CASE WHEN pg_catalog.pg_table_is_visible(c.oid) IS TRUE AND nc.nspname!='pg_catalog' THEN c.relname ELSE coalesce (nc.nspname || '.', '') || c.relname END, coalesce (nc.nspname || '.', '') || c.relname, o.rolname FROM pg_namespace nc, pg_class c, pg_authid o WHERE current_database()::information_schema.sql_identifier = ##cat::string AND nc.nspname::information_schema.sql_identifier = ##schema::string AND c.relnamespace = nc.oid AND (c.relkind = ANY (ARRAY['r', 'v'])) AND NOT pg_is_ot
her_temp_schema(nc.oid) AND (pg_has_role(c.relowner, 'USAGE'::text) OR has_table_privilege(c.oid, 'SELECT'::text) OR has_table_privilege(c.oid, 'INSERT'::text) OR has_table_privilege(c.oid, 'UPDATE'::text) OR has_table_privilege(c.oid, 'DELETE'::text) OR has_table_privilege(c.oid, 'REFERENCES'::text) OR has_table_privilege(c.oid, 'TRIGGER'::text)) AND o.oid=c.relowner",
+
+ /* I_STMT_TABLE_NAMED */
+ "SELECT current_database()::information_schema.sql_identifier AS table_catalog, nc.nspname::information_schema.sql_identifier AS table_schema, c.relname::information_schema.sql_identifier AS table_name, CASE WHEN nc.oid = pg_my_temp_schema() THEN 'LOCAL TEMPORARY'::text WHEN c.relkind = 'r' THEN 'BASE TABLE' WHEN c.relkind = 'v' THEN 'VIEW' ELSE NULL::text END::information_schema.character_data AS table_type, CASE WHEN c.relkind = 'r' THEN TRUE ELSE FALSE END, pg_catalog.obj_description(c.oid), CASE WHEN pg_catalog.pg_table_is_visible(c.oid) IS TRUE AND nc.nspname!='pg_catalog' THEN c.relname ELSE coalesce (nc.nspname || '.', '') || c.relname END, coalesce (nc.nspname || '.', '') || c.relname, o.rolname FROM pg_namespace nc, pg_class c, pg_authid o WHERE current_database()::information_schema.sql_identifier = ##cat::string AND nc.nspname::information_schema.sql_identifier = ##schema::string AND c.relnamespace = nc.oid AND (c.relkind = ANY (ARRAY['r', 'v'])) AND NOT pg_is_ot
her_temp_schema(nc.oid) AND (pg_has_role(c.relowner, 'USAGE'::text) OR has_table_privilege(c.oid, 'SELECT'::text) OR has_table_privilege(c.oid, 'INSERT'::text) OR has_table_privilege(c.oid, 'UPDATE'::text) OR has_table_privilege(c.oid, 'DELETE'::text) OR has_table_privilege(c.oid, 'REFERENCES'::text) OR has_table_privilege(c.oid, 'TRIGGER'::text)) AND o.oid=c.relowner AND c.relname::information_schema.sql_identifier = ##name::string",
+
/* I_STMT_VIEWS */
- "SELECT current_database()::information_schema.sql_identifier AS table_catalog, nc.nspname::information_schema.sql_identifier AS table_schema, c.relname::information_schema.sql_identifier AS table_name, pg_catalog.pg_get_viewdef(c.oid, TRUE), NULL, CASE WHEN c.relkind = 'r'::\"char\" THEN TRUE ELSE FALSE END FROM pg_namespace nc, pg_class c WHERE c.relnamespace = nc.oid AND c.relkind = 'v' AND NOT pg_is_other_temp_schema(nc.oid) AND (pg_has_role(c.relowner, 'USAGE'::text) OR has_table_privilege(c.oid, 'SELECT'::text) OR has_table_privilege(c.oid, 'INSERT'::text) OR has_table_privilege(c.oid, 'UPDATE'::text) OR has_table_privilege(c.oid, 'DELETE'::text) OR has_table_privilege(c.oid, 'REFERENCES'::text) OR has_table_privilege(c.oid, 'TRIGGER'::text))",
- /* I_STMT_TABLES_S */
- "SELECT current_database()::information_schema.sql_identifier AS table_catalog, nc.nspname::information_schema.sql_identifier AS table_schema, c.relname::information_schema.sql_identifier AS table_name, CASE WHEN nc.oid = pg_my_temp_schema() THEN 'LOCAL TEMPORARY'::text WHEN c.relkind = 'r' THEN 'BASE TABLE' WHEN c.relkind = 'v' THEN 'VIEW' ELSE NULL::text END::information_schema.character_data AS table_type, CASE WHEN c.relkind = 'r' THEN TRUE ELSE FALSE END, pg_catalog.obj_description(c.oid), CASE WHEN pg_catalog.pg_table_is_visible(c.oid) IS TRUE AND nc.nspname!='pg_catalog' THEN c.relname ELSE coalesce (nc.nspname || '.', '') || c.relname END, coalesce (nc.nspname || '.', '') || c.relname, o.rolname FROM pg_namespace nc, pg_class c, pg_authid o WHERE c.relnamespace = nc.oid AND (c.relkind = ANY (ARRAY['r', 'v'])) AND NOT pg_is_other_temp_schema(nc.oid) AND (pg_has_role(c.relowner, 'USAGE'::text) OR has_table_privilege(c.oid, 'SELECT'::text) OR has_table_privilege(c.oid,
'INSERT'::text) OR has_table_privilege(c.oid, 'UPDATE'::text) OR has_table_privilege(c.oid, 'DELETE'::text) OR has_table_privilege(c.oid, 'REFERENCES'::text) OR has_table_privilege(c.oid, 'TRIGGER'::text)) AND o.oid=c.relowner AND table_schema = ##schema::string",
- /* I_STMT_VIEWS_S */
- "SELECT current_database()::information_schema.sql_identifier AS table_catalog, nc.nspname::information_schema.sql_identifier AS table_schema, c.relname::information_schema.sql_identifier AS table_name, pg_catalog.pg_get_viewdef(c.oid, TRUE), NULL, CASE WHEN c.relkind = 'r'::\"char\" THEN TRUE ELSE FALSE END FROM pg_namespace nc, pg_class c WHERE c.relnamespace = nc.oid AND c.relkind = 'v' AND NOT pg_is_other_temp_schema(nc.oid) AND (pg_has_role(c.relowner, 'USAGE'::text) OR has_table_privilege(c.oid, 'SELECT'::text) OR has_table_privilege(c.oid, 'INSERT'::text) OR has_table_privilege(c.oid, 'UPDATE'::text) OR has_table_privilege(c.oid, 'DELETE'::text) OR has_table_privilege(c.oid, 'REFERENCES'::text) OR has_table_privilege(c.oid, 'TRIGGER'::text)) AND table_schema = ##schema::string",
- /* I_STMT_ALLCOLUMNS */
- "SELECT current_database(), nc.nspname, c.relname, a.attname, a.attnum, pg_get_expr(ad.adbin, ad.adrelid), CASE WHEN a.attnotnull OR t.typtype = 'd' AND t.typnotnull THEN FALSE ELSE TRUE END, coalesce (nt.nspname || '.', '') || t.typname, CASE WHEN t.typelem <> 0::oid AND t.typlen = -1 THEN 1 ELSE 0 END, CASE WHEN t.typelem <> 0::oid AND t.typlen = -1 THEN 'ARRAY' || 'COL' || current_database() || '.' || nc.nspname || '.' || c.relname || '.' || a.attnum ELSE NULL END, 'gchararray', information_schema._pg_char_max_length(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truetypmod(a.*, t.*)), information_schema._pg_char_octet_length(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truetypmod(a.*, t.*)), information_schema._pg_numeric_precision(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truetypmod(a.*, t.*)), information_schema._pg_numeric_scale(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truety
pmod(a.*, t.*)), information_schema._pg_datetime_precision(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truetypmod(a.*, t.*)), NULL, NULL, NULL, NULL, NULL, NULL, CASE WHEN pg_get_expr(ad.adbin, ad.adrelid) LIKE 'nextval(%' THEN 'AUTO_INCREMENT' ELSE NULL END, CASE WHEN c.relkind = 'r' THEN TRUE ELSE FALSE END, pg_catalog.col_description(c.oid, a.attnum), CAST (t.oid AS int8) FROM pg_attribute a LEFT JOIN pg_attrdef ad ON a.attrelid = ad.adrelid AND a.attnum = ad.adnum, pg_class c, pg_namespace nc, pg_type t JOIN pg_namespace nt ON t.typnamespace = nt.oid LEFT JOIN (pg_type bt JOIN pg_namespace nbt ON bt.typnamespace = nbt.oid) ON t.typtype = 'd' AND t.typbasetype = bt.oid WHERE a.attrelid = c.oid AND a.atttypid = t.oid AND nc.oid = c.relnamespace AND NOT pg_is_other_temp_schema(nc.oid) AND a.attnum > 0 AND NOT a.attisdropped AND (c.relkind = ANY (ARRAY['r', 'v'])) AND (pg_has_role(c.relowner, 'USAGE'::text) OR has_table_privilege(c.oid, 'SELECT'::text)
OR has_table_privilege(c.oid, 'INSERT'::text) OR has_table_privilege(c.oid, 'UPDATE'::text) OR has_table_privilege(c.oid, 'REFERENCES'::text))",
+ "SELECT current_database()::information_schema.sql_identifier AS table_catalog, nc.nspname::information_schema.sql_identifier AS table_schema, c.relname::information_schema.sql_identifier AS table_name, pg_catalog.pg_get_viewdef(c.oid, TRUE), NULL, CASE WHEN c.relkind = 'r'::\"char\" THEN TRUE ELSE FALSE END FROM pg_namespace nc, pg_class c WHERE current_database()::information_schema.sql_identifier = ##cat::string AND nc.nspname::information_schema.sql_identifier = ##schema::string AND c.relnamespace = nc.oid AND c.relkind = 'v' AND NOT pg_is_other_temp_schema(nc.oid) AND (pg_has_role(c.relowner, 'USAGE'::text) OR has_table_privilege(c.oid, 'SELECT'::text) OR has_table_privilege(c.oid, 'INSERT'::text) OR has_table_privilege(c.oid, 'UPDATE'::text) OR has_table_privilege(c.oid, 'DELETE'::text) OR has_table_privilege(c.oid, 'REFERENCES'::text) OR has_table_privilege(c.oid, 'TRIGGER'::text))",
+
+ /* I_STMT_VIEW_NAMED */
+ "SELECT current_database()::information_schema.sql_identifier AS table_catalog, nc.nspname::information_schema.sql_identifier AS table_schema, c.relname::information_schema.sql_identifier AS table_name, pg_catalog.pg_get_viewdef(c.oid, TRUE), NULL, CASE WHEN c.relkind = 'r'::\"char\" THEN TRUE ELSE FALSE END FROM pg_namespace nc, pg_class c WHERE current_database()::information_schema.sql_identifier = ##cat::string AND nc.nspname::information_schema.sql_identifier = ##schema::string AND c.relnamespace = nc.oid AND c.relkind = 'v' AND NOT pg_is_other_temp_schema(nc.oid) AND (pg_has_role(c.relowner, 'USAGE'::text) OR has_table_privilege(c.oid, 'SELECT'::text) OR has_table_privilege(c.oid, 'INSERT'::text) OR has_table_privilege(c.oid, 'UPDATE'::text) OR has_table_privilege(c.oid, 'DELETE'::text) OR has_table_privilege(c.oid, 'REFERENCES'::text) OR has_table_privilege(c.oid, 'TRIGGER'::text)) AND c.relname::information_schema.sql_identifier = ##name::string",
+
/* I_STMT_COLUMNS_OF_TABLE */
- "SELECT current_database(), nc.nspname, c.relname, a.attname, a.attnum, pg_get_expr(ad.adbin, ad.adrelid), CASE WHEN a.attnotnull OR t.typtype = 'd' AND t.typnotnull THEN FALSE ELSE TRUE END, coalesce (nt.nspname || '.', '') || t.typname, CASE WHEN t.typelem <> 0::oid AND t.typlen = -1 THEN 1 ELSE 0 END, CASE WHEN t.typelem <> 0::oid AND t.typlen = -1 THEN 'ARRAY' || 'COL' || current_database() || '.' || nc.nspname || '.' || c.relname || '.' || a.attnum ELSE NULL END, 'gchararray', information_schema._pg_char_max_length(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truetypmod(a.*, t.*)), information_schema._pg_char_octet_length(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truetypmod(a.*, t.*)), information_schema._pg_numeric_precision(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truetypmod(a.*, t.*)), information_schema._pg_numeric_scale(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truety
pmod(a.*, t.*)), information_schema._pg_datetime_precision(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truetypmod(a.*, t.*)), NULL, NULL, NULL, NULL, NULL, NULL, CASE WHEN pg_get_expr(ad.adbin, ad.adrelid) LIKE 'nextval(%' THEN 'AUTO_INCREMENT' ELSE NULL END, CASE WHEN c.relkind = 'r' THEN TRUE ELSE FALSE END, pg_catalog.col_description(c.oid, a.attnum), CAST (t.oid AS int8) FROM pg_attribute a LEFT JOIN pg_attrdef ad ON a.attrelid = ad.adrelid AND a.attnum = ad.adnum, pg_class c, pg_namespace nc, pg_type t JOIN pg_namespace nt ON t.typnamespace = nt.oid LEFT JOIN (pg_type bt JOIN pg_namespace nbt ON bt.typnamespace = nbt.oid) ON t.typtype = 'd' AND t.typbasetype = bt.oid WHERE nc.nspname = ##schema::string AND c.relname = ##tblname::string AND a.attrelid = c.oid AND a.atttypid = t.oid AND nc.oid = c.relnamespace AND NOT pg_is_other_temp_schema(nc.oid) AND a.attnum > 0 AND NOT a.attisdropped AND (c.relkind = ANY (ARRAY['r', 'v'])) AND (pg_has_role(c.re
lowner, 'USAGE'::text) OR has_table_privilege(c.oid, 'SELECT'::text) OR has_table_privilege(c.oid, 'INSERT'::text) OR has_table_privilege(c.oid, 'UPDATE'::text) OR has_table_privilege(c.oid, 'REFERENCES'::text))",
- /* I_STMT_ALL_TABLES_CONSTRAINTS */
- "SELECT constraint_catalog, constraint_schema, constraint_name, table_catalog, table_schema, table_name, constraint_type, CASE WHEN is_deferrable = 'YES' THEN TRUE ELSE FALSE END, CASE WHEN initially_deferred = 'YES' THEN TRUE ELSE FALSE END FROM information_schema.table_constraints",
- /* I_STMT_TABLE_CONSTRAINTS */
- "SELECT constraint_catalog, constraint_schema, constraint_name, table_catalog, table_schema, table_name, constraint_type, CASE WHEN is_deferrable = 'YES' THEN TRUE ELSE FALSE END, CASE WHEN initially_deferred = 'YES' THEN TRUE ELSE FALSE END FROM information_schema.table_constraints WHERE table_schema = ##schema::string AND table_name = ##tblname::string",
- /* I_STMT_ALL_REF_CONSTRAINTS */
- "SELECT constraint_catalog, constraint_schema, constraint_name, unique_constraint_catalog, unique_constraint_schema, unique_constraint_name, match_option, update_rule, delete_rule FROM information_schema.referential_constraints",
+ "SELECT current_database(), nc.nspname, c.relname, a.attname, a.attnum, pg_get_expr(ad.adbin, ad.adrelid), CASE WHEN a.attnotnull OR t.typtype = 'd' AND t.typnotnull THEN FALSE ELSE TRUE END, coalesce (nt.nspname || '.', '') || t.typname, CASE WHEN t.typelem <> 0::oid AND t.typlen = -1 THEN 1 ELSE 0 END, CASE WHEN t.typelem <> 0::oid AND t.typlen = -1 THEN 'ARRAY' || 'COL' || current_database() || '.' || nc.nspname || '.' || c.relname || '.' || a.attnum ELSE NULL END, 'gchararray', information_schema._pg_char_max_length(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truetypmod(a.*, t.*)), information_schema._pg_char_octet_length(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truetypmod(a.*, t.*)), information_schema._pg_numeric_precision(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truetypmod(a.*, t.*)), information_schema._pg_numeric_scale(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truety
pmod(a.*, t.*)), information_schema._pg_datetime_precision(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truetypmod(a.*, t.*)), NULL, NULL, NULL, NULL, NULL, NULL, CASE WHEN pg_get_expr(ad.adbin, ad.adrelid) LIKE 'nextval(%' THEN 'AUTO_INCREMENT' ELSE NULL END, CASE WHEN c.relkind = 'r' THEN TRUE ELSE FALSE END, pg_catalog.col_description(c.oid, a.attnum), CAST (t.oid AS int8) FROM pg_attribute a LEFT JOIN pg_attrdef ad ON a.attrelid = ad.adrelid AND a.attnum = ad.adnum, pg_class c, pg_namespace nc, pg_type t JOIN pg_namespace nt ON t.typnamespace = nt.oid LEFT JOIN (pg_type bt JOIN pg_namespace nbt ON bt.typnamespace = nbt.oid) ON t.typtype = 'd' AND t.typbasetype = bt.oid WHERE current_database() = ##cat::string AND nc.nspname = ##schema::string AND c.relname = ##name::string AND a.attrelid = c.oid AND a.atttypid = t.oid AND nc.oid = c.relnamespace AND NOT pg_is_other_temp_schema(nc.oid) AND a.attnum > 0 AND NOT a.attisdropped AND (c.relkind = ANY (ARR
AY['r', 'v'])) AND (pg_has_role(c.relowner, 'USAGE'::text) OR has_table_privilege(c.oid, 'SELECT'::text) OR has_table_privilege(c.oid, 'INSERT'::text) OR has_table_privilege(c.oid, 'UPDATE'::text) OR has_table_privilege(c.oid, 'REFERENCES'::text))",
+
+ /* I_STMT_TABLES_CONSTRAINTS */
+ "SELECT constraint_catalog, constraint_schema, constraint_name, table_catalog, table_schema, table_name, constraint_type, NULL, CASE WHEN is_deferrable = 'YES' THEN TRUE ELSE FALSE END, CASE WHEN initially_deferred = 'YES' THEN TRUE ELSE FALSE END FROM information_schema.table_constraints WHERE table_catalog = ##cat::string AND table_schema = ##schema::string AND table_name = ##name::string",
+
+ /* I_STMT_TABLES_CONSTRAINT_NAMED */
+ "SELECT constraint_catalog, constraint_schema, constraint_name, table_catalog, table_schema, table_name, constraint_type, NULL, CASE WHEN is_deferrable = 'YES' THEN TRUE ELSE FALSE END, CASE WHEN initially_deferred = 'YES' THEN TRUE ELSE FALSE END FROM information_schema.table_constraints WHERE table_catalog = ##cat::string AND table_schema = ##schema::string AND table_name = ##name::string AND constraint_name = ##name2::string",
+
/* I_STMT_REF_CONSTRAINTS */
- "SELECT constraint_catalog, constraint_schema, constraint_name, unique_constraint_catalog, unique_constraint_schema, unique_constraint_name, match_option, update_rule, delete_rule FROM information_schema.referential_constraints WHERE constraint_schema = ##schema::string AND constraint_name = ##constname::string"
+ " SELECT current_database(), nt.nspname, t.relname, c.conname, current_database(), nref.nspname, ref.relname, pkc.conname, CASE c.confmatchtype WHEN 'f'::\"char\" THEN 'FULL'::text WHEN 'p'::\"char\" THEN 'PARTIAL'::text WHEN 'u'::\"char\" THEN 'NONE'::text ELSE NULL::text END AS match_option, CASE c.confupdtype WHEN 'c'::\"char\" THEN 'CASCADE'::text WHEN 'n'::\"char\" THEN 'SET NULL'::text WHEN 'd'::\"char\" THEN 'SET DEFAULT'::text WHEN 'r'::\"char\" THEN 'RESTRICT'::text WHEN 'a'::\"char\" THEN 'NO ACTION'::text ELSE NULL::text END AS update_rule, CASE c.confdeltype WHEN 'c'::\"char\" THEN 'CASCADE'::text WHEN 'n'::\"char\" THEN 'SET NULL'::text WHEN 'd'::\"char\" THEN 'SET DEFAULT'::text WHEN 'r'::\"char\" THEN 'RESTRICT'::text WHEN 'a'::\"char\" THEN 'NO ACTION'::text ELSE NULL::text END AS delete_rule FROM pg_constraint c INNER JOIN pg_class t ON (c.conrelid=t.oid) INNER JOIN pg_namespace nt ON (nt.oid=t.relnamespace) INNER JOIN pg_class ref ON (c.confrelid=ref.oid)
INNER JOIN pg_namespace nref ON (nref.oid=ref.relnamespace) INNER JOIN pg_constraint pkc ON (c.confrelid = pkc.conrelid AND information_schema._pg_keysequal(c.confkey, pkc.conkey)) WHERE c.contype = 'f' AND current_database() = ##cat::string AND nt.nspname = ##schema::string AND t.relname = ##name::string AND c.conname = ##name2::string"
};
/*
@@ -97,7 +105,7 @@
* global static values
*/
static GdaSqlParser *internal_parser = NULL;
-static GdaSet *pragma_set;
+static GdaSet *i_set;
/*
@@ -125,9 +133,10 @@
}
/* initialize static values here */
- pragma_set = gda_set_new_inline (3, "tblname", G_TYPE_STRING, "",
- "schema", G_TYPE_STRING, "",
- "constname", G_TYPE_STRING, "");
+ i_set = gda_set_new_inline (4, "cat", G_TYPE_STRING, "",
+ "name", G_TYPE_STRING, "",
+ "name2", G_TYPE_STRING, "",
+ "schema", G_TYPE_STRING, "");
}
gboolean
@@ -197,74 +206,62 @@
gboolean
_gda_postgres_meta_schemata (GdaServerProvider *prov, GdaConnection *cnc,
GdaMetaStore *store, GdaMetaContext *context, GError **error,
- const GValue *schema_name)
+ const GValue *catalog_name, const GValue *schema_name_n)
{
GdaDataModel *model;
gboolean retval;
- model = gda_connection_statement_execute_select (cnc, internal_stmt[I_STMT_SCHEMATA], NULL, error);
- if (!model)
- return FALSE;
-
- retval = gda_meta_store_modify (store, context->table_name, model, NULL, error, NULL);
- g_object_unref (model);
-
- return retval;
-}
-
-
-
-gboolean
-_gda_postgres_meta_tables_views (GdaServerProvider *prov, GdaConnection *cnc,
- GdaMetaStore *store, GdaMetaContext *context, GError **error)
-{
- GdaDataModel *tables_model, *views_model;
- gboolean retval = TRUE;
-
- tables_model = gda_connection_statement_execute_select (cnc, internal_stmt[I_STMT_TABLES], NULL, error);
- if (!tables_model)
- return FALSE;
- views_model = gda_connection_statement_execute_select (cnc, internal_stmt[I_STMT_VIEWS], NULL, error);
- if (!views_model) {
- g_object_unref (tables_model);
- return FALSE;
- }
-
- GdaMetaContext c2;
- c2 = *context; /* copy contents, just because we need to modify @context->table_name */
- if (retval) {
- c2.table_name = "_tables";
- retval = gda_meta_store_modify_with_context (store, &c2, tables_model, error);
+ gda_holder_set_value (gda_set_get_holder (i_set, "cat"), catalog_name);
+ if (!schema_name_n) {
+ model = gda_connection_statement_execute_select (cnc, internal_stmt[I_STMT_SCHEMAS], i_set, error);
+ if (!model)
+ return FALSE;
+ retval = gda_meta_store_modify (store, context->table_name, model, NULL, error, NULL);
}
- if (retval) {
- c2.table_name = "_views";
- retval = gda_meta_store_modify_with_context (store, &c2, views_model, error);
+ else {
+ gda_holder_set_value (gda_set_get_holder (i_set, "name"), schema_name_n);
+ model = gda_connection_statement_execute_select (cnc, internal_stmt[I_STMT_SCHEMA_NAMED], i_set, error);
+ if (!model)
+ return FALSE;
+
+ retval = gda_meta_store_modify (store, context->table_name, model, "schema_name = ##name::string", error,
+ "name", schema_name_n, NULL);
}
- g_object_unref (tables_model);
- g_object_unref (views_model);
-
+ g_object_unref (model);
return retval;
}
-
-
gboolean
-_gda_postgres_meta_tables_views_s (GdaServerProvider *prov, GdaConnection *cnc,
- GdaMetaStore *store, GdaMetaContext *context, GError **error,
- const GValue *table_schema, const GValue *table_name)
+_gda_postgres_meta_tables_views (GdaServerProvider *prov, GdaConnection *cnc,
+ GdaMetaStore *store, GdaMetaContext *context, GError **error,
+ const GValue *table_catalog, const GValue *table_schema, const GValue *table_name_n)
{
GdaDataModel *tables_model, *views_model;
gboolean retval = TRUE;
- gda_holder_set_value (gda_set_get_holder (pragma_set, "schema"), table_schema);
- tables_model = gda_connection_statement_execute_select (cnc, internal_stmt[I_STMT_TABLES_S], pragma_set, error);
- if (!tables_model)
- return FALSE;
- views_model = gda_connection_statement_execute_select (cnc, internal_stmt[I_STMT_VIEWS_S], pragma_set, error);
- if (!views_model) {
- g_object_unref (tables_model);
- return FALSE;
+ gda_holder_set_value (gda_set_get_holder (i_set, "cat"), table_catalog);
+ gda_holder_set_value (gda_set_get_holder (i_set, "schema"), table_schema);
+ if (!table_name_n) {
+ tables_model = gda_connection_statement_execute_select (cnc, internal_stmt[I_STMT_TABLES], i_set, error);
+ if (!tables_model)
+ return FALSE;
+ views_model = gda_connection_statement_execute_select (cnc, internal_stmt[I_STMT_VIEWS], i_set, error);
+ if (!views_model) {
+ g_object_unref (tables_model);
+ return FALSE;
+ }
+ }
+ else {
+ gda_holder_set_value (gda_set_get_holder (i_set, "name"), table_name_n);
+ tables_model = gda_connection_statement_execute_select (cnc, internal_stmt[I_STMT_TABLE_NAMED], i_set, error);
+ if (!tables_model)
+ return FALSE;
+ views_model = gda_connection_statement_execute_select (cnc, internal_stmt[I_STMT_VIEW_NAMED], i_set, error);
+ if (!views_model) {
+ g_object_unref (tables_model);
+ return FALSE;
+ }
}
GdaMetaContext c2;
@@ -286,55 +283,8 @@
gboolean
_gda_postgres_meta_columns (GdaServerProvider *prov, GdaConnection *cnc,
- GdaMetaStore *store, GdaMetaContext *context, GError **error)
-{
- GdaDataModel *model, *proxy;
- gboolean retval = TRUE;
- gint i, nrows;
- PostgresConnectionData *cdata;
-
- cdata = (PostgresConnectionData*) gda_connection_internal_get_provider_data (cnc);
- if (!cdata)
- return FALSE;
-
- /* use a prepared statement for the "base" model */
- model = gda_connection_statement_execute_select (cnc, internal_stmt[I_STMT_ALLCOLUMNS], NULL, error);
- if (!model)
- return FALSE;
-
- /* use a proxy to customize @model */
- proxy = (GdaDataModel*) gda_data_proxy_new (model);
- gda_data_proxy_set_sample_size ((GdaDataProxy*) proxy, 0);
- nrows = gda_data_model_get_n_rows (model);
- for (i = 0; i < nrows; i++) {
- const GValue *value;
- GType type;
- value = gda_data_model_get_value_at (model, 25, i);
-
- type = _gda_postgres_type_oid_to_gda (cdata, g_value_get_int64 (value));
- if (type != G_TYPE_STRING) {
- GValue *v;
- g_value_set_string (v = gda_value_new (G_TYPE_STRING), g_type_name (type));
- retval = gda_data_model_set_value_at (proxy, 10, i, v, error);
- gda_value_free (v);
- if (!retval)
- break;
- }
- }
-
- /* modify meta store with @proxy */
- if (retval)
- retval = gda_meta_store_modify (store, context->table_name, proxy, NULL, error, NULL);
- g_object_unref (proxy);
- g_object_unref (model);
-
- return retval;
-}
-
-gboolean
-_gda_postgres_meta_columns_t (GdaServerProvider *prov, GdaConnection *cnc,
- GdaMetaStore *store, GdaMetaContext *context, GError **error,
- const GValue *table_schema, const GValue *table_name)
+ GdaMetaStore *store, GdaMetaContext *context, GError **error,
+ const GValue *table_catalog, const GValue *table_schema, const GValue *table_name)
{
GdaDataModel *model, *proxy;
gboolean retval = TRUE;
@@ -350,9 +300,10 @@
return FALSE;
/* use a prepared statement for the "base" model */
- gda_holder_set_value (gda_set_get_holder (pragma_set, "schema"), table_schema);
- gda_holder_set_value (gda_set_get_holder (pragma_set, "tblname"), table_name);
- model = gda_connection_statement_execute_select_full (cnc, internal_stmt[I_STMT_COLUMNS_OF_TABLE], pragma_set,
+ gda_holder_set_value (gda_set_get_holder (i_set, "cat"), table_catalog);
+ gda_holder_set_value (gda_set_get_holder (i_set, "schema"), table_schema);
+ gda_holder_set_value (gda_set_get_holder (i_set, "name"), table_name);
+ model = gda_connection_statement_execute_select_full (cnc, internal_stmt[I_STMT_COLUMNS_OF_TABLE], i_set,
GDA_STATEMENT_MODEL_RANDOM_ACCESS, col_types, error);
if (!model)
return FALSE;
@@ -379,7 +330,9 @@
/* modify meta store with @proxy */
if (retval)
- retval = gda_meta_store_modify (store, context->table_name, proxy, NULL, error, NULL);
+ retval = gda_meta_store_modify (store, context->table_name, proxy,
+ "table_schema = ##schema::string AND table_name = ##name::string", error,
+ "schema", table_schema, "name", table_name, NULL);
g_object_unref (proxy);
g_object_unref (model);
@@ -387,28 +340,10 @@
}
gboolean
-_gda_postgres_meta_columns_c (GdaServerProvider *prov, GdaConnection *cnc,
- GdaMetaStore *store, GdaMetaContext *context, GError **error,
- const GValue *table_schema, const GValue *table_name, const GValue *column_name)
-{
- GdaDataModel *model;
- gboolean retval = TRUE;
-
- model = gda_meta_store_create_modify_data_model (store, context->table_name);
- g_assert (model);
-
- /* fill in @model */
- TO_IMPLEMENT;
- if (retval)
- retval = gda_meta_store_modify (store, context->table_name, model, NULL, error, NULL);
- g_object_unref (model);
-
- return retval;
-}
-
-gboolean
_gda_postgres_meta_constraints_tab (GdaServerProvider *prov, GdaConnection *cnc,
- GdaMetaStore *store, GdaMetaContext *context, GError **error)
+ GdaMetaStore *store, GdaMetaContext *context, GError **error,
+ const GValue *table_catalog, const GValue *table_schema, const GValue *table_name,
+ const GValue *constraint_name_n)
{
GdaDataModel *model;
gboolean retval = TRUE;
@@ -418,82 +353,45 @@
if (!cdata)
return FALSE;
- /* use a prepared statement for the "base" model */
- model = gda_connection_statement_execute_select (cnc, internal_stmt[I_STMT_ALL_TABLES_CONSTRAINTS], NULL,
- error);
- if (!model)
- return FALSE;
+ gda_holder_set_value (gda_set_get_holder (i_set, "cat"), table_catalog);
+ gda_holder_set_value (gda_set_get_holder (i_set, "schema"), table_schema);
+ gda_holder_set_value (gda_set_get_holder (i_set, "name"), table_name);
+
+ if (!constraint_name_n) {
+ model = gda_connection_statement_execute_select (cnc, internal_stmt[I_STMT_TABLES_CONSTRAINTS], i_set,
+ error);
+ if (!model)
+ return FALSE;
+ if (retval)
+ retval = gda_meta_store_modify (store, context->table_name, model,
+ "table_schema = ##schema::string AND table_name = ##name::string",
+ error,
+ "schema", table_schema, "name", table_name, NULL);
+ }
+ else {
+ gda_holder_set_value (gda_set_get_holder (i_set, "name2"), constraint_name_n);
+ model = gda_connection_statement_execute_select (cnc, internal_stmt[I_STMT_TABLES_CONSTRAINT_NAMED], i_set,
+ error);
+ if (!model)
+ return FALSE;
+ if (retval)
+ retval = gda_meta_store_modify (store, context->table_name, model,
+ "table_schema = ##schema::string AND table_name = ##name::string AND constraint_name = ##name2::string", error,
+ "schema", table_schema, "name", table_name, "name2", constraint_name_n, NULL);
+ }
- /* modify meta store with @proxy */
- if (retval)
- retval = gda_meta_store_modify (store, context->table_name, model, NULL, error, NULL);
g_object_unref (model);
return retval;
}
-gboolean
-_gda_postgres_meta_constraints_tab_s (GdaServerProvider *prov, GdaConnection *cnc,
- GdaMetaStore *store, GdaMetaContext *context, GError **error,
- const GValue *table_schema, const GValue *table_name)
-{
- GdaDataModel *model;
- gboolean retval = TRUE;
- PostgresConnectionData *cdata;
-
- cdata = (PostgresConnectionData*) gda_connection_internal_get_provider_data (cnc);
- if (!cdata)
- return FALSE;
-
- /* use a prepared statement for the "base" model */
- gda_holder_set_value (gda_set_get_holder (pragma_set, "schema"), table_schema);
- gda_holder_set_value (gda_set_get_holder (pragma_set, "tblname"), table_name);
- model = gda_connection_statement_execute_select (cnc, internal_stmt[I_STMT_TABLE_CONSTRAINTS], pragma_set,
- error);
- if (!model)
- return FALSE;
-
-
- /* modify meta store with @proxy */
- if (retval)
- retval = gda_meta_store_modify (store, context->table_name, model, NULL, error, NULL);
- g_object_unref (model);
-
- return retval;
-}
gboolean
_gda_postgres_meta_constraints_ref (GdaServerProvider *prov, GdaConnection *cnc,
- GdaMetaStore *store, GdaMetaContext *context, GError **error)
-{
- GdaDataModel *model;
- gboolean retval = TRUE;
- PostgresConnectionData *cdata;
-
- cdata = (PostgresConnectionData*) gda_connection_internal_get_provider_data (cnc);
- if (!cdata)
- return FALSE;
-
- /* use a prepared statement for the "base" model */
- model = gda_connection_statement_execute_select (cnc, internal_stmt[I_STMT_ALL_REF_CONSTRAINTS], NULL,
- error);
- if (!model)
- return FALSE;
-
-
- /* modify meta store with @proxy */
- if (retval)
- retval = gda_meta_store_modify (store, context->table_name, model, NULL, error, NULL);
- g_object_unref (model);
-
- return retval;
-}
-
-gboolean
-_gda_postgres_meta_constraints_ref_c (GdaServerProvider *prov, GdaConnection *cnc,
- GdaMetaStore *store, GdaMetaContext *context, GError **error,
- const GValue *constraint_schema, const GValue *constraint_name)
+ GdaMetaStore *store, GdaMetaContext *context, GError **error,
+ const GValue *table_catalog, const GValue *table_schema, const GValue *table_name,
+ const GValue *constraint_name)
{
GdaDataModel *model;
gboolean retval = TRUE;
@@ -503,18 +401,22 @@
if (!cdata)
return FALSE;
- /* use a prepared statement for the "base" model */
- gda_holder_set_value (gda_set_get_holder (pragma_set, "schema"), constraint_schema);
- gda_holder_set_value (gda_set_get_holder (pragma_set, "constname"), constraint_name);
- model = gda_connection_statement_execute_select (cnc, internal_stmt[I_STMT_REF_CONSTRAINTS], pragma_set,
+ gda_holder_set_value (gda_set_get_holder (i_set, "cat"), table_catalog);
+ gda_holder_set_value (gda_set_get_holder (i_set, "schema"), table_schema);
+ gda_holder_set_value (gda_set_get_holder (i_set, "name"), table_name);
+ gda_holder_set_value (gda_set_get_holder (i_set, "name2"), constraint_name);
+ model = gda_connection_statement_execute_select (cnc, internal_stmt[I_STMT_REF_CONSTRAINTS], i_set,
error);
if (!model)
return FALSE;
- /* modify meta store with @proxy */
+ /* modify meta store */
if (retval)
- retval = gda_meta_store_modify (store, context->table_name, model, NULL, error, NULL);
+ retval = gda_meta_store_modify (store, context->table_name, model,
+ "table_schema = ##schema::string AND table_name = ##name::string AND constraint_name = ##name2::string",
+ error,
+ "schema", table_schema, "name", table_name, "name2", constraint_name, NULL);
g_object_unref (model);
return retval;
Modified: trunk/providers/postgres/gda-postgres-meta.h
==============================================================================
--- trunk/providers/postgres/gda-postgres-meta.h (original)
+++ trunk/providers/postgres/gda-postgres-meta.h Wed Mar 12 21:18:24 2008
@@ -31,29 +31,18 @@
GdaMetaStore *store, GdaMetaContext *context, GError **error);
gboolean _gda_postgres_meta_btypes (GdaServerProvider *prov, GdaConnection *cnc,
GdaMetaStore *store, GdaMetaContext *context, GError **error);
-gboolean _gda_postgres_meta_schemata (GdaServerProvider *prov, GdaConnection *cnc,
- GdaMetaStore *store, GdaMetaContext *context, GError **error,
- const GValue *schema_name);
-gboolean _gda_postgres_meta_tables_views (GdaServerProvider *prov, GdaConnection *cnc,
- GdaMetaStore *store, GdaMetaContext *context, GError **error);
-gboolean _gda_postgres_meta_tables_views_s (GdaServerProvider *prov, GdaConnection *cnc,
- GdaMetaStore *store, GdaMetaContext *context, GError **error,
- const GValue *table_schema, const GValue *table_name);
-gboolean _gda_postgres_meta_columns (GdaServerProvider *prov, GdaConnection *cnc,
- GdaMetaStore *store, GdaMetaContext *context, GError **error);
-gboolean _gda_postgres_meta_columns_t (GdaServerProvider *prov, GdaConnection *cnc,
- GdaMetaStore *store, GdaMetaContext *context, GError **error,
- const GValue *table_schema, const GValue *table_name);
-gboolean _gda_postgres_meta_columns_c (GdaServerProvider *prov, GdaConnection *cnc,
- GdaMetaStore *store, GdaMetaContext *context, GError **error,
- const GValue *table_schema, const GValue *table_name, const GValue *column_name);
-gboolean _gda_postgres_meta_constraints_tab (GdaServerProvider *, GdaConnection *, GdaMetaStore *, GdaMetaContext *, GError **);
-gboolean _gda_postgres_meta_constraints_tab_s (GdaServerProvider *, GdaConnection *, GdaMetaStore *, GdaMetaContext *, GError **,
- const GValue *table_schema, const GValue *table_name);
-
-gboolean _gda_postgres_meta_constraints_ref (GdaServerProvider *, GdaConnection *, GdaMetaStore *, GdaMetaContext *, GError **);
-gboolean _gda_postgres_meta_constraints_ref_c (GdaServerProvider *, GdaConnection *, GdaMetaStore *, GdaMetaContext *, GError **,
- const GValue *table_schema, const GValue *table_name);
+gboolean _gda_postgres_meta_schemata (GdaServerProvider *, GdaConnection *, GdaMetaStore *, GdaMetaContext *, GError **,
+ const GValue *catalog_name, const GValue *schema_name_n);
+gboolean _gda_postgres_meta_tables_views (GdaServerProvider *, GdaConnection *, GdaMetaStore *, GdaMetaContext *, GError **,
+ const GValue *table_catalog, const GValue *table_schema, const GValue *table_name_n);
+gboolean _gda_postgres_meta_columns (GdaServerProvider *, GdaConnection *, GdaMetaStore *, GdaMetaContext *, GError **,
+ const GValue *table_catalog, const GValue *table_schema, const GValue *table_name);
+gboolean _gda_postgres_meta_constraints_tab (GdaServerProvider *, GdaConnection *, GdaMetaStore *, GdaMetaContext *, GError **,
+ const GValue *table_catalog, const GValue *table_schema, const GValue *table_name,
+ const GValue *constraint_name_n);
+gboolean _gda_postgres_meta_constraints_ref (GdaServerProvider *, GdaConnection *, GdaMetaStore *, GdaMetaContext *, GError **,
+ const GValue *table_catalog, const GValue *table_schema, const GValue *table_name,
+ const GValue *constraint_name);
G_END_DECLS
Modified: trunk/providers/postgres/gda-postgres-provider.c
==============================================================================
--- trunk/providers/postgres/gda-postgres-provider.c (original)
+++ trunk/providers/postgres/gda-postgres-provider.c Wed Mar 12 21:18:24 2008
@@ -185,18 +185,13 @@
provider_class->statement_execute = gda_postgres_provider_statement_execute;
memset (&(provider_class->meta_funcs), 0, sizeof (GdaServerProviderMeta));
- provider_class->meta_funcs.info = _gda_postgres_meta_info;
- provider_class->meta_funcs.btypes = _gda_postgres_meta_btypes;
+ provider_class->meta_funcs._info = _gda_postgres_meta_info;
+ provider_class->meta_funcs._btypes = _gda_postgres_meta_btypes;
provider_class->meta_funcs.schemata = _gda_postgres_meta_schemata;
provider_class->meta_funcs.tables_views = _gda_postgres_meta_tables_views;
- provider_class->meta_funcs.tables_views_s = _gda_postgres_meta_tables_views_s;
provider_class->meta_funcs.columns = _gda_postgres_meta_columns;
- provider_class->meta_funcs.columns_t = _gda_postgres_meta_columns_t;
- provider_class->meta_funcs.columns_c = _gda_postgres_meta_columns_c;
provider_class->meta_funcs.constraints_tab = _gda_postgres_meta_constraints_tab;
- provider_class->meta_funcs.constraints_tab_s = _gda_postgres_meta_constraints_tab_s;
provider_class->meta_funcs.constraints_ref = _gda_postgres_meta_constraints_ref;
- provider_class->meta_funcs.constraints_ref_c = _gda_postgres_meta_constraints_ref_c;
}
static void
Modified: trunk/providers/sqlite/sqlite_specs_create_table.xml.in
==============================================================================
--- trunk/providers/sqlite/sqlite_specs_create_table.xml.in (original)
+++ trunk/providers/sqlite/sqlite_specs_create_table.xml.in Wed Mar 12 21:18:24 2008
@@ -30,14 +30,14 @@
<gda_array_row>
<gda_value>id</gda_value>
<gda_value>integer</gda_value>
- <gda_value></gda_value>
- <gda_value></gda_value>
+ <gda_value isnull='t'></gda_value>
+ <gda_value isnull='t'></gda_value>
<gda_value>FALSE</gda_value>
<gda_value>TRUE</gda_value>
<gda_value>FALSE</gda_value>
<gda_value>TRUE</gda_value>
- <gda_value></gda_value>
- <gda_value></gda_value>
+ <gda_value isnull='t'></gda_value>
+ <gda_value isnull='t'></gda_value>
</gda_array_row>
</gda_array_data>
</gda_array>
Modified: trunk/tests/data-models/check_data_proxy.c
==============================================================================
--- trunk/tests/data-models/check_data_proxy.c (original)
+++ trunk/tests/data-models/check_data_proxy.c Wed Mar 12 21:18:24 2008
@@ -123,6 +123,10 @@
if (!do_test_proxied_model_modif ())
number_failed ++;
+ if (number_failed == 0)
+ g_print ("Ok.\n");
+ else
+ g_print ("%d failed\n", number_failed);
return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
}
Modified: trunk/tests/data-models/check_model_import.c
==============================================================================
--- trunk/tests/data-models/check_model_import.c (original)
+++ trunk/tests/data-models/check_model_import.c Wed Mar 12 21:18:24 2008
@@ -48,6 +48,10 @@
}
g_dir_close (dir);
+ if (number_failed == 0)
+ g_print ("Ok.\n");
+ else
+ g_print ("%d failed\n", number_failed);
return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
}
Modified: trunk/tests/meta-store/common.c
==============================================================================
--- trunk/tests/meta-store/common.c (original)
+++ trunk/tests/meta-store/common.c Wed Mar 12 21:18:24 2008
@@ -15,7 +15,7 @@
GSList *expected_changes;
static void meta_changed_cb (GdaMetaStore *store, GSList *changes, gpointer data);
-static void suggest_update_cb (GdaMetaStore *store, GdaMetaContext *context, gpointer data);
+static GError *suggest_update_cb (GdaMetaStore *store, GdaMetaContext *context, gpointer data);
/*
* Declare a GdaMetaStore to test
@@ -91,17 +91,18 @@
}
}
-static void
+static GError *
suggest_update_cb (GdaMetaStore *store, GdaMetaContext *context, gpointer data)
{
gint i;
- g_print ("Update suggested for table %s:\n", context->table_name);
+ g_print ("test: Update suggested for table %s:\n", context->table_name);
for (i = 0; i < context->size; i++) {
gchar *str;
str = gda_value_stringify (context->column_values[i]);
g_print ("\t%s => %s\n", context->column_names[i], str);
g_free (str);
}
+ return NULL;
}
/*
@@ -272,11 +273,6 @@
};
gchar *view_names [] = {
"_all_types",
- "_constraint_column_usage",
- "_constraint_table_usage",
- "_view_table_usage",
- "_check_constraints",
- "_domain_column_usage"
};
GdaConnection *cnc = gda_meta_store_get_internal_connection (store);
@@ -346,7 +342,7 @@
test_columns (store);
test_table_constraints (store);
test_referential_constraints (store);
- test_key_column_usage (store);
+ /*test_key_column_usage (store);*/
test_domain_constraints (store);
test_parameters (store);
}
Modified: trunk/tests/providers/Makefile.am
==============================================================================
--- trunk/tests/providers/Makefile.am (original)
+++ trunk/tests/providers/Makefile.am Wed Mar 12 21:18:24 2008
@@ -170,22 +170,6 @@
PostgreSQL_create_tables.sql \
SQLite_create_tables.sql \
MySQL_create_tables.sql \
- FIELDS_SCHEMA_Mdb_actor.xml \
- FIELDS_SCHEMA_Mdb_film_actor.xml \
- FIELDS_SCHEMA_Mdb_film.xml \
- FIELDS_SCHEMA_Mdb_language.xml \
- FIELDS_SCHEMA_MySQL_actor.xml \
- FIELDS_SCHEMA_MySQL_film_actor.xml \
- FIELDS_SCHEMA_MySQL_film.xml \
- FIELDS_SCHEMA_MySQL_language.xml \
- FIELDS_SCHEMA_PostgreSQL_actor.xml \
- FIELDS_SCHEMA_PostgreSQL_film_actor.xml \
- FIELDS_SCHEMA_PostgreSQL_film.xml \
- FIELDS_SCHEMA_PostgreSQL_language.xml \
- FIELDS_SCHEMA_SQLite_actor.xml \
- FIELDS_SCHEMA_SQLite_film_actor.xml \
- FIELDS_SCHEMA_SQLite_film.xml \
- FIELDS_SCHEMA_SQLite_language.xml \
TYPES_SCHEMA_Mdb.xml \
TYPES_SCHEMA_MySQL.xml \
TYPES_SCHEMA_PostgreSQL.xml \
Modified: trunk/tests/providers/README
==============================================================================
--- trunk/tests/providers/README (original)
+++ trunk/tests/providers/README Wed Mar 12 21:18:24 2008
@@ -41,10 +41,10 @@
MYSQL_DBCREATE_PARAMS "HOST=localhost"
POSTGRESQL_DBCREATE_PARAMS "HOST=localhost;PORT=5432"
-SQLITE_DBCREATE_PARAMS "DB_DIR=/home/me/libgda/tests/providers"
-BERKELEY_DB_CNC_PARAMS "FILE=gda_check_bdb.db"
+SQLITE_DBCREATE_PARAMS "DB_DIR=."
+BERKELEY_DB_CNC_PARAMS "DB_NAME=gda_check_bdb.db"
The MDB provider does not allow database creation, so use the gda_check_db.mdb file in this directory
-MS_ACCESS_CNC_PARAMS "DB_DIR=/home/me/libgda/tests/providers;DB_NAME=gda_check_db"
+MSACCESS_CNC_PARAMS "DB_DIR=/home/me/libgda/tests/providers;DB_NAME=gda_check_db"
ORACLE_CNC_PARAMS TNSNAME=//127.0.0.1
Modified: trunk/tests/providers/TYPES_SCHEMA_SQLite.xml
==============================================================================
--- trunk/tests/providers/TYPES_SCHEMA_SQLite.xml (original)
+++ trunk/tests/providers/TYPES_SCHEMA_SQLite.xml Wed Mar 12 21:18:24 2008
@@ -1,142 +1,56 @@
<?xml version="1.0"?>
<gda_array id="EXPORT" name="Exported Data">
- <gda_array_field id="FI0" name="Type" title="Type" gdatype="gchararray" nullok="TRUE"/>
- <gda_array_field id="FI1" name="Owner" title="Owner" gdatype="gchararray" nullok="TRUE"/>
- <gda_array_field id="FI2" name="Comments" title="Comments" gdatype="gchararray" nullok="TRUE"/>
- <gda_array_field id="FI3" name="GDA type" title="GDA type" gdatype="gulong" nullok="TRUE"/>
- <gda_array_field id="FI4" name="Synonyms" title="Synonyms" gdatype="gchararray" nullok="TRUE"/>
+ <gda_array_field id="FI0" name="short_type_name" title="short_type_name" gdatype="gchararray" size="-1" scale="-1"/>
+ <gda_array_field id="FI1" name="gtype" title="gtype" gdatype="gchararray" size="-1" scale="-1" nullok="TRUE"/>
+ <gda_array_field id="FI2" name="comments" title="comments" gdatype="gchararray" size="-1" scale="-1" nullok="TRUE"/>
+ <gda_array_field id="FI3" name="synonyms" title="synonyms" gdatype="gchararray" size="-1" scale="-1" nullok="TRUE"/>
<gda_array_data>
<gda_array_row>
- <gda_value>integer</gda_value>
- <gda_value>system</gda_value>
- <gda_value>Signed integer, stored in 1, 2, 3, 4, 6, or 8 bytes depending on the magnitude of the value</gda_value>
- <gda_value>24</gda_value>
- <gda_value isnull="t"/>
- </gda_array_row>
- <gda_array_row>
- <gda_value>real</gda_value>
- <gda_value>system</gda_value>
- <gda_value>Floating point value, stored as an 8-byte IEEE floating point number</gda_value>
- <gda_value>60</gda_value>
- <gda_value isnull="t"/>
- </gda_array_row>
- <gda_array_row>
- <gda_value>text</gda_value>
- <gda_value>system</gda_value>
- <gda_value>Text string, stored using the database encoding</gda_value>
- <gda_value>64</gda_value>
- <gda_value isnull="t"/>
- </gda_array_row>
- <gda_array_row>
<gda_value>blob</gda_value>
- <gda_value>system</gda_value>
+ <gda_value>GdaBinary</gda_value>
<gda_value>Blob of data, stored exactly as it was input</gda_value>
- <gda_value>145570992</gda_value>
- <gda_value isnull="t"/>
- </gda_array_row>
- <gda_array_row>
- <gda_value>timestamp</gda_value>
- <gda_value>system</gda_value>
- <gda_value>Time stamp, stored as 'YYYY-MM-DD HH:MM:SS.SSS'</gda_value>
- <gda_value>145573576</gda_value>
<gda_value isnull="t"/>
</gda_array_row>
<gda_array_row>
- <gda_value>time</gda_value>
- <gda_value>system</gda_value>
- <gda_value>Time, stored as 'HH:MM:SS.SSS'</gda_value>
- <gda_value>145568736</gda_value>
- <gda_value isnull="t"/>
+ <gda_value>boolean</gda_value>
+ <gda_value>gboolean</gda_value>
+ <gda_value>Boolean value</gda_value>
+ <gda_value>bool</gda_value>
</gda_array_row>
<gda_array_row>
<gda_value>date</gda_value>
- <gda_value>system</gda_value>
+ <gda_value>GDate</gda_value>
<gda_value>Date, stored as 'YYYY-MM-DD'</gda_value>
- <gda_value>145570864</gda_value>
- <gda_value isnull="t"/>
- </gda_array_row>
- <gda_array_row>
- <gda_value>VARCHAR(45)</gda_value>
- <gda_value>system</gda_value>
- <gda_value isnull="t"/>
- <gda_value>64</gda_value>
- <gda_value isnull="t"/>
- </gda_array_row>
- <gda_array_row>
- <gda_value>INTEGER</gda_value>
- <gda_value>system</gda_value>
- <gda_value isnull="t"/>
- <gda_value>24</gda_value>
- <gda_value isnull="t"/>
- </gda_array_row>
- <gda_array_row>
- <gda_value>CHAR(20)</gda_value>
- <gda_value>system</gda_value>
- <gda_value isnull="t"/>
- <gda_value>64</gda_value>
- <gda_value isnull="t"/>
- </gda_array_row>
- <gda_array_row>
- <gda_value>SMALLINT</gda_value>
- <gda_value>system</gda_value>
- <gda_value isnull="t"/>
- <gda_value>24</gda_value>
- <gda_value isnull="t"/>
- </gda_array_row>
- <gda_array_row>
- <gda_value>VARCHAR</gda_value>
- <gda_value>system</gda_value>
- <gda_value isnull="t"/>
- <gda_value>64</gda_value>
- <gda_value isnull="t"/>
- </gda_array_row>
- <gda_array_row>
- <gda_value>year</gda_value>
- <gda_value>system</gda_value>
- <gda_value isnull="t"/>
- <gda_value>64</gda_value>
- <gda_value isnull="t"/>
- </gda_array_row>
- <gda_array_row>
- <gda_value>TEXT[]</gda_value>
- <gda_value>system</gda_value>
- <gda_value isnull="t"/>
- <gda_value>64</gda_value>
<gda_value isnull="t"/>
</gda_array_row>
<gda_array_row>
- <gda_value>VARCHAR(255)</gda_value>
- <gda_value>system</gda_value>
- <gda_value isnull="t"/>
- <gda_value>64</gda_value>
- <gda_value isnull="t"/>
+ <gda_value>integer</gda_value>
+ <gda_value>gint</gda_value>
+ <gda_value>Signed integer, stored in 1, 2, 3, 4, 6, or 8 bytes depending on the magnitude of the value</gda_value>
+ <gda_value>int</gda_value>
</gda_array_row>
<gda_array_row>
- <gda_value>TEXT</gda_value>
- <gda_value>system</gda_value>
- <gda_value isnull="t"/>
- <gda_value>64</gda_value>
+ <gda_value>real</gda_value>
+ <gda_value>gdouble</gda_value>
+ <gda_value>Floating point value, stored as an 8-byte IEEE floating point number</gda_value>
<gda_value isnull="t"/>
</gda_array_row>
<gda_array_row>
- <gda_value>NUMERIC(4,2)</gda_value>
- <gda_value>system</gda_value>
- <gda_value isnull="t"/>
- <gda_value>64</gda_value>
- <gda_value isnull="t"/>
+ <gda_value>text</gda_value>
+ <gda_value>string</gda_value>
+ <gda_value>Text string, stored using the database encoding</gda_value>
+ <gda_value>string</gda_value>
</gda_array_row>
<gda_array_row>
- <gda_value>TIMESTAMP</gda_value>
- <gda_value>system</gda_value>
- <gda_value isnull="t"/>
- <gda_value>64</gda_value>
+ <gda_value>time</gda_value>
+ <gda_value>GdaTime</gda_value>
+ <gda_value>Time, stored as 'HH:MM:SS.SSS'</gda_value>
<gda_value isnull="t"/>
</gda_array_row>
<gda_array_row>
- <gda_value>NUMERIC(5,2)</gda_value>
- <gda_value>system</gda_value>
- <gda_value isnull="t"/>
- <gda_value>64</gda_value>
+ <gda_value>timestamp</gda_value>
+ <gda_value>GdaTimestamp</gda_value>
+ <gda_value>Time stamp, stored as 'YYYY-MM-DD HH:MM:SS.SSS'</gda_value>
<gda_value isnull="t"/>
</gda_array_row>
</gda_array_data>
Modified: trunk/tests/providers/check_bdb.c
==============================================================================
--- trunk/tests/providers/check_bdb.c (original)
+++ trunk/tests/providers/check_bdb.c Wed Mar 12 21:18:24 2008
@@ -26,13 +26,15 @@
number_failed = prov_test_common_setup ();
if (cnc) {
- number_failed += prov_test_check_table_schema (cnc, "data");
+ number_failed += prov_test_common_check_meta ();
number_failed += prov_test_common_clean ();
}
if (! params_provided)
return EXIT_SUCCESS;
- else
+ else {
+ g_print ("Test %s\n", (number_failed == 0) ? "Ok" : "failed");
return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
+ }
}
Modified: trunk/tests/providers/check_mdb.c
==============================================================================
--- trunk/tests/providers/check_mdb.c (original)
+++ trunk/tests/providers/check_mdb.c Wed Mar 12 21:18:24 2008
@@ -27,13 +27,15 @@
if (cnc) {
/* don't test create tables because it does not work for that provider */
- number_failed += prov_test_common_check_schemas ();
+ number_failed += prov_test_common_check_meta ();
number_failed += prov_test_common_clean ();
}
if (! params_provided)
return EXIT_SUCCESS;
- else
+ else {
+ g_print ("Test %s\n", (number_failed == 0) ? "Ok" : "failed");
return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
+ }
}
Modified: trunk/tests/providers/check_mysql.c
==============================================================================
--- trunk/tests/providers/check_mysql.c (original)
+++ trunk/tests/providers/check_mysql.c Wed Mar 12 21:18:24 2008
@@ -27,13 +27,15 @@
if (cnc) {
number_failed += prov_test_common_create_tables_sql ();
- number_failed += prov_test_common_check_schemas ();
+ number_failed += prov_test_common_check_meta ();
number_failed += prov_test_common_clean ();
}
if (! params_provided)
return EXIT_SUCCESS;
- else
+ else {
+ g_print ("Test %s\n", (number_failed == 0) ? "Ok" : "failed");
return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
+ }
}
Modified: trunk/tests/providers/check_oracle.c
==============================================================================
--- trunk/tests/providers/check_oracle.c (original)
+++ trunk/tests/providers/check_oracle.c Wed Mar 12 21:18:24 2008
@@ -27,13 +27,15 @@
if (cnc) {
number_failed += prov_test_common_create_tables_sql ();
- number_failed += prov_test_common_check_schemas ();
+ number_failed += prov_test_common_check_meta ();
number_failed += prov_test_common_clean ();
}
if (! params_provided)
return EXIT_SUCCESS;
- else
+ else {
+ g_print ("Test %s\n", (number_failed == 0) ? "Ok" : "failed");
return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
+ }
}
Modified: trunk/tests/providers/check_postgres.c
==============================================================================
--- trunk/tests/providers/check_postgres.c (original)
+++ trunk/tests/providers/check_postgres.c Wed Mar 12 21:18:24 2008
@@ -29,7 +29,7 @@
if (cnc) {
number_failed += prov_test_common_create_tables_sql ();
- number_failed += prov_test_common_check_schemas ();
+ number_failed += prov_test_common_check_meta ();
number_failed += prov_test_common_load_data ();
number_failed += prov_test_common_check_cursor_models ();
number_failed += prov_test_common_clean ();
@@ -37,7 +37,9 @@
if (! params_provided)
return EXIT_SUCCESS;
- else
+ else {
+ g_print ("Test %s\n", (number_failed == 0) ? "Ok" : "failed");
return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
+ }
}
Modified: trunk/tests/providers/check_sqlite.c
==============================================================================
--- trunk/tests/providers/check_sqlite.c (original)
+++ trunk/tests/providers/check_sqlite.c Wed Mar 12 21:18:24 2008
@@ -29,7 +29,7 @@
if (cnc) {
number_failed += prov_test_common_create_tables_sql ();
- number_failed += prov_test_common_check_schemas ();
+ number_failed += prov_test_common_check_meta ();
number_failed += prov_test_common_load_data ();
number_failed += prov_test_common_check_cursor_models ();
number_failed += prov_test_common_clean ();
@@ -37,7 +37,9 @@
if (! params_provided)
return EXIT_SUCCESS;
- else
+ else {
+ g_print ("Test %s\n", (number_failed == 0) ? "Ok" : "failed");
return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
+ }
}
Modified: trunk/tests/providers/prov-test-common.c
==============================================================================
--- trunk/tests/providers/prov-test-common.c (original)
+++ trunk/tests/providers/prov-test-common.c Wed Mar 12 21:18:24 2008
@@ -2,6 +2,10 @@
#include <string.h>
#include "prov-test-common.h"
#include "prov-test-util.h"
+#include <sql-parser/gda-sql-statement.h>
+
+#define CHECK_EXTRA_INFO
+/*#undef CHECK_EXTRA_INFO*/
GdaProviderInfo *pinfo;
GdaConnection *cnc;
@@ -59,24 +63,131 @@
/*
*
- * CHECK_SCHEMAS
+ * CHECK_META
*
*/
int
-prov_test_common_check_schemas ()
+prov_test_common_check_meta ()
{
int number_failed = 0;
- if (!prov_test_check_table_schema (cnc, "actor"))
- number_failed++;
- if (!prov_test_check_table_schema (cnc, "language"))
- number_failed++;
- if (!prov_test_check_table_schema (cnc, "film"))
- number_failed++;
- if (!prov_test_check_table_schema (cnc, "film_actor"))
- number_failed++;
- if (!prov_test_check_types_schema (cnc))
- number_failed++;
+ GSList *tables, *list;
+ gboolean dump_ok = TRUE;
+ GdaMetaStore *store;
+ gchar **dump1 = NULL;
+ GError *gerror = NULL;
+ gint ntables, i;
+
+ /* update meta store */
+ if (! gda_connection_update_meta_store (cnc, NULL, &gerror)) {
+#ifdef CHECK_EXTRA_INFO
+ g_warning ("Can't update meta store (1): %s\n",
+ gerror && gerror->message ? gerror->message : "???");
+#endif
+ g_error_free (gerror);
+ number_failed++;
+ goto theend;
+ }
+
+ /* dump all tables */
+ store = gda_connection_get_meta_store (cnc);
+ tables = gda_meta_store_schema_get_tables (store);
+ ntables = g_slist_length (tables);
+ dump1 = g_new0 (gchar *, ntables + 1);
+
+ for (i = 0, list = tables; list; i++, list = list->next) {
+ GdaDataModel *model;
+ gchar *tmp;
+
+ tmp = g_strdup_printf ("SELECT * FROM %s", (gchar*) list->data);
+ model = gda_meta_store_extract (store, tmp, &gerror, NULL);
+ g_free (tmp);
+ if (!model) {
+#ifdef CHECK_EXTRA_INFO
+ g_warning ("Can't execute SELECT statement: %s\n",
+ gerror && gerror->message ? gerror->message : "???");
+#endif
+ g_error_free (gerror);
+ dump_ok = FALSE;
+ break;
+ }
+
+ dump1 [i] = gda_data_model_export_to_string (model, GDA_DATA_MODEL_IO_DATA_ARRAY_XML,
+ NULL, 0, NULL, 0, NULL);
+ g_object_unref (model);
+ if (!dump1 [i]) {
+#ifdef CHECK_EXTRA_INFO
+ g_warning ("Can't export data model\n");
+#endif
+ dump_ok = FALSE;
+ break;
+ }
+ }
+
+ if (!dump_ok) {
+ number_failed++;
+ goto theend;
+ }
+
+ /* update meta store */
+ if (! gda_connection_update_meta_store (cnc, NULL, &gerror)) {
+#ifdef CHECK_EXTRA_INFO
+ g_warning ("Can't update meta store (2): %s\n",
+ gerror && gerror->message ? gerror->message : "???");
+#endif
+ g_error_free (gerror);
+ number_failed++;
+ goto theend;
+ }
+
+ for (i = 0, list = tables; list; i++, list = list->next) {
+ GdaDataModel *model;
+ gchar *tmp;
+ GError *gerror = NULL;
+
+ tmp = g_strdup_printf ("SELECT * FROM %s", (gchar*) list->data);
+ model = gda_meta_store_extract (store, tmp, &gerror, NULL);
+ g_free (tmp);
+ if (!model) {
+#ifdef CHECK_EXTRA_INFO
+ g_warning ("Can't execute SELECT statement: %s\n",
+ gerror && gerror->message ? gerror->message : "???");
+#endif
+ g_error_free (gerror);
+ number_failed++;
+ continue;
+ }
+
+ tmp = gda_data_model_export_to_string (model, GDA_DATA_MODEL_IO_DATA_ARRAY_XML,
+ NULL, 0, NULL, 0, NULL);
+ g_object_unref (model);
+ if (!tmp) {
+#ifdef CHECK_EXTRA_INFO
+ g_warning ("Can't export data model\n");
+#endif
+ number_failed++;
+ continue;
+ }
+ if (strcmp (tmp, dump1[i])) {
+#ifdef CHECK_EXTRA_INFO
+ g_warning ("Meta data has changed after update for table %s\n", (gchar*) list->data);
+#endif
+ number_failed++;
+ g_free (tmp);
+ continue;
+ }
+#ifdef CHECK_EXTRA_INFO
+ else
+ g_print ("Meta for table '%s' Ok\n", (gchar*) list->data);
+#endif
+ g_free (tmp);
+ }
+
+ theend:
+ /* remove tmp files */
+ if (dump1)
+ g_strfreev (dump1);
+ g_slist_free (tables);
return number_failed;
}
Modified: trunk/tests/providers/prov-test-common.h
==============================================================================
--- trunk/tests/providers/prov-test-common.h (original)
+++ trunk/tests/providers/prov-test-common.h Wed Mar 12 21:18:24 2008
@@ -13,7 +13,7 @@
int prov_test_common_setup ();
int prov_test_common_create_tables_sql ();
int prov_test_common_load_data ();
-int prov_test_common_check_schemas ();
+int prov_test_common_check_meta ();
int prov_test_common_check_cursor_models ();
int prov_test_common_clean ();
Modified: trunk/tests/providers/prov-test-util.c
==============================================================================
--- trunk/tests/providers/prov-test-util.c (original)
+++ trunk/tests/providers/prov-test-util.c Wed Mar 12 21:18:24 2008
@@ -10,7 +10,7 @@
/*#undef CHECK_EXTRA_INFO*/
#define DB_NAME "gda_check_db"
-#define CREATE_FILES 0
+#define CREATE_FILES 1
GdaSqlParser *parser = NULL;
/*
@@ -175,14 +175,14 @@
db_name = DB_NAME;
db_quark_list = gda_quark_list_new_from_string (db_params);
- op = gda_prepare_drop_database (client, db_name, prov_info->id);
+ op = gda_prepare_drop_database (prov_info->id, db_name, NULL);
gda_quark_list_foreach (db_quark_list, (GHFunc) db_create_quark_foreach_func, op);
- gda_perform_create_database (client, op, NULL);
+ gda_perform_create_database (op, NULL);
g_object_unref (op);
- op = gda_prepare_create_database (client, db_name, prov_info->id);
+ op = gda_prepare_create_database (prov_info->id, db_name, NULL);
gda_quark_list_foreach (db_quark_list, (GHFunc) db_create_quark_foreach_func, op);
- if (!gda_perform_create_database (client, op, &error)) {
+ if (!gda_perform_create_database (op, &error)) {
#ifdef CHECK_EXTRA_INFO
g_warning ("Could not create the '%s' database (provider %s): %s", db_name,
prov_info->id, error && error->message ? error->message : "No detail");
@@ -219,15 +219,23 @@
g_print ("Open connection string: %s\n", data.string->str);
const gchar *username, *password;
+ gchar *auth = NULL;
str = g_strdup_printf ("%s_USER", upname);
username = getenv (str);
g_free (str);
str = g_strdup_printf ("%s_PASS", upname);
password = getenv (str);
g_free (str);
+ if (username) {
+ if (password)
+ auth = g_strdup_printf ("USERNAME=%s;PASSWORD=%s", username, password);
+ else
+ auth = g_strdup_printf ("USERNAME=%s", username);
+ }
- cnc = gda_connection_open_from_string (prov_info->id, data.string->str, username, password,
+ cnc = gda_connection_open_from_string (prov_info->id, data.string->str, auth,
GDA_CONNECTION_OPTIONS_NONE, &error);
+ g_free (auth);
if (!cnc && error) {
#ifdef CHECK_EXTRA_INFO
g_warning ("Could not open connection to %s (provider %s): %s",
@@ -304,12 +312,12 @@
g_free (str);
g_assert (db_params);
- op = gda_prepare_drop_database (client, DB_NAME, prov_id);
+ op = gda_prepare_drop_database (prov_id, DB_NAME, NULL);
db_quark_list = gda_quark_list_new_from_string (db_params);
gda_quark_list_foreach (db_quark_list, (GHFunc) db_drop_quark_foreach_func, op);
gda_quark_list_free (db_quark_list);
- if (!gda_perform_drop_database (client, op, &error)) {
+ if (!gda_perform_drop_database (op, &error)) {
#ifdef CHECK_EXTRA_INFO
g_warning ("Could not drop the '%s' database (provider %s): %s", DB_NAME,
prov_id, error && error->message ? error->message : "No detail");
@@ -381,68 +389,6 @@
/*
*
- * Check a table's schema
- *
- */
-gboolean
-prov_test_check_table_schema (GdaConnection *cnc, const gchar *table)
-{
- if (!cnc || !gda_connection_is_opened (cnc)) {
-#ifdef CHECK_EXTRA_INFO
- g_warning ("Connection is closed!");
-#endif
- return FALSE;
- }
-
- GdaServerProvider *prov;
- GdaDataModel *schema_m;
- GError *error = NULL;
- gchar *str;
- GValue *v;
-
- prov = gda_connection_get_provider_obj (cnc);
- g_value_set_string (v = gda_value_new (G_TYPE_STRING), table);
- schema_m = gda_connection_get_meta_store_data (cnc, GDA_CONNECTION_META_FIELDS, &error, 1, "name", v);
- gda_value_free (v);
- if (!schema_m) {
-#ifdef CHECK_EXTRA_INFO
- g_warning ("Could not get FIELDS schema for table '%s': %s", table,
- error && error->message ? error->message : "No detail");
-#endif
- return FALSE;
- }
-
- str = g_strdup_printf ("FIELDS_SCHEMA_%s_%s.xml", gda_connection_get_provider_name (cnc), table);
- if (CREATE_FILES) {
- GdaSet *plist;
- /* export schema model to a file, to create first version of the files, not to be used in actual checks */
- plist = gda_set_new_inline (1, "OVERWRITE", G_TYPE_BOOLEAN, TRUE);
- if (! (gda_data_model_export_to_file (schema_m, GDA_DATA_MODEL_IO_DATA_ARRAY_XML, str,
- NULL, 0, NULL, 0, plist, &error))) {
-#ifdef CHECK_EXTRA_INFO
- g_warning ("Could not export schema to file '%s': %s", str,
- error && error->message ? error->message : "No detail");
-#endif
- return FALSE;
- }
- g_object_unref (plist);
- }
- else {
- /* compare schema with what's expected */
- gchar *file = g_build_filename (CHECK_SQL_FILES, "tests", "providers", str, NULL);
- if (!compare_data_model_with_expected (schema_m, file))
- return FALSE;
- g_free (file);
- }
- g_free (str);
-
- /*gda_data_model_dump (schema_m, stdout);*/
- g_object_unref (schema_m);
- return TRUE;
-}
-
-/*
- *
* Check data types' schema
*
*/
@@ -711,6 +657,11 @@
return FALSE;
}
+ /* try to start a transaction to spped things up */
+ gboolean started_transaction;
+ started_transaction = gda_connection_begin_transaction (cnc, NULL,
+ GDA_TRANSACTION_ISOLATION_UNKNOWN,
+ NULL);
gint row, nrows;
nrows = gda_data_model_get_n_rows (imodel);
for (row = 0; row < nrows; row++) {
@@ -742,6 +693,10 @@
return FALSE;
}
}
+
+ if (started_transaction)
+ gda_connection_commit_transaction (cnc, NULL, NULL);
+
#ifdef CHECK_EXTRA_INFO
g_print ("Loaded %d rows into table '%s'\n", nrows, table);
#endif
Modified: trunk/tests/providers/prov-test-util.h
==============================================================================
--- trunk/tests/providers/prov-test-util.h (original)
+++ trunk/tests/providers/prov-test-util.h Wed Mar 12 21:18:24 2008
@@ -16,7 +16,6 @@
gboolean prov_test_clean_connection (GdaConnection *cnc, gboolean destroy_db);
gboolean prov_test_create_tables_sql (GdaConnection *cnc);
-gboolean prov_test_check_table_schema (GdaConnection *cnc, const gchar *table);
gboolean prov_test_check_types_schema (GdaConnection *cnc);
gboolean prov_test_load_data (GdaConnection *cnc, const gchar *table);
Modified: trunk/tools/command-exec.c
==============================================================================
--- trunk/tools/command-exec.c (original)
+++ trunk/tools/command-exec.c Wed Mar 12 21:18:24 2008
@@ -519,7 +519,7 @@
GdaMetaStore *store;
store = gda_connection_get_meta_store (cnc);
- mstruct = gda_meta_struct_new ();
+ mstruct = gda_meta_struct_new (GDA_META_STRUCT_FEATURE_ALL);
if (!args[0]) {
/* use all tables or views */
@@ -579,8 +579,41 @@
}
else {
/* try to find it as a table or view */
- if (!gda_meta_struct_complement (mstruct, store, GDA_META_DB_TABLE, NULL, NULL, v, NULL))
- gda_meta_struct_complement (mstruct, store, GDA_META_DB_VIEW, NULL, NULL, v, NULL);
+ if (!gda_meta_struct_complement (mstruct, store, GDA_META_DB_UNKNOWN, NULL, NULL, v, NULL)) {
+ if (g_str_has_suffix (arg, "=") && (*arg != '=')) {
+ GdaMetaDbObject *dbo;
+ gchar *str;
+ str = g_strdup (arg);
+ str[strlen (str) - 1] = 0;
+ g_value_take_string (v, str);
+ dbo = gda_meta_struct_complement (mstruct, store, GDA_META_DB_TABLE,
+ NULL, NULL, v, NULL);
+ if (!dbo)
+ dbo = gda_meta_struct_complement (mstruct, store, GDA_META_DB_VIEW,
+ NULL, NULL, v, NULL);
+ if (dbo && dbo->depend_list) {
+ GSList *list, *dep_list;
+ GValue *catalog, *schema, *name;
+
+ dep_list = g_slist_copy (dbo->depend_list);
+ for (list = dep_list; list; list = list->next) {
+ dbo = GDA_META_DB_OBJECT (list->data);
+ g_value_set_string ((catalog = gda_value_new (G_TYPE_STRING)),
+ dbo->obj_catalog);
+ g_value_set_string ((schema = gda_value_new (G_TYPE_STRING)),
+ dbo->obj_schema);
+ g_value_set_string ((name = gda_value_new (G_TYPE_STRING)),
+ dbo->obj_name);
+ gda_meta_struct_complement (mstruct, store, dbo->obj_type,
+ catalog, schema, name, NULL);
+ gda_value_free (catalog);
+ gda_value_free (schema);
+ gda_value_free (name);
+ }
+ g_slist_free (dep_list);
+ }
+ }
+ }
}
}
@@ -628,8 +661,16 @@
if (!mstruct)
return NULL;
+ /* compute the number of known database objects */
+ gint nb_objects = 0;
+ for (dbo_list = mstruct->db_objects; dbo_list; dbo_list = dbo_list->next) {
+ GdaMetaDbObject *dbo = GDA_META_DB_OBJECT (dbo_list->data);
+ if (dbo->obj_type != GDA_META_DB_UNKNOWN)
+ nb_objects++;
+ }
+
/* if more than one object, then show a list */
- if (mstruct->db_objects && mstruct->db_objects->next) {
+ if (nb_objects > 1) {
model = gda_data_model_array_new (4);
gda_data_model_set_column_title (model, 0, _("Schema"));
gda_data_model_set_column_title (model, 1, _("Name"));
Modified: trunk/tools/gda-sql.c
==============================================================================
--- trunk/tools/gda-sql.c (original)
+++ trunk/tools/gda-sql.c Wed Mar 12 21:18:24 2008
@@ -915,6 +915,7 @@
if (!data->output_stream)
g_print (_(" Done.\n"));
}
+
g_object_unref (store);
}
@@ -2365,81 +2366,15 @@
create_graph_from_meta_struct (GdaConnection *cnc, GdaMetaStruct *mstruct, GError **error)
{
#define FNAME "graph.dot"
- GString *string;
- gint i;
-
- /* prepare the graph */
- string = g_string_new ("digraph G {\nrankdir = BT;\nnode [shape = plaintext];\n");
- GSList *dbo_list;
- for (dbo_list = mstruct->db_objects; dbo_list; dbo_list = dbo_list->next) {
- gchar *objname, *fullname;
- GdaMetaDbObject *dbo = GDA_META_DB_OBJECT (dbo_list->data);
- GSList *list;
-
- /* obj human readable name, and full name */
- fullname = g_strdup_printf ("%s.%s.%s", dbo->obj_catalog, dbo->obj_schema, dbo->obj_name);
- if (dbo->obj_short_name)
- objname = g_strdup (dbo->obj_short_name);
- else
- objname = g_strdup_printf ("%s.%s", dbo->obj_schema, dbo->obj_name);
-
- /* node */
- switch (dbo->obj_type) {
- case GDA_META_DB_UNKNOWN:
- break;
- case GDA_META_DB_TABLE:
- g_string_append_printf (string, "\"%s\" [label=<<TABLE BORDER=\"1\" CELLBORDER=\"0\" CELLSPACING=\"0\">", fullname);
- g_string_append_printf (string, "<TR><TD COLSPAN=\"2\" BGCOLOR=\"grey\" BORDER=\"1\">%s</TD></TR>", objname);
- break;
- case GDA_META_DB_VIEW:
- g_string_append_printf (string, "\"%s\" [label=<<TABLE BORDER=\"1\" CELLBORDER=\"0\" CELLSPACING=\"0\">", fullname);
- g_string_append_printf (string, "<TR><TD BGCOLOR=\"yellow\" BORDER=\"1\">%s</TD></TR>", objname);
- break;
- default:
- TO_IMPLEMENT;
- g_string_append_printf (string, "\"%s\" [ shape = note ", fullname);
- break;
- }
+ gchar *graph;
- /* columns, only for tables */
- if (dbo->obj_type == GDA_META_DB_TABLE) {
- GdaMetaTable *mt = GDA_META_DB_OBJECT_GET_TABLE (dbo);
- for (list = mt->columns; list; list = list->next) {
- GdaMetaTableColumn *tcol = GDA_META_TABLE_COLUMN (list->data);
- GString *extra = g_string_new ("");
- if (tcol->pkey)
- g_string_append_printf (extra, "key");
- g_string_append_printf (string, "<TR><TD ALIGN=\"left\">%s</TD><TD ALIGN=\"right\">%s</TD></TR>",
- tcol->column_name, extra->str);
- g_string_free (extra, TRUE);
- }
- g_string_append (string, "</TABLE>>];\n");
- /* foreign keys */
- for (i = 1, list = mt->fk_list; list; i++, list = list->next) {
- GdaMetaTableForeignKey *tfk = GDA_META_TABLE_FOREIGN_KEY (list->data);
- if (tfk->depend_on->obj_type != GDA_META_DB_UNKNOWN)
- g_string_append_printf (string, "\"%s\" -> \"%s.%s.%s\" [label=\"(%d)\"];\n", fullname,
- tfk->depend_on->obj_catalog, tfk->depend_on->obj_schema,
- tfk->depend_on->obj_name, i);
- }
- }
- else if (dbo->obj_type == GDA_META_DB_VIEW) {
- GdaMetaTable *mt = GDA_META_DB_OBJECT_GET_TABLE (dbo);
- for (list = mt->columns; list; list = list->next) {
- GdaMetaTableColumn *tcol = GDA_META_TABLE_COLUMN (list->data);
- g_string_append_printf (string, "<TR><TD ALIGN=\"left\">%s</TD></TR>", tcol->column_name);
- }
- g_string_append (string, "</TABLE>>];\n");
- }
-
- g_free (objname);
- g_free (fullname);
- }
- g_string_append_c (string, '}');
+ graph = gda_meta_struct_dump_as_graph (mstruct, GDA_META_GRAPH_COLUMNS, error);
+ if (!graph)
+ return NULL;
/* do something with the graph */
gchar *result = NULL;
- if (g_file_set_contents (FNAME, string->str, -1, error)) {
+ if (g_file_set_contents (FNAME, graph, -1, error)) {
const gchar *viewer;
const gchar *format;
@@ -2494,7 +2429,7 @@
"Note: set the GDA_SQL_VIEWER_PNG or GDA_SQL_VIEWER_PDF environment "
"variables to view the graph"), FNAME, FNAME);
}
- g_string_free (string, TRUE);
+ g_free (graph);
return result;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]