libgda r3261 - in trunk: . libgda libgda-report po tools
- From: vivien svn gnome org
- To: svn-commits-list gnome org
- Subject: libgda r3261 - in trunk: . libgda libgda-report po tools
- Date: Wed, 10 Dec 2008 21:11:52 +0000 (UTC)
Author: vivien
Date: Wed Dec 10 21:11:52 2008
New Revision: 3261
URL: http://svn.gnome.org/viewvc/libgda?rev=3261&view=rev
Log:
2008-12-10 Vivien Malerba <malerba gnome-db org>
* libgda/libgda.symbols:
* libgda/Makefile.am:
* libgda-report/libgda-report.symbols:
* libgda-report/Makefile.am:
- use a DEF file on Windows to only export the
correct symbols (in the initialized data and the text (code) sections)
- create import libraries (.lib) files
* tools-input.[ch]:
* tools/gda-sql.c: use a main loop for characters input notification instead of
locking on a readline function
* configure.in
* tools/Makefile.am
* tools/html-doc.[ch]
* tools/web-server.[ch]: optionnally run a small embedded web server (if
libsoup is installed) to display meta data information in a browser
* libgda/gda-easy.[ch]: applied patch from Daniel Espinosa for bug #529794
* libgda/gda-data-model.c: calling gda_data_model_dump() with a NULL FILE*
now prints to stdout
* libgda/gda-meta-struct.c:
- removed debug messages
- better API documentation
Added:
trunk/libgda-report/libgda-report.symbols
trunk/libgda/libgda.symbols
trunk/tools/gda-sql.h
trunk/tools/html-doc.c
trunk/tools/html-doc.h
trunk/tools/web-server.c
trunk/tools/web-server.h
Modified:
trunk/ChangeLog
trunk/configure.in
trunk/libgda/ (props changed)
trunk/libgda-report/ (props changed)
trunk/libgda-report/Makefile.am
trunk/libgda/Makefile.am
trunk/libgda/gda-data-model.c
trunk/libgda/gda-easy.c
trunk/libgda/gda-easy.h
trunk/libgda/gda-meta-struct.c
trunk/po/POTFILES.in
trunk/tools/Makefile.am
trunk/tools/gda-sql.c
trunk/tools/tools-input.c
trunk/tools/tools-input.h
Modified: trunk/configure.in
==============================================================================
--- trunk/configure.in (original)
+++ trunk/configure.in Wed Dec 10 21:11:52 2008
@@ -163,6 +163,8 @@
linklibext=".dll.a"
AC_CHECK_TOOL(WINDRES, windres, windres)
AC_SUBST(WINDRES)
+ AC_CHECK_TOOL(DLLTOOL, dlltool, dlltool)
+ AC_SUBST(DLLTOOL)
;;
*-*-darwin*)
dnl Darwin based distributions (including Mac OS X)
@@ -1324,6 +1326,19 @@
LIBS="$save_LIBS"
export LD_LIBRARY_PATH="$save_LD_LIBRARY_PATH"
+dnl ************************
+dnl Check for libsoup
+dnl ************************
+PKG_CHECK_MODULES(LIBSOUP, libsoup-2.4, have_libsoup=yes, have_libsoup=no)
+AM_CONDITIONAL(LIBSOUP, test x"$have_libsoup" = "xyes")
+if test x"$have_libsoup" = "xyes"
+then
+ LIBSOUP_CFLAGS="$LIBSOUP_CFLAGS -DHAVE_LIBSOUP"
+fi
+AC_SUBST(LIBSOUP_CFLAGS)
+AC_SUBST(LIBSOUP_LIBS)
+
+
dnl **************************
dnl Check for readline/history
dnl **************************
Modified: trunk/libgda-report/Makefile.am
==============================================================================
--- trunk/libgda-report/Makefile.am (original)
+++ trunk/libgda-report/Makefile.am Wed Dec 10 21:11:52 2008
@@ -18,11 +18,37 @@
gda-report-document-private.h \
gda-report-document.c
-libgda_report_4_0_la_LDFLAGS = -version-info $(GDA_CURRENT):$(GDA_REVISION):$(GDA_AGE) $(NO_UNDEFINED)
+libgda_report_4_0_la_LDFLAGS = -version-info $(GDA_CURRENT):$(GDA_REVISION):$(GDA_AGE) \
+ $(NO_UNDEFINED) $(LIBTOOL_EXPORT_OPTIONS)
libgda_report_4_0_la_LIBADD = engine/libgda-report-engine-4.0.la \
DocBook/libgda-report-docbook-4.0.la \
RML/libgda-report-rml-4.0.la \
$(LIBGDA_LIBS)
+if PLATFORM_WIN32
+libgda_report_4_0_la_LDFLAGS += -export-symbols $(srcdir)/libgda-report.def
+libgda_report_4_0_la_DEPENDENCIES = libgda-report.def
+
+libgda-report.def: libgda-report.symbols
+ (echo -e EXPORTS; $(CPP) -P - <$(srcdir)/libgda-report.symbols | sed -e '/^$$/d' -e 's/^/ /' -e 's/G_GNUC_[^ ]*//g' | sort) > libgda-report.def.tmp && mv libgda-report.def.tmp libgda-report.def
+
+libgda-report-$(GDA_ABI_VERSION).lib: libgda-report.def
+ $(DLLTOOL) --dllname libgda-report-$(GDA_ABI_VERSION)-$(GDA_CURRENT).dll --def libgda-report.def --output-lib libgda-report-$(GDA_ABI_VERSION).lib
+
+install-data-local: install-def-files
+uninstall-local: uninstall-def-files
+
+install-def-files: libgda-report.def libgda-report-$(GDA_ABI_VERSION).lib
+ $(INSTALL) $(srcdir)/libgda-report.def $(DESTDIR)$(libdir)/libgda-report-$(GDA_ABI_VERSION).def
+ $(INSTALL) $(srcdir)/libgda-report-$(GDA_ABI_VERSION).lib $(DESTDIR)$(libdir)/
+
+uninstall-def-files:
+ -rm $(DESTDIR)$(libdir)/libgda-report-$(GDA_ABI_VERSION).def
+ -rm $(DESTDIR)$(libdir)/libgda-report-$(GDA_ABI_VERSION).lib
+endif
+
gdareportincludedir=$(includedir)/libgda-$(GDA_ABI_MAJOR_VERSION).$(GDA_ABI_MINOR_VERSION)/libgda-report
gdareportinclude_HEADERS= libgda-report.h $(report_headers)
+
+CLEANFILES = libgda-report.def \
+ libgda-report-$(GDA_ABI_VERSION).lib
Added: trunk/libgda-report/libgda-report.symbols
==============================================================================
--- (empty file)
+++ trunk/libgda-report/libgda-report.symbols Wed Dec 10 21:11:52 2008
@@ -0,0 +1,18 @@
+ gda_report_docbook_document_get_type
+ gda_report_docbook_document_new
+ gda_report_document_get_type
+ gda_report_document_run_as_html
+ gda_report_document_run_as_pdf
+ gda_report_document_run_converter_argv
+ gda_report_document_run_converter_path
+ gda_report_document_set_template
+ gda_report_engine_declare_object
+ gda_report_engine_find_declared_object
+ gda_report_engine_get_type
+ gda_report_engine_new
+ gda_report_engine_new_from_file
+ gda_report_engine_new_from_string
+ gda_report_engine_run_as_doc
+ gda_report_engine_run_as_node
+ gda_report_rml_document_get_type
+ gda_report_rml_document_new
Modified: trunk/libgda/Makefile.am
==============================================================================
--- trunk/libgda/Makefile.am (original)
+++ trunk/libgda/Makefile.am Wed Dec 10 21:11:52 2008
@@ -5,6 +5,7 @@
if BDB
GDA_BDB_H=gda-data-model-bdb.h
GDA_BDB_S=gda-data-model-bdb.c
+DEF_FLAGS=-DHAVE_BDB
endif
AM_CPPFLAGS = \
@@ -191,6 +192,28 @@
$(LIBGDA_LIBS) $(FAM_LIBS) \
$(BDB_LIBS) $(GIO_LIBS) $(GNOMEVFS_LIBS)
+if PLATFORM_WIN32
+libgda_4_0_la_LDFLAGS += -export-symbols $(srcdir)/libgda.def
+libgda_4_0_la_DEPENDENCIES = libgda.def
+
+libgda.def: libgda.symbols
+ (echo -e EXPORTS; $(CPP) -P $(DEF_FLAGS) - <$(srcdir)/libgda.symbols | sed -e '/^$$/d' -e 's/^/ /' -e 's/G_GNUC_[^ ]*//g' | sort) > libgda.def.tmp && mv libgda.def.tmp libgda.def
+
+libgda-$(GDA_ABI_VERSION).lib: libgda.def
+ $(DLLTOOL) --dllname libgda-$(GDA_ABI_VERSION)-$(GDA_CURRENT).dll --def libgda.def --output-lib libgda-$(GDA_ABI_VERSION).lib
+
+install-data-local: install-def-files
+uninstall-local: uninstall-def-files
+
+install-def-files: libgda.def libgda-$(GDA_ABI_VERSION).lib
+ $(INSTALL) $(srcdir)/libgda.def $(DESTDIR)$(libdir)/libgda-$(GDA_ABI_VERSION).def
+ $(INSTALL) $(srcdir)/libgda-$(GDA_ABI_VERSION).lib $(DESTDIR)$(libdir)/
+
+uninstall-def-files:
+ -rm $(DESTDIR)$(libdir)/libgda-$(GDA_ABI_VERSION).def
+ -rm $(DESTDIR)$(libdir)/libgda-$(GDA_ABI_VERSION).lib
+endif
+
gdaincludedir=$(includedir)/libgda-$(GDA_ABI_MAJOR_VERSION).$(GDA_ABI_MINOR_VERSION)/libgda
gdainclude_HEADERS=$(libgda_built_headers) $(gda_headers)
@@ -199,7 +222,9 @@
gda-enum-types.h \
s-enum-types-h \
gda-enum-types.c \
- s-enum-types-c
+ s-enum-types-c \
+ libgda.def \
+ libgda-$(GDA_ABI_VERSION).lib
dist-hook:
cd $(distdir); rm -f $(libgda_built_headers) $(libgda_built_cfiles)
@@ -213,6 +238,7 @@
EXTRA_DIST = \
$(DTD_FILES) \
$(xml_DATA) \
- gda-marshal.list
+ gda-marshal.list \
+ libgda.symbols
DISTCLEANFILES = .deps/*.P
Modified: trunk/libgda/gda-data-model.c
==============================================================================
--- trunk/libgda/gda-data-model.c (original)
+++ trunk/libgda/gda-data-model.c Wed Dec 10 21:11:52 2008
@@ -1814,7 +1814,8 @@
GError *error = NULL;
g_return_if_fail (GDA_IS_DATA_MODEL (model));
- g_return_if_fail (to_stream);
+ if (!to_stream)
+ to_stream = stdout;
if (getenv ("GDA_DATA_MODEL_DUMP_ATTRIBUTES"))
dump_attrs = TRUE;
Modified: trunk/libgda/gda-easy.c
==============================================================================
--- trunk/libgda/gda-easy.c (original)
+++ trunk/libgda/gda-easy.c Wed Dec 10 21:11:52 2008
@@ -252,6 +252,20 @@
* @...: group of three arguments for column's name, column's #GType
* and a #GdaEasyCreateTableFlag flag, finished with NULL
*
+ * Add more arguments if the flag needs then:
+ *
+ * GDA_EASY_CREATE_TABLE_FKEY_FLAG:
+ * <itemizedlist>
+ * <listitem><para>string with the table's name referenced</para></listitem>
+ * <listitem><para>an integer with the number pairs "local_field", "referenced_field"
+ * used in the reference</para></listitem>
+ * <listitem><para>Pairs of "local_field", "referenced_field" to use, must match
+ * the number specified above.</para></listitem>
+ * <listitem><para>a string with the action for ON DELETE; can be: "RESTRICT", "CASCADE",
+ * "NO ACTION", "SET NULL" and "SET DEFAULT". Example: "ON UPDATE CASCADE".</para></listitem>
+ * <listitem><para>a string with the action for ON UPDATE (see above).</para></listitem>
+ * </itemizedlist>
+ *
* Create a #GdaServerOperation object using an opened connection, taking three
* arguments, a colum's name the column's GType and #GdaEasyCreateTableFlag
* flag, you need to finish the list using NULL.
@@ -286,7 +300,8 @@
gchar *dbms_type;
GdaEasyCreateTableFlag flag;
gint i;
-
+ gint refs;
+
op = gda_server_provider_create_operation (server, cnc,
GDA_SERVER_OPERATION_CREATE_TABLE, NULL, error);
gda_server_operation_set_value_at (op, table_name, error, "/TABLE_DEF_P/TABLE_NAME");
@@ -295,6 +310,7 @@
type = 0;
arg = NULL;
i = 0;
+ refs = -1;
while ((arg = va_arg (args, gchar*))) {
/* First argument for Column's name */
@@ -320,6 +336,42 @@
gda_server_operation_set_value_at (op, "TRUE", error, "/FIELDS_A/@COLUMN_NNUL/%d", i);
if (flag & GDA_EASY_CREATE_TABLE_AUTOINC_FLAG)
gda_server_operation_set_value_at (op, "TRUE", error, "/FIELDS_A/@COLUMN_AUTOINC/%d", i);
+ if (flag & GDA_EASY_CREATE_TABLE_FKEY_FLAG) {
+ gint j;
+ gint fields;
+ gchar *fkey_table;
+ gchar *fkey_ondelete;
+ gchar *fkey_onupdate;
+
+ refs++;
+
+ fkey_table = va_arg (args, gchar*);
+ gda_server_operation_set_value_at (op, fkey_table, error,
+ "/FKEY_S/%d/FKEY_REF_TABLE", refs);
+
+ fields = va_arg (args, gint);
+
+ for (j = 0; j < fields; j++) {
+ gchar *field, *rfield;
+
+ field = va_arg (args, gchar*);
+ gda_server_operation_set_value_at (op, field, error,
+ "/FKEY_S/%d/FKEY_FIELDS_A/@FK_FIELD/%d", refs, j);
+
+ rfield = va_arg (args, gchar*);
+ gda_server_operation_set_value_at (op, rfield, error,
+ "/FKEY_S/%d/FKEY_FIELDS_A/@FK_REF_PK_FIELD/%d", refs, j);
+
+ }
+
+ fkey_ondelete = va_arg (args, gchar*);
+ gda_server_operation_set_value_at (op, fkey_ondelete, error,
+ "/FKEY_S/%d/FKEY_ONDELETE", refs);
+ fkey_onupdate = va_arg (args, gchar*);
+ gda_server_operation_set_value_at (op, fkey_onupdate, error,
+ "/FKEY_S/%d/FKEY_ONUPDATE", refs);
+ }
+
i++;
}
Modified: trunk/libgda/gda-easy.h
==============================================================================
--- trunk/libgda/gda-easy.h (original)
+++ trunk/libgda/gda-easy.h Wed Dec 10 21:11:52 2008
@@ -46,10 +46,12 @@
typedef enum
{
- GDA_EASY_CREATE_TABLE_PKEY_FLAG = 1 << 0,
- GDA_EASY_CREATE_TABLE_NOT_NULL_FLAG = 1 << 1,
- GDA_EASY_CREATE_TABLE_UNIQUE_FLAG = 1 << 2,
- GDA_EASY_CREATE_TABLE_AUTOINC_FLAG = 1 << 3,
+ GDA_EASY_CREATE_TABLE_NOTHING_FLAG = 1 << 0,
+ GDA_EASY_CREATE_TABLE_PKEY_FLAG = 1 << 1,
+ GDA_EASY_CREATE_TABLE_NOT_NULL_FLAG = 1 << 2,
+ GDA_EASY_CREATE_TABLE_UNIQUE_FLAG = 1 << 3,
+ GDA_EASY_CREATE_TABLE_AUTOINC_FLAG = 1 << 4,
+ GDA_EASY_CREATE_TABLE_FKEY_FLAG = 1 << 5,
/* Flags combinations */
GDA_EASY_CREATE_TABLE_PKEY_AUTOINC_FLAG = GDA_EASY_CREATE_TABLE_PKEY_FLAG | GDA_EASY_CREATE_TABLE_AUTOINC_FLAG
} GdaEasyCreateTableFlag;
Modified: trunk/libgda/gda-meta-struct.c
==============================================================================
--- trunk/libgda/gda-meta-struct.c (original)
+++ trunk/libgda/gda-meta-struct.c Wed Dec 10 21:11:52 2008
@@ -414,10 +414,10 @@
*
* If @catalog is not %NULL, then @schema should not be %NULL.
*
- * If @catalog is %NULL and @schema is not %NULL, then the database object will be the one which is
+ * If both @catalog and @schema are %NULL, then the database object will be the one which is
* "visible" by default (that is which can be accessed only by its short @name name).
*
- * If both @catalog and @schema are %NULL, then the database object will be the one which
+ * If @catalog is %NULL and @schema is not %NULL, then the database object will be the one which
* can be accessed by its @schema name name.
*
* Important note: @catalog, @schema and @name must respect the following convention:
@@ -861,8 +861,8 @@
"ts", ischema,
"tname", iname,
"cname", cvalue, NULL);
- g_print ("tname=%s cvalue=%s\n", gda_value_stringify (iname),
- gda_value_stringify (cvalue));
+ /*g_print ("tname=%s cvalue=%s\n", gda_value_stringify (iname),
+ gda_value_stringify (cvalue));*/
cvalue = gda_data_model_get_value_at (model, 4, i, error);
if (!cvalue) goto onfkerror;
@@ -871,8 +871,8 @@
"ts", fk_schema,
"tname", fk_name,
"cname", cvalue, NULL);
- g_print ("tname=%s cvalue=%s\n", gda_value_stringify (fk_name),
- gda_value_stringify (cvalue));
+ /*g_print ("tname=%s cvalue=%s\n", gda_value_stringify (fk_name),
+ gda_value_stringify (cvalue));*/
if (fk_cols && ref_pk_cols) {
gint fk_nrows, ref_pk_nrows;
Added: trunk/libgda/libgda.symbols
==============================================================================
--- (empty file)
+++ trunk/libgda/libgda.symbols Wed Dec 10 21:11:52 2008
@@ -0,0 +1,859 @@
+ fnYM49765777344607__gda_gbr_find_bin_dir
+ fnYM49765777344607__gda_gbr_find_data_dir
+ fnYM49765777344607__gda_gbr_find_etc_dir
+ fnYM49765777344607__gda_gbr_find_exe
+ fnYM49765777344607__gda_gbr_find_exe_dir
+ fnYM49765777344607__gda_gbr_find_lib_dir
+ fnYM49765777344607__gda_gbr_find_libexec_dir
+ fnYM49765777344607__gda_gbr_find_locale_dir
+ fnYM49765777344607__gda_gbr_find_prefix
+ fnYM49765777344607__gda_gbr_find_sbin_dir
+ gda_alphanum_to_text
+ gda_attributes_manager_clear
+ gda_attributes_manager_copy
+ gda_attributes_manager_foreach
+ gda_attributes_manager_free
+ gda_attributes_manager_get
+ gda_attributes_manager_new
+ gda_attributes_manager_set
+ gda_attributes_manager_set_full
+ gda_batch_add_statement
+ gda_batch_copy
+ gda_batch_error_quark
+ gda_batch_get_parameters
+ gda_batch_get_statements
+ gda_batch_get_type
+ gda_batch_new
+ gda_batch_remove_statement
+ gda_batch_serialize
+ gda_binary_copy
+ gda_binary_free
+ gda_binary_get_type
+ gda_binary_to_string
+ gda_blob_copy
+ gda_blob_free
+ gda_blob_get_type
+ gda_blob_op_get_length
+ gda_blob_op_get_type
+ gda_blob_op_read
+ gda_blob_op_read_all
+ gda_blob_op_write
+ gda_blob_op_write_all
+ gda_blob_set_op
+ gda_blob_to_string
+ gda_column_copy
+ gda_column_get_allow_null
+ gda_column_get_attribute
+ gda_column_get_auto_increment
+ gda_column_get_dbms_type
+ gda_column_get_default_value
+ gda_column_get_description
+ gda_column_get_g_type
+ gda_column_get_name
+ gda_column_get_position
+ gda_column_get_type
+ gda_column_new
+ gda_column_set_allow_null
+ gda_column_set_attribute
+ gda_column_set_auto_increment
+ gda_column_set_dbms_type
+ gda_column_set_default_value
+ gda_column_set_description
+ gda_column_set_g_type
+ gda_column_set_name
+ gda_column_set_position
+ gda_completion_list_get
+ gda_compute_dml_statements
+ gda_compute_unique_table_row_condition
+ gda_config_can_modify_system_config
+ gda_config_define_dsn
+ gda_config_dsn_needs_authentication
+ gda_config_error_get_type
+ gda_config_error_quark
+ gda_config_get
+ gda_config_get_dsn_info
+ gda_config_get_dsn_info_at_index
+ gda_config_get_dsn_info_index
+ gda_config_get_nb_dsn
+ gda_config_get_provider
+ gda_config_get_provider_info
+ gda_config_get_type
+ gda_config_list_dsn
+ gda_config_list_providers
+ gda_config_remove_dsn
+ gda_connection_add_event
+ gda_connection_add_event_string
+ gda_connection_add_prepared_statement
+ gda_connection_add_savepoint
+ gda_connection_batch_execute
+ gda_connection_begin_transaction
+ gda_connection_clear_events_list
+ gda_connection_close
+ gda_connection_close_no_warning
+ gda_connection_commit_transaction
+ gda_connection_create_operation
+ gda_connection_create_parser
+ gda_connection_delete_savepoint
+ gda_connection_del_prepared_statement
+ gda_connection_error_get_type
+ gda_connection_error_quark
+ gda_connection_event_code_get_type
+ gda_connection_event_get_code
+ gda_connection_event_get_description
+ gda_connection_event_get_event_type
+ gda_connection_event_get_gda_code
+ gda_connection_event_get_source
+ gda_connection_event_get_sqlstate
+ gda_connection_event_get_type
+ gda_connection_event_new
+ gda_connection_event_set_code
+ gda_connection_event_set_description
+ gda_connection_event_set_event_type
+ gda_connection_event_set_gda_code
+ gda_connection_event_set_source
+ gda_connection_event_set_sqlstate
+ gda_connection_event_type_get_type
+ gda_connection_feature_get_type
+ gda_connection_get_authentication
+ gda_connection_get_cnc_string
+ gda_connection_get_dsn
+ gda_connection_get_events
+ gda_connection_get_meta_store
+ gda_connection_get_meta_store_data
+ gda_connection_get_meta_store_data_v
+ gda_connection_get_options
+ gda_connection_get_prepared_statement
+ gda_connection_get_provider
+ gda_connection_get_provider_name
+ gda_connection_get_transaction_status
+ gda_connection_get_type
+ gda_connection_internal_change_transaction_state
+ gda_connection_internal_get_provider_data
+ gda_connection_internal_savepoint_added
+ gda_connection_internal_savepoint_removed
+ gda_connection_internal_savepoint_rolledback
+ gda_connection_internal_set_provider_data
+ gda_connection_internal_statement_executed
+ gda_connection_internal_transaction_committed
+ gda_connection_internal_transaction_rolledback
+ gda_connection_internal_transaction_started
+ gda_connection_is_opened
+ gda_connection_meta_type_get_type
+ gda_connection_open
+ gda_connection_open_from_dsn
+ gda_connection_open_from_string
+ gda_connection_options_get_type
+ gda_connection_perform_operation
+ gda_connection_rollback_savepoint
+ gda_connection_rollback_transaction
+ gda_connection_schema_get_type
+ gda_connection_statement_execute
+ gda_connection_statement_execute_non_select
+ gda_connection_statement_execute_select
+ gda_connection_statement_execute_select_full
+ gda_connection_statement_execute_select_fullv
+ gda_connection_statement_prepare
+ gda_connection_statement_to_sql
+ gda_connection_string_split
+ gda_connection_supports_feature
+ gda_connection_update_meta_store
+ gda_connection_value_to_sql_string
+ gda_data_access_wrapper_get_type
+ gda_data_access_wrapper_new
+ gda_data_comparator_compute_diff
+ gda_data_comparator_error_get_type
+ gda_data_comparator_error_quark
+ gda_data_comparator_get_diff
+ gda_data_comparator_get_n_diffs
+ gda_data_comparator_get_type
+ gda_data_comparator_new
+ gda_data_comparator_set_key_columns
+ gda_data_handler_accepts_g_type
+ gda_data_handler_get_descr
+ gda_data_handler_get_g_type_index
+ gda_data_handler_get_nb_g_types
+ gda_data_handler_get_sane_init_value
+ gda_data_handler_get_sql_from_value
+ gda_data_handler_get_str_from_value
+ gda_data_handler_get_type
+ gda_data_handler_get_value_from_sql
+ gda_data_handler_get_value_from_str
+ gda_data_model_access_flags_get_type
+ gda_data_model_add_data_from_xml_node
+ gda_data_model_append_row
+ gda_data_model_append_values
+ gda_data_model_array_clear
+ gda_data_model_array_copy_model
+ gda_data_model_array_get_row
+ gda_data_model_array_get_type
+ gda_data_model_array_new
+ gda_data_model_array_new_with_g_types
+ gda_data_model_array_set_n_columns
+#ifdef HAVE_BDB
+ gda_data_model_bdb_clean_errors
+ gda_data_model_bdb_get_errors
+ gda_data_model_bdb_get_type
+ gda_data_model_bdb_new
+#endif
+ gda_data_model_create_iter
+ gda_data_model_describe_column
+ gda_data_model_dir_clean_errors
+ gda_data_model_dir_get_errors
+ gda_data_model_dir_get_type
+ gda_data_model_dir_new
+ gda_data_model_dsn_list_get_type
+ gda_data_model_dump
+ gda_data_model_dump_as_string
+ gda_data_model_error_quark
+ gda_data_model_export_to_file
+ gda_data_model_export_to_string
+ gda_data_model_freeze
+ gda_data_model_get_access_flags
+ gda_data_model_get_attributes_at
+ gda_data_model_get_column_index
+ gda_data_model_get_column_name
+ gda_data_model_get_column_title
+ gda_data_model_get_n_columns
+ gda_data_model_get_n_rows
+ gda_data_model_get_row_from_values
+ gda_data_model_get_type
+ gda_data_model_get_typed_value_at
+ gda_data_model_get_value_at
+ gda_data_model_hint_get_type
+ gda_data_model_import_clean_errors
+ gda_data_model_import_from_file
+ gda_data_model_import_from_model
+ gda_data_model_import_from_string
+ gda_data_model_import_get_errors
+ gda_data_model_import_get_type
+ gda_data_model_import_new_file
+ gda_data_model_import_new_mem
+ gda_data_model_import_new_xml_node
+ gda_data_model_io_format_get_type
+ gda_data_model_iter_error_get_type
+ gda_data_model_iter_error_quark
+ gda_data_model_iter_get_column_for_param
+ gda_data_model_iter_get_holder_for_field
+ gda_data_model_iter_get_row
+ gda_data_model_iter_get_type
+ gda_data_model_iter_get_value_at
+ gda_data_model_iter_get_value_for_field
+ gda_data_model_iter_invalidate_contents
+ gda_data_model_iter_is_valid
+ gda_data_model_iter_move_at_row
+ gda_data_model_iter_move_at_row_default
+ gda_data_model_iter_move_next
+ gda_data_model_iter_move_next_default
+ gda_data_model_iter_move_prev
+ gda_data_model_iter_move_prev_default
+ gda_data_model_iter_set_value_at
+ gda_data_model_remove_row
+ gda_data_model_reset
+ gda_data_model_row_inserted
+ gda_data_model_row_removed
+ gda_data_model_row_updated
+ gda_data_model_send_hint
+ gda_data_model_set_column_name
+ gda_data_model_set_column_title
+ gda_data_model_set_value_at
+ gda_data_model_set_values
+ gda_data_model_thaw
+ gda_data_model_to_xml_node
+ gda_data_proxy_alter_value_attributes
+ gda_data_proxy_append
+ gda_data_proxy_apply_all_changes
+ gda_data_proxy_apply_row_changes
+ gda_data_proxy_cancel_all_changes
+ gda_data_proxy_cancel_row_changes
+ gda_data_proxy_delete
+ gda_data_proxy_error_get_type
+ gda_data_proxy_error_quark
+ gda_data_proxy_get_filtered_n_rows
+ gda_data_proxy_get_filter_expr
+ gda_data_proxy_get_model
+ gda_data_proxy_get_n_modified_rows
+ gda_data_proxy_get_n_new_rows
+ gda_data_proxy_get_proxied_model
+ gda_data_proxy_get_proxied_model_n_cols
+ gda_data_proxy_get_proxied_model_n_rows
+ gda_data_proxy_get_proxied_model_row
+ gda_data_proxy_get_sample_end
+ gda_data_proxy_get_sample_size
+ gda_data_proxy_get_sample_start
+ gda_data_proxy_get_type
+ gda_data_proxy_get_value_attributes
+ gda_data_proxy_get_values
+ gda_data_proxy_has_changed
+ gda_data_proxy_is_read_only
+ gda_data_proxy_new
+ gda_data_proxy_row_has_changed
+ gda_data_proxy_row_is_deleted
+ gda_data_proxy_row_is_inserted
+ gda_data_proxy_set_filter_expr
+ gda_data_proxy_set_ordering_column
+ gda_data_proxy_set_sample_size
+ gda_data_proxy_set_sample_start
+ gda_data_proxy_undelete
+ gda_data_select_compute_columns_attributes
+ gda_data_select_compute_modification_statements
+ gda_data_select_compute_row_selection_condition
+ gda_data_select_error_quark
+ gda_data_select_get_connection
+ gda_data_select_get_stored_row
+ gda_data_select_get_type
+ gda_data_select_set_modification_statement
+ gda_data_select_set_modification_statement_sql
+ gda_data_select_set_row_selection_condition
+ gda_data_select_set_row_selection_condition_sql
+ gda_data_select_take_row
+ gda_default_escape_string
+ gda_default_unescape_string
+ gda_delete_row_from_table
+ gda_diff_type_get_type
+ gda_dir_blob_get_filename
+ gda_dir_blob_op_get_type
+ gda_dir_blob_op_new
+ gda_dir_blob_set_filename
+ gda_dsn_split
+ gda_easy_create_table_flag_get_type
+ gda_easy_error_get_type
+ gda_easy_error_quark
+ gda_error_get_type
+ gda_execute_non_select_command
+ gda_execute_select_command
+ gda_gbr_get_file_path
+ gda_gbr_init
+ gda_geometricpoint_copy
+ gda_geometricpoint_free
+ gda_geometricpoint_get_type
+ gda_get_application_exec_path
+ gda_get_default_handler
+ gda_g_type_from_string
+ gda_g_type_to_string
+ gda_handler_bin_get_type
+ gda_handler_bin_new
+ gda_handler_boolean_get_type
+ gda_handler_boolean_new
+ gda_handler_numerical_get_type
+ gda_handler_numerical_new
+ gda_handler_string_get_type
+ gda_handler_string_new
+ gda_handler_string_new_with_provider
+ gda_handler_time_get_format
+ gda_handler_time_get_no_locale_str_from_value
+ gda_handler_time_get_type
+ gda_handler_time_new
+ gda_handler_time_new_no_locale
+ gda_handler_time_set_sql_spec
+ gda_handler_type_get_type
+ gda_handler_type_new
+ gda_holder_copy
+ gda_holder_error_get_type
+ gda_holder_error_quark
+ gda_holder_force_invalid
+ gda_holder_get_alphanum_id
+ gda_holder_get_attribute
+ gda_holder_get_bind
+ gda_holder_get_default_value
+ gda_holder_get_g_type
+ gda_holder_get_id
+ gda_holder_get_not_null
+ gda_holder_get_source_model
+ gda_holder_get_type
+ gda_holder_get_value
+ gda_holder_get_value_str
+ gda_holder_is_valid
+ gda_holder_new
+ gda_holder_new_inline
+ gda_holder_set_attribute
+ gda_holder_set_bind
+ gda_holder_set_default_value
+ gda_holder_set_not_null
+ gda_holder_set_source_model
+ gda_holder_set_value
+ gda_holder_set_value_str
+ gda_holder_set_value_to_default
+ gda_holder_take_static_value
+ gda_holder_take_value
+ gda_holder_value_is_default
+ gda_identifier_equal
+ gda_identifier_hash
+ gda_init
+ gda_insert_row_into_table
+ gda_insert_row_into_table_from_string
+ gda_lang_locale
+ gda_lockable_get_type
+ gda_lockable_lock
+ gda_lockable_trylock
+ gda_lockable_unlock
+ gda_log_disable
+ gda_log_enable
+ gda_log_error
+ gda_log_is_enabled
+ gda_log_message
+ gda_meta_db_object_type_get_type
+ gda_meta_graph_info_get_type
+ gda_meta_sort_type_get_type
+ gda_meta_store_change_type_get_type
+ gda_meta_store_create_modify_data_model
+ gda_meta_store_error_get_type
+ gda_meta_store_error_quark
+ gda_meta_store_extract
+ gda_meta_store_get_attribute_value
+ gda_meta_store_get_internal_connection
+ gda_meta_store_get_type
+ gda_meta_store_get_version
+ gda_meta_store_modify
+ gda_meta_store_modify_with_context
+ gda_meta_store_new
+ gda_meta_store_new_with_file
+ gda_meta_store_schema_add_custom_object
+ gda_meta_store_schema_get_all_tables
+ gda_meta_store_schema_get_depend_tables
+ gda_meta_store_schema_get_structure
+ gda_meta_store_schema_remove_custom_object
+ gda_meta_store_set_attribute_value
+ gda_meta_struct_add_db_object
+ gda_meta_struct_complement
+ gda_meta_struct_complement_all
+ gda_meta_struct_complement_default
+ gda_meta_struct_complement_depend
+ gda_meta_struct_complement_schema
+ gda_meta_struct_dump_as_graph
+ gda_meta_struct_error_get_type
+ gda_meta_struct_error_quark
+ gda_meta_struct_feature_get_type
+ gda_meta_struct_get_all_db_objects
+ gda_meta_struct_get_db_object
+ gda_meta_struct_get_table_column
+ gda_meta_struct_get_type
+ gda_meta_struct_load_from_xml_file
+ gda_meta_struct_new
+ gda_meta_struct_sort_db_objects
+ gda_meta_table_column_foreach_attribute
+ gda_meta_table_column_get_attribute
+ gda_meta_table_column_set_attribute
+ gda_mutex_free
+ gda_mutex_lock
+ gda_mutex_new
+ gda_mutex_trylock
+ gda_mutex_unlock
+ gda_numeric_copy
+ gda_numeric_free
+ gda_numeric_get_type
+ gda_numeric_locale
+ gda_parse_iso8601_date
+ gda_parse_iso8601_time
+ gda_parse_iso8601_timestamp
+ gda_perform_create_database
+ gda_perform_create_table
+ gda_perform_drop_database
+ gda_perform_drop_table
+ gda_prepare_create_database
+ gda_prepare_create_table
+ gda_prepare_drop_database
+ gda_prepare_drop_table
+ gda_pstmt_copy_contents
+ gda_pstmt_get_gda_statement
+ gda_pstmt_get_type
+ gda_pstmt_set_gda_statement
+ gda_quark_list_add_from_string
+ gda_quark_list_clear
+ gda_quark_list_copy
+ gda_quark_list_find
+ gda_quark_list_foreach
+ gda_quark_list_free
+ gda_quark_list_get_type
+ gda_quark_list_new
+ gda_quark_list_new_from_string
+ gda_quark_list_remove
+ gda_rfc1738_decode
+ gda_rfc1738_encode
+ gda_row_get_length
+ gda_row_get_type
+ gda_row_get_value
+ gda_row_new
+ gda_select_alter_select_for_empty
+ gda_server_operation_add_item_to_sequence
+ gda_server_operation_del_item_from_sequence
+ gda_server_operation_get_node_info
+ gda_server_operation_get_node_parent
+ gda_server_operation_get_node_path_portion
+ gda_server_operation_get_node_type
+ gda_server_operation_get_op_type
+ gda_server_operation_get_root_nodes
+ gda_server_operation_get_sequence_item_names
+ gda_server_operation_get_sequence_max_size
+ gda_server_operation_get_sequence_min_size
+ gda_server_operation_get_sequence_name
+ gda_server_operation_get_sequence_size
+ gda_server_operation_get_type
+ gda_server_operation_get_value_at
+ gda_server_operation_is_valid
+ gda_server_operation_load_data_from_xml
+ gda_server_operation_new
+ gda_server_operation_node_status_get_type
+ gda_server_operation_node_type_get_type
+ gda_server_operation_op_type_to_string
+ gda_server_operation_save_data_to_xml
+ gda_server_operation_set_value_at
+ gda_server_operation_type_get_type
+ gda_server_provider_blob_list_for_delete
+ gda_server_provider_blob_list_for_update
+ gda_server_provider_create_operation
+ gda_server_provider_create_parser
+ gda_server_provider_error_get_type
+ gda_server_provider_error_quark
+ gda_server_provider_escape_string
+ gda_server_provider_find_file
+ gda_server_provider_get_data_handler_dbms
+ gda_server_provider_get_data_handler_default
+ gda_server_provider_get_data_handler_g_type
+ gda_server_provider_get_default_dbms_type
+ gda_server_provider_get_name
+ gda_server_provider_get_schema_nb_columns
+ gda_server_provider_get_server_version
+ gda_server_provider_get_type
+ gda_server_provider_get_version
+ gda_server_provider_handler_declare
+ gda_server_provider_handler_find
+ gda_server_provider_init_schema_model
+ gda_server_provider_internal_get_parser
+ gda_server_provider_load_file_contents
+ gda_server_provider_perform_operation
+ gda_server_provider_perform_operation_default
+ gda_server_provider_render_operation
+ gda_server_provider_select_query_has_blobs
+ gda_server_provider_split_update_query
+ gda_server_provider_string_to_value
+ gda_server_provider_supports_feature
+ gda_server_provider_supports_operation
+ gda_server_provider_test_schema_model
+ gda_server_provider_unescape_string
+ gda_server_provider_value_to_sql_string
+ gda_set_add_holder
+ gda_set_copy
+ gda_set_error_get_type
+ gda_set_error_quark
+ gda_set_get_group
+ gda_set_get_holder
+ gda_set_get_holder_value
+ gda_set_get_node
+ gda_set_get_source
+ gda_set_get_source_for_model
+ gda_set_get_type
+ gda_set_is_valid
+ gda_set_merge_with_set
+ gda_set_new
+ gda_set_new_from_spec_node
+ gda_set_new_from_spec_string
+ gda_set_new_inline
+ gda_set_remove_holder
+ gda_set_set_holder_value
+ gda_short_get_type
+ gda_sql_any_part_check_structure
+ gda_sql_any_part_foreach
+ gda_sql_any_part_type_get_type
+ gda_sql_case_copy
+ gda_sql_case_free
+ gda_sql_case_new
+ gda_sql_case_serialize
+ gda_sql_delimiter
+ gda_sql_delimiterAlloc
+ gda_sql_delimiterFree
+ gda_sql_delimiterTrace
+ gda_sql_error_quark
+ gda_sql_error_type_get_type
+ gda_sql_expr_check_clean
+ gda_sql_expr_copy
+ gda_sql_expr_free
+ gda_sql_expr_new
+ gda_sql_expr_serialize
+ gda_sql_expr_take_select
+ gda_sql_field_check_clean
+ gda_sql_field_copy
+ gda_sql_field_free
+ gda_sql_field_new
+ gda_sql_field_serialize
+ gda_sql_field_take_name
+ gda_sql_function_check_clean
+ gda_sql_function_copy
+ gda_sql_function_free
+ gda_sql_function_new
+ gda_sql_function_serialize
+ gda_sql_function_take_args_list
+ gda_sql_function_take_name
+ gda_sql_identifier_add_quotes
+ gda_sql_identifier_needs_quotes
+ gda_sql_identifier_remove_quotes
+ gda_sqlite_handler_bin_get_type
+ gda_sqlite_handler_bin_new
+ gda_sqlite_provider_get_type
+ gda_sqlite_pstmt_get_type
+ gda_sqlite_pstmt_new
+ gda_sqlite_recordset_get_type
+ gda_sqlite_recordset_new
+ gda_sqlite_render_ADD_COLUMN
+ gda_sqlite_render_CREATE_INDEX
+ gda_sqlite_render_CREATE_TABLE
+ gda_sqlite_render_CREATE_VIEW
+ gda_sqlite_render_DROP_INDEX
+ gda_sqlite_render_DROP_TABLE
+ gda_sqlite_render_DROP_VIEW
+ gda_sqlite_render_RENAME_TABLE
+ gda_sql_operation_copy
+ gda_sql_operation_free
+ gda_sql_operation_new
+ gda_sql_operation_operator_from_string
+ gda_sql_operation_operator_to_string
+ gda_sql_operation_serialize
+ gda_sql_operator_type_get_type
+ gda_sql_param_spec_copy
+ gda_sql_param_spec_free
+ gda_sql_param_spec_new
+ gda_sql_param_spec_serialize
+ gda_sql_param_spec_take_descr
+ gda_sql_param_spec_take_name
+ gda_sql_param_spec_take_nullok
+ gda_sql_param_spec_take_type
+ gda_sql_parser
+ gda_sql_parserAlloc
+ gda_sql_parser_error_get_type
+ gda_sql_parser_error_quark
+ gda_sql_parser_flavour_get_type
+ gda_sql_parserFree
+ gda_sql_parser_get_type
+ gda_sql_parser_mode_get_type
+ gda_sql_parser_new
+ gda_sql_parser_parse_file_as_batch
+ gda_sql_parser_parse_string
+ gda_sql_parser_parse_string_as_batch
+ gda_sql_parser_set_overflow_error
+ gda_sql_parser_set_syntax_error
+ gda_sql_parserTrace
+ gda_sql_select_field_check_clean
+ gda_sql_select_field_copy
+ gda_sql_select_field_free
+ gda_sql_select_field_new
+ gda_sql_select_field_serialize
+ gda_sql_select_field_take_alias
+ gda_sql_select_field_take_expr
+ gda_sql_select_field_take_star_value
+ gda_sql_select_from_copy
+ gda_sql_select_from_free
+ gda_sql_select_from_new
+ gda_sql_select_from_serialize
+ gda_sql_select_from_take_new_join
+ gda_sql_select_from_take_new_target
+ gda_sql_select_join_copy
+ gda_sql_select_join_free
+ gda_sql_select_join_new
+ gda_sql_select_join_serialize
+ gda_sql_select_join_type_get_type
+ gda_sql_select_join_type_to_string
+ gda_sql_select_order_copy
+ gda_sql_select_order_free
+ gda_sql_select_order_new
+ gda_sql_select_order_serialize
+ gda_sql_select_target_check_clean
+ gda_sql_select_target_copy
+ gda_sql_select_target_free
+ gda_sql_select_target_new
+ gda_sql_select_target_serialize
+ gda_sql_select_target_take_alias
+ gda_sql_select_target_take_select
+ gda_sql_select_target_take_table_name
+ gda_sql_statement_begin_get_infos
+ gda_sql_statement_check_clean
+ gda_sql_statement_check_structure
+ gda_sql_statement_check_validity
+ gda_sql_statement_commit_get_infos
+ gda_sql_statement_compound_copy
+ gda_sql_statement_compound_free
+ gda_sql_statement_compound_get_infos
+ gda_sql_statement_compound_get_n_cols
+ gda_sql_statement_compound_reduce
+ gda_sql_statement_compound_serialize
+ gda_sql_statement_compound_set_type
+ gda_sql_statement_compound_take_stmt
+ gda_sql_statement_compound_type_get_type
+ gda_sql_statement_copy
+ gda_sql_statement_delete_get_infos
+ gda_sql_statement_delete_savepoint_get_infos
+ gda_sql_statement_delete_take_condition
+ gda_sql_statement_delete_take_table_name
+ gda_sql_statement_free
+ gda_sql_statement_get_contents_infos
+ gda_sql_statement_insert_get_infos
+ gda_sql_statement_insert_take_1_values_list
+ gda_sql_statement_insert_take_extra_values_list
+ gda_sql_statement_insert_take_fields_list
+ gda_sql_statement_insert_take_on_conflict
+ gda_sql_statement_insert_take_select
+ gda_sql_statement_insert_take_table_name
+ gda_sql_statement_new
+ gda_sql_statement_normalize
+ gda_sql_statement_rollback_get_infos
+ gda_sql_statement_rollback_savepoint_get_infos
+ gda_sql_statement_savepoint_get_infos
+ gda_sql_statement_select_copy
+ gda_sql_statement_select_free
+ gda_sql_statement_select_get_infos
+ gda_sql_statement_select_new
+ gda_sql_statement_select_serialize
+ gda_sql_statement_select_take_distinct
+ gda_sql_statement_select_take_expr_list
+ gda_sql_statement_select_take_from
+ gda_sql_statement_select_take_group_by
+ gda_sql_statement_select_take_having_cond
+ gda_sql_statement_select_take_limits
+ gda_sql_statement_select_take_order_by
+ gda_sql_statement_select_take_where_cond
+ gda_sql_statement_serialize
+ gda_sql_statement_string_to_type
+ gda_sql_statement_trans_set_isol_level
+ gda_sql_statement_trans_take_mode
+ gda_sql_statement_trans_take_name
+ gda_sql_statement_type_get_type
+ gda_sql_statement_type_to_string
+ gda_sql_statement_unknown_get_infos
+ gda_sql_statement_unknown_take_expressions
+ gda_sql_statement_update_get_infos
+ gda_sql_statement_update_take_condition
+ gda_sql_statement_update_take_on_conflict
+ gda_sql_statement_update_take_set_value
+ gda_sql_statement_update_take_table_name
+ gda_sql_table_check_clean
+ gda_sql_table_copy
+ gda_sql_table_free
+ gda_sql_table_new
+ gda_sql_table_serialize
+ gda_sql_table_take_name
+ gda_sql_value_stringify
+ gda_statement_check_structure
+ gda_statement_check_validity
+ gda_statement_copy
+ gda_statement_error_get_type
+ gda_statement_error_quark
+ gda_statement_get_parameters
+ gda_statement_get_statement_type
+ gda_statement_get_type
+ gda_statement_is_useless
+ gda_statement_model_usage_get_type
+ gda_statement_new
+ gda_statement_normalize
+ gda_statement_serialize
+ gda_statement_sql_flag_get_type
+ gda_statement_to_sql_extended
+ gda_statement_to_sql_real
+ gda_string_to_binary
+ gda_string_to_blob
+ gda_text_to_alphanum
+ gda_threader_cancel
+ gda_threader_get_type
+ gda_threader_new
+ gda_threader_start_thread
+ gda_time_copy
+ gda_time_free
+ gda_time_get_type
+ gda_timestamp_copy
+ gda_timestamp_free
+ gda_timestamp_get_type
+ gda_transaction_isolation_get_type
+ gda_transaction_status_add_event_sql
+ gda_transaction_status_add_event_sub
+ gda_transaction_status_add_event_svp
+ gda_transaction_status_dump
+ gda_transaction_status_event_type_get_type
+ gda_transaction_status_find
+ gda_transaction_status_find_current
+ gda_transaction_status_free_events
+ gda_transaction_status_get_type
+ gda_transaction_status_new
+ gda_transaction_status_state_get_type
+ gda_update_value_in_table
+ gda_update_values_in_table
+ gda_ushort_get_type
+ gda_utility_check_data_model
+ gda_utility_data_model_dump_data_to_xml
+ gda_utility_holder_load_attributes
+ gda_value_attribute_get_type
+ gda_value_compare
+ gda_value_copy
+ gda_value_differ
+ gda_value_free
+ gda_value_get_binary
+ gda_value_get_blob
+ gda_value_get_geometric_point
+ gda_value_get_list
+ gda_value_get_numeric
+ gda_value_get_short
+ gda_value_get_time
+ gda_value_get_timestamp
+ gda_value_get_ushort
+ gda_value_is_null
+ gda_value_is_number
+ gda_value_list_copy
+ gda_value_list_free
+ gda_value_list_get_type
+ gda_value_new
+ gda_value_new_binary
+ gda_value_new_blob
+ gda_value_new_blob_from_file
+ gda_value_new_from_string
+ gda_value_new_from_xml
+ gda_value_new_timestamp_from_timet
+ gda_value_reset_with_type
+ gda_value_set_binary
+ gda_value_set_blob
+ gda_value_set_from_string
+ gda_value_set_from_value
+ gda_value_set_geometric_point
+ gda_value_set_list
+ gda_value_set_null
+ gda_value_set_numeric
+ gda_value_set_short
+ gda_value_set_time
+ gda_value_set_timestamp
+ gda_value_set_ushort
+ gda_value_stringify
+ gda_value_take_binary
+ gda_value_take_blob
+ gda_value_to_xml
+ gda_vconnection_data_model_add
+ gda_vconnection_data_model_add_model
+ gda_vconnection_data_model_foreach
+ gda_vconnection_data_model_get_model
+ gda_vconnection_data_model_get_table_name
+ gda_vconnection_data_model_get_type
+ gda_vconnection_data_model_remove
+ gda_vconnection_data_model_table_data_free
+ gda_vconnection_get_table_data_by_model
+ gda_vconnection_get_table_data_by_name
+ gda_vconnection_get_table_data_by_unique_name
+ gda_vconnection_hub_add
+ gda_vconnection_hub_foreach
+ gda_vconnection_hub_get_connection
+ gda_vconnection_hub_get_type
+ gda_vconnection_hub_remove
+ gda_virtual_connection_get_type
+ gda_virtual_connection_internal_get_provider_data
+ gda_virtual_connection_internal_set_provider_data
+ gda_virtual_connection_open
+ gda_virtual_provider_get_type
+ gda_vprovider_data_model_get_type
+ gda_vprovider_data_model_new
+ gda_vprovider_hub_get_type
+ gda_vprovider_hub_new
+ gda_xa_transaction_begin
+ gda_xa_transaction_commit
+ gda_xa_transaction_commit_recovered
+ gda_xa_transaction_error_get_type
+ gda_xa_transaction_error_quark
+ gda_xa_transaction_get_type
+ gda_xa_transaction_id_to_string
+ gda_xa_transaction_new
+ gda_xa_transaction_register_connection
+ gda_xa_transaction_rollback
+ gda_xa_transaction_string_to_id
+ gda_xa_transaction_unregister_connection
Modified: trunk/po/POTFILES.in
==============================================================================
--- trunk/po/POTFILES.in (original)
+++ trunk/po/POTFILES.in Wed Dec 10 21:11:52 2008
@@ -132,4 +132,6 @@
tools/gda-list-config.c
tools/gda-list-server-op.c
tools/gda-sql.c
+tools/html-doc.c
tools/tools-input.c
+tools/web-server.c
Modified: trunk/tools/Makefile.am
==============================================================================
--- trunk/tools/Makefile.am (original)
+++ trunk/tools/Makefile.am Wed Dec 10 21:11:52 2008
@@ -23,6 +23,7 @@
gda_sql_4_0_SOURCES = \
gda-sql.c \
+ gda-sql.h \
tools-input.h \
tools-input.c \
command-exec.h \
@@ -34,6 +35,12 @@
$(READLINE_LIB) \
$(HISTORY_LIB)
+if LIBSOUP
+gda_sql_4_0_SOURCES += web-server.h web-server.c html-doc.h html-doc.c
+AM_CPPFLAGS += $(LIBSOUP_CFLAGS)
+gda_sql_4_0_LDADD += $(LIBSOUP_LIBS)
+endif
+
# setenv() is in libiberty in mingw
Modified: trunk/tools/gda-sql.c
==============================================================================
--- trunk/tools/gda-sql.c (original)
+++ trunk/tools/gda-sql.c Wed Dec 10 21:11:52 2008
@@ -19,8 +19,7 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include <libgda/libgda.h>
-#include <sql-parser/gda-sql-parser.h>
+#include "gda-sql.h"
#include <virtual/libgda-virtual.h>
#include <glib/gi18n-lib.h>
#include <glib/gprintf.h>
@@ -49,6 +48,10 @@
#include <readline/readline.h>
#endif
+#ifdef HAVE_LIBSOUP
+#include "web-server.h"
+#endif
+
/* options */
gboolean ask_pass = FALSE;
@@ -62,6 +65,10 @@
gchar *outfile = NULL;
gboolean has_threads;
+#ifdef HAVE_LIBSOUP
+gint http_port = -1;
+#endif
+
static GOptionEntry entries[] = {
{ "no-password-ask", 'p', 0, G_OPTION_ARG_NONE, &ask_pass, "Don't ask for a password when it is empty", NULL },
@@ -71,6 +78,9 @@
{ "interractive", 'i', 0, G_OPTION_ARG_NONE, &interractive, "Keep the console opened after executing a file (-f option)", NULL },
{ "list-dsn", 'l', 0, G_OPTION_ARG_NONE, &list_configs, "List configured data sources and exit", NULL },
{ "list-providers", 'L', 0, G_OPTION_ARG_NONE, &list_providers, "List installed database providers and exit", NULL },
+#ifdef HAVE_LIBSOUP
+ { "http-port", 's', 0, G_OPTION_ARG_INT, &http_port, "Run embedded HTTP server on specified port", "port" },
+#endif
{ NULL }
};
@@ -93,19 +103,6 @@
OUTPUT_FORMAT_CSV
} OutputFormat;
-/*
- * structure representing an opened connection
- */
-typedef struct {
- gchar *name;
- GdaConnection *cnc;
- GdaSqlParser *parser;
- GString *query_buffer;
-
- GdaThreader *threader;
- guint meta_job_id;
-} ConnectionSetting;
-
/* structure to hold program's data */
typedef struct {
GSList *settings; /* list all the CncSetting */
@@ -120,11 +117,15 @@
GString *partial_command;
GHashTable *parameters; /* key = name, value = G_TYPE_STRING GdaParameter */
+
+#ifdef HAVE_LIBSOUP
+ WebServer *server;
+#endif
} MainData;
MainData *main_data;
GString *prompt = NULL;
+GMainLoop *main_loop = NULL;
-static gchar *read_a_line (MainData *data);
static char **completion_func (const char *text, int start, int end);
static void compute_prompt (MainData *data, GString *string, gboolean in_command);
static gboolean set_output_file (MainData *data, const gchar *file, GError **error);
@@ -137,6 +138,10 @@
static GdaDataModel *list_all_dsn (MainData *data);
static GdaDataModel *list_all_providers (MainData *data);
+static gboolean treat_line_func (const gchar *cmde, MainData *data);
+static const char *prompt_func (void);
+
+
/* commands manipulation */
static GdaInternalCommandsList *build_internal_commands_list (MainData *data);
static gboolean command_is_complete (const gchar *command);
@@ -270,93 +275,156 @@
/* build internal command s list */
data->internal_commands = build_internal_commands_list (data);
- /* loop over commands */
- setup_sigint_handler ();
- init_input ();
- set_completion_func (completion_func);
- init_history ();
- for (;;) {
- gchar *cmde;
+#ifdef HAVE_LIBSOUP
+ /* start HTTP server if requested */
+ if (http_port > 0) {
+ main_data->server = web_server_new (http_port);
+ if (!main_data->server) {
+ g_print (_("Can't run HTTP server on port %d\n"), http_port);
+ exit_status = EXIT_FAILURE;
+ goto cleanup;
+ }
+ }
+#endif
- /* run any pending iterations */
- while (g_main_context_iteration (NULL, FALSE));
+ /* process commands which need to be executed as specified by the command line args */
+ if (single_command) {
+ treat_line_func (single_command, data);
+ if (!data->output_stream)
+ g_print ("\n");
+ goto cleanup;
+ }
- cmde = read_a_line (data);
- if (!cmde) {
- save_history (NULL, NULL);
+ if (data->input_stream) {
+ gchar *cmde;
+ for (;;) {
+ cmde = input_from_stream (data->input_stream);
+ if (cmde) {
+ treat_line_func (cmde, data);
+ g_free (cmde);
+ }
+ else
+ break;
+ }
+ if (interractive && !cmde && isatty (fileno (stdin)))
+ set_input_file (data, NULL, NULL);
+ else {
if (!data->output_stream)
g_print ("\n");
goto cleanup;
}
+ }
- g_strchug (cmde);
- if (*cmde) {
- if (!data->partial_command) {
- /* enable SIGINT handling */
- sigint_handler_status = SIGINT_HANDLER_PARTIAL_COMMAND;
- data->partial_command = g_string_new (cmde);
- }
- else {
- g_string_append_c (data->partial_command, ' ');
- g_string_append (data->partial_command, cmde);
- }
- if (command_is_complete (data->partial_command->str)) {
- /* execute command */
- GdaInternalCommandResult *res;
- FILE *to_stream;
+ /* set up interractive commands */
+ setup_sigint_handler ();
+ init_input ((TreatLineFunc) treat_line_func, prompt_func, data);
+ set_completion_func (completion_func);
+ init_history ();
+
+ /* run main loop */
+ main_loop = g_main_loop_new (NULL, TRUE);
+ g_main_loop_run (main_loop);
+ g_main_loop_unref (main_loop);
- if ((*data->partial_command->str != '\\') && (*data->partial_command->str != '.')) {
- if (data->current) {
- if (!data->current->query_buffer)
- data->current->query_buffer = g_string_new ("");
- g_string_assign (data->current->query_buffer, data->partial_command->str);
- }
- }
- if (data && data->output_stream)
- to_stream = data->output_stream;
- else
- to_stream = stdout;
- res = command_execute (data, data->partial_command->str, &error);
-
- if (!res) {
- g_fprintf (to_stream,
- "ERROR: %s\n",
- error && error->message ? error->message : _("No detail"));
- if (error) {
- g_error_free (error);
- error = NULL;
- }
- }
- else {
- display_result (data, res);
- if (res->type == GDA_INTERNAL_COMMAND_RESULT_EXIT) {
- gda_internal_command_exec_result_free (res);
- goto cleanup;
- }
- gda_internal_command_exec_result_free (res);
- }
- g_string_free (data->partial_command, TRUE);
- data->partial_command = NULL;
-
- /* disable SIGINT handling */
- sigint_handler_status = SIGINT_HANDLER_DISABLED;
- }
- }
- g_free (cmde);
- }
-
- /* cleanups */
cleanup:
+ /* cleanups */
g_slist_foreach (data->settings, (GFunc) connection_settings_free, NULL);
set_input_file (data, NULL, NULL);
set_output_file (data, NULL, NULL);
+ end_input ();
g_free (data);
return EXIT_SUCCESS;
}
+static const char *
+prompt_func (void)
+{
+ /* compute a new prompt */
+ compute_prompt (main_data, prompt, main_data->partial_command == NULL ? FALSE : TRUE);
+ return (char*) prompt->str;
+}
+
+/* @cmde is stolen here */
+static gboolean
+treat_line_func (const gchar *cmde, MainData *data)
+{
+ gchar *loc_cmde = NULL;
+ if (!cmde) {
+ save_history (NULL, NULL);
+ if (!data->output_stream)
+ g_print ("\n");
+ goto exit;
+ }
+
+ loc_cmde = g_strdup (cmde);
+ g_strchug (loc_cmde);
+ if (*loc_cmde) {
+ add_to_history (loc_cmde);
+ if (!data->partial_command) {
+ /* enable SIGINT handling */
+ sigint_handler_status = SIGINT_HANDLER_PARTIAL_COMMAND;
+ data->partial_command = g_string_new (loc_cmde);
+ }
+ else {
+ g_string_append_c (data->partial_command, ' ');
+ g_string_append (data->partial_command, loc_cmde);
+ }
+ if (command_is_complete (data->partial_command->str)) {
+ /* execute command */
+ GdaInternalCommandResult *res;
+ FILE *to_stream;
+ GError *error = NULL;
+
+ if ((*data->partial_command->str != '\\') && (*data->partial_command->str != '.')) {
+ if (data->current) {
+ if (!data->current->query_buffer)
+ data->current->query_buffer = g_string_new ("");
+ g_string_assign (data->current->query_buffer, data->partial_command->str);
+ }
+ }
+
+ if (data && data->output_stream)
+ to_stream = data->output_stream;
+ else
+ to_stream = stdout;
+ res = command_execute (data, data->partial_command->str, &error);
+
+ if (!res) {
+ g_fprintf (to_stream,
+ "ERROR: %s\n",
+ error && error->message ? error->message : _("No detail"));
+ if (error) {
+ g_error_free (error);
+ error = NULL;
+ }
+ }
+ else {
+ display_result (data, res);
+ if (res->type == GDA_INTERNAL_COMMAND_RESULT_EXIT) {
+ gda_internal_command_exec_result_free (res);
+ goto exit;
+ }
+ gda_internal_command_exec_result_free (res);
+ }
+ g_string_free (data->partial_command, TRUE);
+ data->partial_command = NULL;
+
+ /* disable SIGINT handling */
+ sigint_handler_status = SIGINT_HANDLER_DISABLED;
+ }
+ }
+ g_free (loc_cmde);
+ return TRUE;
+
+ exit:
+ g_free (loc_cmde);
+ g_main_loop_quit (main_loop);
+ return FALSE;
+}
+
static void
display_result (MainData *data, GdaInternalCommandResult *res)
{
@@ -480,6 +548,8 @@
}
case GDA_INTERNAL_COMMAND_RESULT_TXT_STDOUT:
g_print ("%s", res->u.txt->str);
+ if (res->u.txt->str [strlen (res->u.txt->str) - 1] != '\n')
+ g_print ("\n");
fflush (NULL);
break;
case GDA_INTERNAL_COMMAND_RESULT_EMPTY:
@@ -540,39 +610,6 @@
#endif
/*
- * read_a_line
- *
- * Read a line to be processed
- */
-static gchar *read_a_line (MainData *data)
-{
- gchar *cmde;
-
- if (single_command) {
- if (*single_command) {
- cmde = single_command;
- single_command = "";
- return cmde;
- }
- else
- return NULL;
- }
- compute_prompt (data, prompt, data->partial_command == NULL ? FALSE : TRUE);
- if (data->input_stream) {
- cmde = input_from_stream (data->input_stream);
- if (interractive && !cmde && isatty (fileno (stdin))) {
- /* go back to console after file is over */
- set_input_file (data, NULL, NULL);
- cmde = input_from_console (prompt->str);
- }
- }
- else
- cmde = input_from_console (prompt->str);
-
- return cmde;
-}
-
-/*
* command_is_complete
*
* Checks if @command can be executed, or if more data is required
@@ -773,8 +810,6 @@
return res;
}
-
-
static void
compute_prompt (MainData *data, GString *string, gboolean in_command)
{
@@ -1480,6 +1515,10 @@
static GdaInternalCommandResult *extra_command_graph (GdaConnection *cnc, const gchar **args,
GError **error, MainData *data);
+#ifdef HAVE_LIBSOUP
+static GdaInternalCommandResult *extra_command_httpd (GdaConnection *cnc, const gchar **args,
+ GError **error, MainData *data);
+#endif
static GdaInternalCommandResult *extra_command_lo_update (GdaConnection *cnc, const gchar **args,
GError **error, MainData *data);
@@ -1571,6 +1610,19 @@
c->unquote_args = FALSE;
commands->commands = g_slist_prepend (commands->commands, c);
+#ifdef HAVE_LIBSOUP
+ c = g_new0 (GdaInternalCommand, 1);
+ c->group = _("Information");
+ c->name = g_strdup_printf (_("%s [port]"), "http");
+ c->description = _("Start/stop embedded HTTP server (on given port or on 12345 by default)");
+ c->args = NULL;
+ c->command_func = (GdaInternalCommandFunc) extra_command_httpd;
+ c->user_data = data;
+ c->arguments_delimiter_func = NULL;
+ c->unquote_args = FALSE;
+ commands->commands = g_slist_prepend (commands->commands, c);
+#endif
+
/* specific commands */
c = g_new0 (GdaInternalCommand, 1);
c->group = _("General");
@@ -3672,6 +3724,49 @@
return NULL;
}
+#ifdef HAVE_LIBSOUP
+static GdaInternalCommandResult *
+extra_command_httpd (GdaConnection *cnc, const gchar **args,
+ GError **error, MainData *data)
+{
+ GdaInternalCommandResult *res = NULL;
+ if (data->server) {
+ /* stop server */
+ g_object_unref (data->server);
+ data->server = NULL;
+ res = g_new0 (GdaInternalCommandResult, 1);
+ res->type = GDA_INTERNAL_COMMAND_RESULT_TXT_STDOUT;
+ res->u.txt = g_string_new (_("HTTPD server stopped"));
+ }
+ else {
+ /* start new server */
+ gint port = 12345;
+ if (args[0] && *args[0]) {
+ gchar *ptr;
+ port = (gint) strtol (args[0], &ptr, 10);
+ if (ptr && *ptr)
+ port = -1;
+ }
+ if (port > 0) {
+ data->server = web_server_new (port);
+ if (!data->server)
+ g_set_error (error, 0, 0,
+ _("Could not start HTTPD server"));
+ else {
+ res = g_new0 (GdaInternalCommandResult, 1);
+ res->type = GDA_INTERNAL_COMMAND_RESULT_TXT_STDOUT;
+ res->u.txt = g_string_new (_("HTTPD server started"));
+ }
+ }
+ else
+ g_set_error (error, 0, 0,
+ _("Invalid port specification"));
+ }
+
+ return res;
+}
+#endif
+
#ifdef NONE
static GdaInternalCommandResult *
extra_command_lo_update (GdaConnection *cnc, const gchar **args,
@@ -3831,3 +3926,22 @@
return NULL;
#endif
}
+
+
+const GSList *
+gda_sql_get_all_connections (void)
+{
+ return main_data->settings;
+}
+
+const ConnectionSetting *
+gda_sql_get_connection (const gchar *name)
+{
+ return find_connection_from_name (main_data, name);
+}
+
+const ConnectionSetting *
+gda_sql_get_current_connection (void)
+{
+ return main_data->current;
+}
Added: trunk/tools/gda-sql.h
==============================================================================
--- (empty file)
+++ trunk/tools/gda-sql.h Wed Dec 10 21:11:52 2008
@@ -0,0 +1,49 @@
+/* GDA - SQL console
+ * Copyright (C) 2007 - 2008 The GNOME Foundation.
+ *
+ * AUTHORS:
+ * Vivien Malerba <malerba gnome-db org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __GDA_SQL_H_
+#define __GDA_SQL_H_
+
+#include <libgda/libgda.h>
+#include <sql-parser/gda-sql-parser.h>
+
+G_BEGIN_DECLS
+
+/*
+ * structure representing an opened connection
+ */
+typedef struct {
+ gchar *name;
+ GdaConnection *cnc;
+ GdaSqlParser *parser;
+ GString *query_buffer;
+
+ GdaThreader *threader;
+ guint meta_job_id;
+} ConnectionSetting;
+
+const GSList *gda_sql_get_all_connections (void);
+const ConnectionSetting *gda_sql_get_connection (const gchar *name);
+const ConnectionSetting *gda_sql_get_current_connection (void);
+
+G_END_DECLS
+
+#endif
Added: trunk/tools/html-doc.c
==============================================================================
--- (empty file)
+++ trunk/tools/html-doc.c Wed Dec 10 21:11:52 2008
@@ -0,0 +1,89 @@
+#include "html-doc.h"
+#include <glib/gi18n-lib.h>
+
+HtmlDoc *
+html_doc_new (const gchar *title)
+{
+ HtmlDoc *hdoc;
+ xmlNodePtr topnode, head, node, div, container;
+
+ hdoc = g_new0 (HtmlDoc, 1);
+ hdoc->doc = xmlNewDoc ("1.0");
+ topnode = xmlNewDocNode (hdoc->doc, NULL, "html", NULL);
+ xmlDocSetRootElement (hdoc->doc, topnode);
+
+ /* head */
+ head = xmlNewChild (topnode, NULL, "head", NULL);
+
+ node = xmlNewChild (head, NULL, "meta", NULL);
+ xmlSetProp(node, "http-equiv", (xmlChar*)"Content-Type");
+ xmlSetProp(node, "content", (xmlChar*)"text/html; charset=UTF-8");
+
+ node = xmlNewChild (head, NULL, "meta", NULL);
+ xmlSetProp(node, "http-equiv", (xmlChar*)"refresh");
+ xmlSetProp(node, "content", (xmlChar*)"30"); /* refresh the page every 30 seconds */
+
+ node = xmlNewChild (head, NULL, "title", title);
+ node = xmlNewChild (head, NULL, "link", NULL);
+ xmlSetProp(node, "href", (xmlChar*)"/gda.css");
+ xmlSetProp(node, "rel", (xmlChar*)"stylesheet");
+ xmlSetProp(node, "type", (xmlChar*)"text/css");
+
+ /* body */
+ node = xmlNewChild (topnode, NULL, "body", NULL);
+ hdoc->body = node;
+
+ /* container */
+ container = xmlNewChild (hdoc->body, NULL, "div", NULL);
+ xmlSetProp(container, "id", (xmlChar*)"container");
+
+ /* top */
+ div = xmlNewChild (container, NULL, "div", NULL);
+ xmlSetProp (div, "id", (xmlChar*)"top");
+
+ xmlNewChild (div, NULL, "h1", title);
+
+
+ /* leftnav */
+ div = xmlNewChild (container, NULL, "div", NULL);
+ xmlSetProp(div, "id", (xmlChar*)"leftnav");
+ hdoc->sidebar = div;
+
+ /* content */
+ div = xmlNewChild (container, NULL, "div", NULL);
+ xmlSetProp(div, "id", (xmlChar*)"content");
+ hdoc->content = div;
+
+ /* footer */
+ div = xmlNewChild (container, NULL, "div", NULL);
+ xmlSetProp(div, "id", (xmlChar*)"footer");
+ xmlNewChild (div, NULL, "p", NULL);
+
+ return hdoc;
+}
+
+void
+html_doc_free (HtmlDoc *hdoc)
+{
+ xmlFreeDoc (hdoc->doc);
+ g_free (hdoc);
+}
+
+xmlChar *
+html_doc_to_string (HtmlDoc *hdoc, gsize *out_size)
+{
+ xmlChar *retval = NULL;
+ int size;
+ xmlNodePtr li, a, node;
+
+ node = xmlNewChild (hdoc->sidebar, NULL, "ul", "Misc");
+ li = xmlNewChild (node, NULL, "li", NULL);
+ a = xmlNewChild (li, NULL, "a", _("Help"));
+ xmlSetProp (a, "href", (xmlChar*)"/___help");
+
+ xmlDocDumpFormatMemory (hdoc->doc, &retval, &size, 1);
+ if (out_size)
+ *out_size = (gsize) size;
+
+ return retval;
+}
Added: trunk/tools/html-doc.h
==============================================================================
--- (empty file)
+++ trunk/tools/html-doc.h Wed Dec 10 21:11:52 2008
@@ -0,0 +1,14 @@
+#include <glib.h>
+#include <libxml/tree.h>
+
+typedef struct {
+ xmlDocPtr doc;
+ xmlNodePtr body;
+
+ xmlNodePtr sidebar;
+ xmlNodePtr content;
+} HtmlDoc;
+
+HtmlDoc *html_doc_new (const gchar *title);
+void html_doc_free (HtmlDoc *hdoc);
+xmlChar *html_doc_to_string (HtmlDoc *hdoc, gsize *out_size);
Modified: trunk/tools/tools-input.c
==============================================================================
--- trunk/tools/tools-input.c (original)
+++ trunk/tools/tools-input.c Wed Dec 10 21:11:52 2008
@@ -28,6 +28,7 @@
#ifndef G_OS_WIN32
#include <sys/ioctl.h>
#endif
+#include <libgda/gda-debug-macros.h>
#ifdef HAVE_READLINE
#include <readline/readline.h>
@@ -38,8 +39,10 @@
#define HISTORY_ENV_NAME "GDA_SQL_HISTFILE"
#define HISTORY_FILE ".gdasql_history"
+#ifdef HAVE_HISTORY
static gboolean history_init_done = FALSE;
const gchar *history_file = NULL;
+#endif
/**
* input_from_console
@@ -95,18 +98,99 @@
}
}
+static TreatLineFunc line_cb_func = NULL;
+static gpointer line_cb_func_data = NULL;
+static ComputePromptFunc line_prompt_func = NULL;
+static GIOChannel *ioc = NULL;
+
+static gboolean
+chars_for_readline_cb (GIOChannel *ioc, GIOCondition condition, gpointer data)
+{
+#ifdef HAVE_READLINE
+ rl_callback_read_char ();
+#else
+ gchar *line;
+ gsize tpos;
+ GError *error = NULL;
+ GIOStatus st;
+ st = g_io_channel_read_line (ioc, &line, NULL, &tpos, &error);
+ switch (st) {
+ case G_IO_STATUS_NORMAL:
+ line [tpos] = 0;
+ if (line_cb_func (line, line_cb_func_data) == TRUE) {
+ /* print prompt for next line */
+ g_print ("%s", line_prompt_func ());
+ }
+ g_free (line);
+ break;
+ case G_IO_STATUS_ERROR:
+ g_warning ("Error reading from STDIN: %s\n",
+ error && error->message ? error->message : _("No detail"));
+ if (error)
+ g_error_free (error);
+ break;
+ case G_IO_STATUS_EOF:
+ /* send the Quit command */
+ line_cb_func (".q", line_cb_func_data);
+ return FALSE;
+ break;
+ default:
+ break;
+ }
+#endif
+ return TRUE;
+}
+
+#ifdef HAVE_READLINE
+static void
+line_read_handler (char *line)
+{
+ line_cb_func (line, line_cb_func_data); /* we don't care about the return status */
+ free (line);
+ rl_set_prompt (line_prompt_func ());
+}
+#endif
+
/**
* init_input
*
* Initializes input
*/
void
-init_input ()
+init_input (TreatLineFunc treat_line_func, ComputePromptFunc prompt_func, gpointer data)
{
-#ifdef HAVE_READLINE
+ line_cb_func = treat_line_func;
+ line_cb_func_data = data;
+ line_prompt_func = prompt_func;
+
+#ifdef HAVE_READLINE
rl_set_signals ();
rl_readline_name = "gda-sql";
+ rl_callback_handler_install (prompt_func () , line_read_handler);
+#else
+ g_print ("%s", line_prompt_func ());
+#endif
+ if (!ioc) {
+ ioc = g_io_channel_unix_new (STDIN_FILENO);
+ g_io_add_watch (ioc, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL, (GIOFunc) chars_for_readline_cb, NULL);
+ }
+}
+
+/**
+ * end_input
+ *
+ * Releases any data related to the input and allocated during init_input()
+ */
+void
+end_input (void)
+{
+#ifdef HAVE_READLINE
+ rl_callback_handler_remove ();
#endif
+ if (ioc) {
+ g_io_channel_shutdown (ioc, TRUE, NULL);
+ g_io_channel_unref (ioc);
+ }
}
/**
Modified: trunk/tools/tools-input.h
==============================================================================
--- trunk/tools/tools-input.h (original)
+++ trunk/tools/tools-input.h Wed Dec 10 21:11:52 2008
@@ -25,13 +25,16 @@
#include <stdio.h>
#include <glib.h>
-typedef char **(*CompletionFunc) (const char *, int, int);
+typedef char **(*CompletionFunc) (const char *, int, int);
+typedef gboolean (*TreatLineFunc) (const gchar *, gpointer);
+typedef const char *(*ComputePromptFunc) (void);
gchar *input_from_console (const gchar *prompt);
gchar *input_from_stream (FILE *stream);
-void init_input ();
+void init_input (TreatLineFunc treat_line_func, ComputePromptFunc prompt_func, gpointer data);
void input_get_size (gint *width, gint *height);
+void end_input (void);
void init_history ();
void add_to_history (const gchar *txt);
Added: trunk/tools/web-server.c
==============================================================================
--- (empty file)
+++ trunk/tools/web-server.c Wed Dec 10 21:11:52 2008
@@ -0,0 +1,1681 @@
+
+/* web-server.c
+ *
+ * Copyright (C) 2008 Vivien Malerba
+ *
+ * This Library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This Library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this Library; see the file COPYING.LIB. If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <glib/gi18n-lib.h>
+#include <glib/gstdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include "web-server.h"
+#include <libsoup/soup.h>
+#include "html-doc.h"
+
+/*
+ * Main static functions
+ */
+static void web_server_class_init (WebServerClass * class);
+static void web_server_init (WebServer *server);
+static void web_server_dispose (GObject *object);
+static void web_server_finalize (GObject *object);
+
+/* get a pointer to the parents to be able to call their destructor */
+static GObjectClass *parent_class = NULL;
+
+
+struct _WebServerPrivate
+{
+ SoupServer *server;
+ GHashTable *tmpdata_hash; /* key = a path without the starting '/', value = a TmpData pointer */
+ GSList *tmpdata_list; /* list of the TmpData pointers in @tmpdata_hash, memory not managed here */
+ guint timer;
+};
+
+/*
+ * Temporary available data
+ *
+ * Each TmpData structure represents a ressource which will be available for some time (until it has
+ * expired).
+ *
+ * If the expiration_date attribute is set to 0, then there is no expiration at all.
+ */
+typedef struct {
+ gchar *path;
+ gchar *data;
+ gsize size;
+ int expiration_date; /* 0 to avoid expiration */
+} TmpData;
+
+static gboolean
+delete_tmp_data (WebServer *server)
+{
+ GSList *list;
+ GTimeVal tv;
+ gint n_timed = 0;
+
+ g_get_current_time (&tv);
+ for (list = server->priv->tmpdata_list; list; ) {
+ TmpData *td = (TmpData *) list->data;
+ if ((td->expiration_date > 0) && (td->expiration_date < tv.tv_sec)) {
+ GSList *n = list->next;
+ g_hash_table_remove (server->priv->tmpdata_hash, td->path);
+ server->priv->tmpdata_list = g_slist_delete_link (server->priv->tmpdata_list, list);
+ list = n;
+ }
+ else {
+ if (td->expiration_date > 0)
+ n_timed ++;
+ list = list->next;
+ }
+ }
+ if (n_timed == 0) {
+ server->priv->timer = 0;
+ return FALSE;
+ }
+ else
+ return TRUE;
+}
+
+/*
+ * @data is stolen!
+ */
+static TmpData *
+tmp_data_add (WebServer *server, const gchar *path, gchar *data, gsize data_length)
+{
+ TmpData *td;
+ GTimeVal tv;
+
+ g_get_current_time (&tv);
+ td = g_new0 (TmpData, 1);
+ td->path = g_strdup (path);
+ td->data = data;
+ td->size = data_length;
+ td->expiration_date = tv.tv_sec + 30;
+ g_hash_table_insert (server->priv->tmpdata_hash, g_strdup (path), td);
+ server->priv->tmpdata_list = g_slist_prepend (server->priv->tmpdata_list, td);
+ if (!server->priv->timer)
+ server->priv->timer = g_timeout_add_seconds (5, (GSourceFunc) delete_tmp_data, server);
+ return td;
+}
+
+/*
+ * @data is static
+ */
+static TmpData *
+tmp_static_data_add (WebServer *server, const gchar *path, gchar *data, gsize data_length)
+{
+ TmpData *td;
+
+ td = g_new0 (TmpData, 1);
+ td->path = g_strdup (path);
+ td->data = data;
+ td->size = data_length;
+ td->expiration_date = 0;
+ g_hash_table_insert (server->priv->tmpdata_hash, g_strdup (path), td);
+ server->priv->tmpdata_list = g_slist_prepend (server->priv->tmpdata_list, td);
+ return td;
+}
+
+static void
+tmp_data_free (TmpData *data)
+{
+ g_free (data->data);
+ g_free (data);
+}
+
+#define GDA_CSS \
+"body {" \
+" margin: 0px;" \
+" background-color: white;" \
+" font-family: sans-serif;" \
+" color: black;" \
+"}" \
+"" \
+"a {" \
+" color: #0000ff;" \
+" border: 0px;" \
+"}" \
+"" \
+"a:active {" \
+" color: #ff0000;" \
+"}" \
+"" \
+"a:visited {" \
+" color: #551a8b;" \
+"}" \
+"" \
+"" \
+"#container" \
+"{" \
+" width: 97%;" \
+" margin: 1%;" \
+" background-color: #fff;" \
+" color: #333;" \
+"}" \
+"" \
+"" \
+"" \
+"#top" \
+"{" \
+" background: #729FCF;" \
+" float: left;" \
+" width: 100%;" \
+" font-size: 75%;" \
+"}" \
+"" \
+"#top h1" \
+"{" \
+" margin: 0;" \
+" margin-left: 85px;" \
+" padding-top: 20px;" \
+" padding-bottom: 20px;" \
+" color: #eeeeec;" \
+"}" \
+"" \
+"#top ul {" \
+" list-style: none;" \
+" text-align: right;" \
+" padding: 0 1ex;" \
+" margin: 0;" \
+" font-size: 85%;" \
+"}" \
+"" \
+"#top li a {" \
+" font-weight: bold;" \
+" color: #FFFFFF;" \
+" margin: 0 2ex;" \
+" text-decoration: none;" \
+" line-height: 30px;" \
+"" \
+"}" \
+"" \
+"" \
+"/*" \
+" * Left naivgation pane" \
+" */" \
+"#leftnav" \
+"{" \
+" float: left;" \
+" width: 140px;" \
+" margin: 0;" \
+" padding-top: 5;" \
+"" \
+" background: #2E3436;" \
+" color: #FFFFFF;" \
+"}" \
+"" \
+"#leftnav ul {" \
+" font-weight: bold;" \
+" list-style: none;" \
+" padding: 0 10px 10px;;" \
+" margin: 0 0 0 0;" \
+" font-size: 90%;" \
+"}" \
+"" \
+"#leftnav li a {" \
+" font-weight: normal;" \
+" color: #FFFFFF;" \
+" margin: 0 0 0 0;" \
+" padding: 0 10px;" \
+" text-decoration: none;" \
+" font-size: 80%;" \
+"}" \
+"" \
+"#leftnav p { margin: 0 0 1em 0; }" \
+"" \
+"/* " \
+" * Content" \
+" */" \
+"#content" \
+"{" \
+" /*background: red;*/" \
+" margin-left: 140px;" \
+" padding: 5em 1em;" \
+"}" \
+"" \
+"#content h1" \
+"{ " \
+" /*background: green;*/" \
+" margin: 5em 0 .5em 0 0;" \
+" font-size: 100%;" \
+"}" \
+"" \
+"#content h2" \
+"{ " \
+ " /*background: green;*/" \
+" padding-left: 5;" \
+" font-size: 80%;" \
+"}" \
+"" \
+"#content ul {" \
+" font-weight: bold;" \
+" list-style: none;" \
+" padding: 0 10px 10px;;" \
+" margin: 0 0 0 0;" \
+" font-size: 90%;" \
+"}" \
+"" \
+"#content li {" \
+" font-weight: normal;" \
+" margin: 0 0 0 0;" \
+" padding: 0 10px;" \
+" text-decoration: none;" \
+" font-size: 80%;" \
+"}" \
+"" \
+"div.clist" \
+"{" \
+" /*background: blue;*/" \
+" padding: 0;" \
+" overflow: hidden;" \
+"}" \
+"" \
+".clist ul" \
+"{" \
+" /*background: lightgray;*/" \
+" margin-bottom: 0;" \
+"" \
+" float: left;" \
+" width: 100%;" \
+" margin: 0;" \
+" margin-left: 10px;" \
+" padding: 0;" \
+" list-style: none;" \
+"}" \
+"" \
+".clist li" \
+"{" \
+" /*background: lightblue;*/" \
+" float: left;" \
+" width: 33%;" \
+" margin: 0;" \
+" padding: 0;" \
+" font-size: 90%;" \
+" /*word-wrap: break-word;*/" \
+"}" \
+"" \
+".clist a" \
+"{" \
+" font-weight: normal;" \
+" color: #050505;" \
+" margin: 0 0 0 0;" \
+" padding: 0 0 0 0;" \
+" text-decoration: none;" \
+"}" \
+"" \
+".clist br" \
+"{" \
+" clear: both;" \
+"}" \
+"" \
+"table.ctable" \
+"{" \
+" font-weight: normal;" \
+" font-size: 90%;" \
+" width: 100%;" \
+" background-color: #fafafa;" \
+" border: 1px #6699CC solid;" \
+" border-collapse: collapse;" \
+" border-spacing: 0px;" \
+" margin-top: 0px;" \
+" margin-bottom: 5px;" \
+"}" \
+"" \
+".ctable th" \
+"{" \
+" border-bottom: 2px solid #6699CC;" \
+" background-color: #729FCF;" \
+" text-align: center;" \
+" font-weight: bold;" \
+" color: #eeeeec;" \
+"}" \
+"" \
+".ctable td" \
+"{" \
+" padding-left: 2px;" \
+" border-left: 1px dotted #729FCF;" \
+"}" \
+"" \
+".graph" \
+"{" \
+" /*background: lightblue;*/" \
+" padding: 0;" \
+"}" \
+"" \
+".graph img" \
+"{" \
+" max-width: 100%;" \
+" height: auto;" \
+" border: 0;" \
+"}" \
+"" \
+".pkey" \
+"{" \
+" /*background: lightblue;*/" \
+" color: blue;" \
+" font-weight: bold;" \
+"}" \
+"" \
+".ccode" \
+"{" \
+" /*background: lightblue;*/" \
+" padding-left: 5px;" \
+"}" \
+"" \
+"/*" \
+" * Footer" \
+" */" \
+"#footer" \
+"{" \
+" clear: both;" \
+" margin: 0;" \
+" padding: 2;" \
+" color: #eeeeec;" \
+" background: #729FCF;" \
+"}"
+
+
+/* module error */
+GQuark web_server_error_quark (void)
+{
+ static GQuark quark;
+ if (!quark)
+ quark = g_quark_from_static_string ("web_server_error");
+ return quark;
+}
+
+GType
+web_server_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ static GStaticMutex registering = G_STATIC_MUTEX_INIT;
+ static const GTypeInfo info = {
+ sizeof (WebServerClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) web_server_class_init,
+ NULL,
+ NULL,
+ sizeof (WebServer),
+ 0,
+ (GInstanceInitFunc) web_server_init
+ };
+
+ g_static_mutex_lock (®istering);
+ if (type == 0)
+ type = g_type_register_static (G_TYPE_OBJECT, "WebServer", &info, 0);
+ g_static_mutex_unlock (®istering);
+ }
+
+ return type;
+}
+
+static void
+web_server_class_init (WebServerClass *class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+
+ parent_class = g_type_class_peek_parent (class);
+
+
+ /* virtual functions */
+ object_class->dispose = web_server_dispose;
+ object_class->finalize = web_server_finalize;
+}
+
+static void
+web_server_init (WebServer *server)
+{
+ server->priv = g_new0 (WebServerPrivate, 1);
+ server->priv->timer = 0;
+ server->priv->tmpdata_hash = g_hash_table_new_full (g_str_hash, g_str_equal,
+ g_free, (GDestroyNotify) tmp_data_free);
+ server->priv->tmpdata_list = NULL;
+
+ tmp_static_data_add (server, "gda.css", GDA_CSS, strlen (GDA_CSS));
+}
+
+
+static gboolean get_file (SoupServer *server, SoupMessage *msg, const char *path, GError **error);
+static void get_root (SoupServer *server, SoupMessage *msg);
+static gboolean get_for_cnc (WebServer *webserver, SoupMessage *msg,
+ const ConnectionSetting *cs, gchar **extra, GError **error);
+
+
+static void
+server_callback (SoupServer *server, SoupMessage *msg,
+ const char *path, GHashTable *query,
+ SoupClientContext *context, WebServer *webserver)
+{
+ /*#define DEBUG_SERVER*/
+#ifdef DEBUG_SERVER
+ printf ("%s %s HTTP/1.%d\n", msg->method, path, soup_message_get_http_version (msg));
+ SoupMessageHeadersIter iter;
+ const char *name, *value;
+ soup_message_headers_iter_init (&iter, msg->request_headers);
+ while (soup_message_headers_iter_next (&iter, &name, &value))
+ printf ("%s: %s\n", name, value);
+ if (msg->request_body->length)
+ printf ("Request body: %s\n", msg->request_body->data);
+#endif
+
+ if (msg->method == SOUP_METHOD_GET) {
+ GError *error = NULL;
+ gboolean ok = TRUE;
+ TmpData *tmpdata;
+ if (*path != '/') {
+ soup_message_set_status_full (msg, SOUP_STATUS_UNAUTHORIZED, "Wrong path name");
+ return;
+ }
+ path++;
+
+ if (*path == 0)
+ get_root (server, msg);
+ else if ((tmpdata = g_hash_table_lookup (webserver->priv->tmpdata_hash, path))) {
+ soup_message_body_append (msg->response_body, SOUP_MEMORY_STATIC,
+ tmpdata->data, tmpdata->size);
+ soup_message_set_status (msg, SOUP_STATUS_OK);
+ }
+ else {
+ gchar **array = NULL;
+ array = g_strsplit (path, "/", 0);
+
+ const ConnectionSetting *cs;
+ cs = gda_sql_get_connection (array[0]);
+
+ if (cs)
+ ok = get_for_cnc (webserver, msg, cs, array[1] ? &(array[1]) : NULL, &error);
+ else {
+ /*ok = get_file (webserver, msg, path, &error);*/
+ ok = FALSE;
+ }
+ if (array)
+ g_strfreev (array);
+ }
+
+ if (!ok) {
+ if (error) {
+ soup_message_set_status_full (msg, error->code, error->message);
+ g_error_free (error);
+ }
+ else
+ soup_message_set_status (msg, SOUP_STATUS_INTERNAL_SERVER_ERROR);
+ }
+ }
+ else
+ soup_message_set_status (msg, SOUP_STATUS_NOT_IMPLEMENTED);
+#ifdef DEBUG_SERVER
+ printf (" -> %d %s\n\n", msg->status_code, msg->reason_phrase);
+#endif
+}
+
+/**
+ * web_server_new
+ * @type: the #GType requested
+ *
+ * Creates a new server of type @type
+ *
+ * Returns: a new #WebServer object
+ */
+WebServer *
+web_server_new (gint port)
+{
+ WebServer *server;
+
+ server = (WebServer*) g_object_new (WEB_TYPE_SERVER, NULL);
+ server->priv->server = soup_server_new (SOUP_SERVER_PORT, port,
+ SOUP_SERVER_SERVER_HEADER, "gda-sql-httpd ",
+ NULL);
+ soup_server_add_handler (server->priv->server, NULL,
+ (SoupServerCallback) server_callback, server, NULL);
+
+ soup_server_run_async (server->priv->server);
+
+ return server;
+}
+
+
+static void
+web_server_dispose (GObject *object)
+{
+ WebServer *server;
+
+ server = WEB_SERVER (object);
+ if (server->priv) {
+ if (server->priv->tmpdata_hash) {
+ g_hash_table_destroy (server->priv->tmpdata_hash);
+ server->priv->tmpdata_hash = NULL;
+ }
+ if (server->priv->tmpdata_list) {
+ g_slist_free (server->priv->tmpdata_list);
+ server->priv->tmpdata_list = NULL;
+ }
+ if (server->priv->server) {
+ g_object_unref (server->priv->server);
+ server->priv->server = NULL;
+ }
+ if (server->priv->timer) {
+ g_source_remove (server->priv->timer);
+ server->priv->timer = 0;
+ }
+ }
+
+ /* parent class */
+ parent_class->dispose (object);
+}
+
+static void
+web_server_finalize (GObject * object)
+{
+ WebServer *server;
+
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (WEB_IS_SERVER (object));
+
+ server = WEB_SERVER (object);
+ if (server->priv) {
+ g_free (server->priv);
+ }
+
+ /* parent class */
+ parent_class->finalize (object);
+}
+
+/*
+ * GET for a file
+ */
+static gboolean
+get_file (SoupServer *server, SoupMessage *msg, const char *path, GError **error)
+{
+ GMappedFile *mfile;
+ mfile = g_mapped_file_new (path, FALSE, error);
+ if (!mfile)
+ return FALSE;
+
+ SoupBuffer *buffer;
+ buffer = soup_buffer_new_with_owner (g_mapped_file_get_contents (mfile),
+ g_mapped_file_get_length (mfile),
+ mfile, (GDestroyNotify) g_mapped_file_free);
+ soup_message_body_append_buffer (msg->response_body, buffer);
+ soup_buffer_free (buffer);
+ soup_message_set_status (msg, SOUP_STATUS_OK);
+ return TRUE;
+}
+
+/*
+ * GET for the / path
+ */
+static void
+get_root (SoupServer *server, SoupMessage *msg)
+{
+ HtmlDoc *hdoc;
+ xmlChar *xstr;
+ SoupBuffer *buffer;
+ gsize size;
+
+ const GSList *list;
+ list = gda_sql_get_all_connections ();
+ if (0 && list && !list->next) {
+ /* only 1 connection => go to this one */
+ ConnectionSetting *cs = (ConnectionSetting*) list->data;
+ soup_message_set_status (msg, SOUP_STATUS_TEMPORARY_REDIRECT);
+ soup_message_headers_append (msg->response_headers, "Location", cs->name);
+ return;
+ }
+ hdoc = html_doc_new (_("Database information"));
+ if (!list) {
+ /* no connection at all */
+ xmlNodePtr node;
+
+ node = xmlNewChild (hdoc->content, NULL, "h1", _("No connection opened."));
+ node = xmlNewChild (hdoc->content, NULL, "p", _("Open a connection from the console and reload this page"));
+ }
+ else {
+ /* more than one connection, redirect to the current one */
+ const ConnectionSetting *cs = gda_sql_get_current_connection ();
+ soup_message_set_status (msg, SOUP_STATUS_TEMPORARY_REDIRECT);
+ soup_message_headers_append (msg->response_headers, "Location", cs->name);
+ return;
+ }
+
+ soup_message_headers_replace (msg->response_headers,
+ "Content-Type", "text/html");
+ xstr = html_doc_to_string (hdoc, &size);
+ buffer = soup_buffer_new_with_owner (xstr, size, xstr, (GDestroyNotify)xmlFree);
+ soup_message_body_append_buffer (msg->response_body, buffer);
+ soup_buffer_free (buffer);
+ html_doc_free (hdoc);
+
+ soup_message_set_status (msg, SOUP_STATUS_OK);
+}
+
+static gboolean compute_all_objects_content (HtmlDoc *hdoc, const ConnectionSetting *cs,
+ const gchar *human_obj_type,
+ const gchar *human_obj_type_in_schema,
+ const gchar *table_name,
+ const gchar *obj_prefix,
+ const gchar *filter,
+ GError **error);
+static gboolean compute_all_triggers_content (HtmlDoc *hdoc, const ConnectionSetting *cs, GError **error);
+static gboolean compute_object_content (HtmlDoc *hdoc, WebServer *webserver, const ConnectionSetting *cs,
+ const gchar *schema, const gchar *name, GError **error);
+/*
+ * GET method for a connection
+ */
+static gboolean
+get_for_cnc (WebServer *webserver, SoupMessage *msg, const ConnectionSetting *cs, gchar **extra, GError **error)
+{
+ gboolean retval = FALSE;
+ HtmlDoc *hdoc;
+ xmlChar *xstr;
+ SoupBuffer *buffer;
+ gsize size;
+ gchar *str;
+
+ gchar *rfc_cnc_name;
+
+ xmlNodePtr ul, li, a;
+
+ const GSList *clist;
+
+
+ str = g_strdup_printf (_("Database information for '%s'"), cs->name);
+ hdoc = html_doc_new (str);
+ g_free (str);
+
+ /* other connections in the sidebar */
+ ul = xmlNewChild (hdoc->sidebar, NULL, "ul", _("Connections"));
+ li = xmlNewChild (ul, NULL, "li", NULL);
+ str = g_strdup_printf ("(%s)", _("From console"));
+ a = xmlNewChild (li, NULL, "a", str);
+ g_free (str);
+ xmlSetProp (a, "href", (xmlChar*) "/");
+
+ for (clist = gda_sql_get_all_connections (); clist; clist = clist->next) {
+ gchar *tmp;
+ ConnectionSetting *cs = (ConnectionSetting*) clist->data;
+
+ li = xmlNewChild (ul, NULL, "li", NULL);
+ a = xmlNewChild (li, NULL, "a", cs->name);
+ tmp = gda_rfc1738_encode (cs->name);
+ str = g_strdup_printf ("/%s", tmp);
+ g_free (tmp);
+ xmlSetProp (a, "href", (xmlChar*) str);
+ g_free (str);
+ }
+
+ /* list all database object's types for which information can be obtained */
+ rfc_cnc_name = gda_rfc1738_encode (cs->name);
+ ul = xmlNewChild (hdoc->sidebar, NULL, "ul", _("Objects"));
+ li = xmlNewChild (ul, NULL, "li", NULL);
+ a = xmlNewChild (li, NULL, "a", _("Tables"));
+ str = g_strdup_printf ("/%s/___tables", rfc_cnc_name);
+ xmlSetProp (a, "href", (xmlChar*) str);
+ g_free (str);
+ li = xmlNewChild (ul, NULL, "li", NULL);
+ a = xmlNewChild (li, NULL, "a", _("Views"));
+ str = g_strdup_printf ("/%s/___views", rfc_cnc_name);
+ xmlSetProp (a, "href", (xmlChar*) str);
+ g_free (str);
+ li = xmlNewChild (ul, NULL, "li", NULL);
+ a = xmlNewChild (li, NULL, "a", _("Triggers"));
+ str = g_strdup_printf ("/%s/___triggers", rfc_cnc_name);
+ xmlSetProp (a, "href", (xmlChar*) str);
+ g_free (str);
+ g_free (rfc_cnc_name);
+
+#ifdef GDA_DEBUG_NO
+ if (extra) {
+ gint i;
+ for (i = 0; extra[i]; i++)
+ g_print ("EXTRA %d: #%s#\n", i, extra[i]);
+ }
+#endif
+ if (!extra || !strcmp (extra[0], "___tables")) {
+ if (! compute_all_objects_content (hdoc, cs,
+ _("Tables"), _("Tables in the '%s' schema"),
+ "_tables", "table", "table_type LIKE \"%TABLE%\"", error))
+ goto onerror;
+ }
+ else if (!strcmp (extra[0], "___views")) {
+ if (! compute_all_objects_content (hdoc, cs,
+ _("Views"), _("Views in the '%s' schema"),
+ "_tables", "table", "table_type LIKE \"%VIEW%\"", error))
+ goto onerror;
+ }
+ else if (!strcmp (extra[0], "___triggers")) {
+ if (! compute_all_triggers_content (hdoc, cs, error))
+ goto onerror;
+ }
+ else {
+ /* extra [0] has to be a schema */
+ if (extra [1]) {
+ if (! compute_object_content (hdoc, webserver, cs, extra [0], extra [1], error))
+ goto onerror;
+ }
+ else
+ xmlNewChild (hdoc->content, NULL, "h1", "Not yet implemented");
+ }
+
+ soup_message_headers_replace (msg->response_headers,
+ "Content-Type", "text/html");
+ xstr = html_doc_to_string (hdoc, &size);
+ buffer = soup_buffer_new_with_owner (xstr, size, xstr, (GDestroyNotify)xmlFree);
+ soup_message_body_append_buffer (msg->response_body, buffer);
+ soup_buffer_free (buffer);
+ soup_message_set_status (msg, SOUP_STATUS_OK);
+ retval = TRUE;
+
+ onerror:
+ html_doc_free (hdoc);
+ return retval;
+}
+
+static void
+meta_table_column_foreach_attribute_func (const gchar *att_name, const GValue *value, GString **string)
+{
+ if (!strcmp (att_name, GDA_ATTRIBUTE_AUTO_INCREMENT) &&
+ (G_VALUE_TYPE (value) == G_TYPE_BOOLEAN) &&
+ g_value_get_boolean (value)) {
+ if (*string) {
+ g_string_append (*string, ", ");
+ g_string_append (*string, _("Auto increment"));
+ }
+ else
+ *string = g_string_new (_("Auto increment"));
+ }
+}
+
+static gchar *meta_struct_dump_as_graph (const ConnectionSetting *cs, GdaMetaStruct *mstruct,
+ GdaMetaDbObject *central_dbo, GError **error);
+static gboolean
+compute_table_details (const ConnectionSetting *cs, HtmlDoc *hdoc, WebServer *webserver,
+ GdaMetaStruct *mstruct, GdaMetaDbObject *dbo, GError **error)
+{
+ gchar *tmp;
+ xmlNodePtr div, table, tr, td;
+ GdaMetaTable *mt = GDA_META_TABLE (dbo);
+ GSList *list;
+ GdaMetaStore *store;
+
+ tmp = g_strdup_printf (_("Columns for the '%s' table:"), dbo->obj_short_name);
+ xmlNewChild (hdoc->content, NULL, "h1", tmp);
+ g_free (tmp);
+
+ div = xmlNewChild (hdoc->content, NULL, "div", NULL);
+ table = xmlNewChild (div, NULL, "table", NULL);
+ xmlSetProp (table, "class", (xmlChar*) "ctable");
+ tr = xmlNewChild (table, NULL, "tr", NULL);
+ td = xmlNewChild (tr, NULL, "th", _("Column"));
+ td = xmlNewChild (tr, NULL, "th", _("Type"));
+ td = xmlNewChild (tr, NULL, "th", _("Nullable"));
+ td = xmlNewChild (tr, NULL, "th", _("Default"));
+ td = xmlNewChild (tr, NULL, "th", _("Extra"));
+
+ for (list = mt->columns; list; list = list->next) {
+ GdaMetaTableColumn *tcol = GDA_META_TABLE_COLUMN (list->data);
+ GString *string = NULL;
+
+ tr = xmlNewChild (table, NULL, "tr", NULL);
+ td = xmlNewChild (tr, NULL, "td", tcol->column_name);
+ if (tcol->pkey)
+ xmlSetProp (td, "class", "pkey");
+ td = xmlNewChild (tr, NULL, "td", tcol->column_type);
+ td = xmlNewChild (tr, NULL, "td", tcol->nullok ? _("yes") : _("no"));
+ td = xmlNewChild (tr, NULL, "td", tcol->default_value);
+
+ gda_meta_table_column_foreach_attribute (tcol,
+ (GdaAttributesManagerFunc) meta_table_column_foreach_attribute_func, &string);
+ if (string) {
+ td = xmlNewChild (tr, NULL, "td", string->str);
+ g_string_free (string, TRUE);
+ }
+ else
+ td = xmlNewChild (tr, NULL, "td", NULL);
+ }
+
+ /* finished if we don't have a table */
+ if (dbo->obj_type != GDA_META_DB_TABLE)
+ return TRUE;
+
+ /* show primary key */
+ GdaMetaTable *dbo_table = GDA_META_TABLE (dbo);
+#ifdef NONO
+ if (dbo_table->pk_cols_nb > 0) {
+ gint ipk;
+ xmlNodePtr ul = NULL;
+ xmlNewChild (hdoc->content, NULL, "h1", _("Primary key:"));
+ div = xmlNewChild (hdoc->content, NULL, "div", NULL);
+ for (ipk = 0; ipk < dbo_table->pk_cols_nb; ipk++) {
+ GdaMetaTableColumn *tcol;
+ if (!ul)
+ ul = xmlNewChild (div, NULL, "ul", NULL);
+
+ tcol = g_slist_nth_data (dbo_table->columns, ipk);
+ xmlNewChild (ul, NULL, "li", tcol->column_name);
+ }
+ }
+#endif
+
+ /* Add objects depending on this table */
+ if (!gda_meta_struct_complement_depend (mstruct, dbo, error))
+ return FALSE;
+
+ /* Add tables from which this one depends */
+ GValue *v0, *v1;
+ GdaDataModel *model;
+ g_object_get (G_OBJECT (mstruct), "meta-store", &store, NULL);
+ g_value_set_string ((v0 = gda_value_new (G_TYPE_STRING)), dbo->obj_schema);
+ g_value_set_string ((v1 = gda_value_new (G_TYPE_STRING)), dbo->obj_name);
+ model = gda_meta_store_extract (store, "SELECT table_catalog, table_schema, table_name FROM "
+ "_referential_constraints WHERE "
+ "ref_table_schema = ##tschema::string AND ref_table_name = ##tname::string",
+ error, "tschema", v0, "tname", v1, NULL);
+ gda_value_free (v0);
+ gda_value_free (v1);
+ g_object_unref (store);
+ if (model) {
+ gint i, nrows;
+ nrows = gda_data_model_get_n_rows (model);
+ for (i = 0; i < nrows; i++) {
+ const GValue *cv0, *cv1 = NULL, *cv2 = NULL;
+ cv0 = gda_data_model_get_value_at (model, 0, i, NULL);
+ if (cv0) {
+ cv1 = gda_data_model_get_value_at (model, 1, i, NULL);
+ if (cv1)
+ cv2 = gda_data_model_get_value_at (model, 2, i, NULL);
+ }
+ if (cv0 && cv1 && cv2)
+ gda_meta_struct_complement (mstruct, GDA_META_DB_TABLE, cv0, cv1, cv2, NULL);
+ }
+ g_object_unref (model);
+ }
+
+ /* create a graph */
+ gchar *graph, *tmp_filename = NULL;
+ xmlNodePtr map_node = NULL;
+ graph = meta_struct_dump_as_graph (cs, mstruct, dbo, NULL);
+ if (graph) {
+ gchar *dotname, *suffix;
+ static gint counter = 0;
+
+ suffix = g_strdup_printf (".gda_graph_tmp-%d.dot", ++counter);
+ dotname = g_build_filename (g_get_tmp_dir (), suffix, NULL);
+ g_free (suffix);
+
+ if (g_file_set_contents (dotname, graph, -1, error)) {
+ gchar *pngname, *mapname;
+ gchar *argv[] = {"dot", "-Tpng", "-o", NULL, "-Tcmapx", "-o", NULL, NULL, NULL};
+
+ suffix = g_strdup_printf (".gda_graph_tmp-%d", counter);
+ pngname = g_build_filename (g_get_tmp_dir (), suffix, NULL);
+ g_free (suffix);
+
+ suffix = g_strdup_printf (".gda_graph_tmp-%d.map", counter);
+ mapname = g_build_filename (g_get_tmp_dir (), suffix, NULL);
+ g_free (suffix);
+
+ argv[3] = pngname;
+ argv[6] = mapname;
+ argv[7] = dotname;
+ if (g_spawn_sync (NULL, argv, NULL,
+ G_SPAWN_SEARCH_PATH | G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL,
+ NULL, NULL,
+ NULL, NULL, NULL, NULL)) {
+ xmlDocPtr map;
+ map = xmlParseFile (mapname);
+ if (map) {
+ map_node = xmlDocGetRootElement (map);
+ xmlUnlinkNode (map_node);
+ xmlFreeDoc (map);
+ }
+
+ gchar *file_data;
+ gsize file_data_len;
+ if (g_file_get_contents (pngname, &file_data, &file_data_len, NULL)) {
+ tmp_filename = g_strdup_printf ("___tmp/g%d", counter);
+ tmp_data_add (webserver, tmp_filename, file_data, file_data_len);
+ }
+ }
+ g_unlink(pngname);
+ g_free (pngname);
+ g_unlink(mapname);
+ g_free (mapname);
+ }
+ g_unlink(dotname);
+ g_free (dotname);
+ g_free (graph);
+ }
+ if (tmp_filename) {
+ xmlNodePtr obj;
+ gchar *tmp;
+ xmlNewChild (hdoc->content, NULL, "h1", _("Relations:"));
+ div = xmlNewChild (hdoc->content, NULL, "div", NULL);
+
+ if (map_node)
+ xmlAddChild (div, map_node);
+
+ xmlSetProp (div, "class", (xmlChar*) "graph");
+ obj = xmlNewChild (div, NULL, "img", NULL);
+ tmp = g_strdup_printf ("/%s", tmp_filename);
+ xmlSetProp (obj, "src", (xmlChar*) tmp);
+ xmlSetProp (obj, "usemap", (xmlChar*) "#G");
+ g_free (tmp);
+ g_free (tmp_filename);
+ }
+ else {
+ /* list foreign keys as we don't have a graph */
+ if (dbo_table->fk_list) {
+ xmlNewChild (hdoc->content, NULL, "h1", _("Foreign keys:"));
+ GSList *list;
+ for (list = dbo_table->fk_list; list; list = list->next) {
+ GdaMetaTableForeignKey *tfk = GDA_META_TABLE_FOREIGN_KEY (list->data);
+ GdaMetaDbObject *fkdbo = tfk->depend_on;
+ xmlNodePtr ul = NULL;
+ gint ifk;
+
+ div = xmlNewChild (hdoc->content, NULL, "div", NULL);
+ for (ifk = 0; ifk < tfk->cols_nb; ifk++) {
+ gchar *tmp;
+ if (!ul) {
+ tmp = g_strdup_printf (_("To '%s':"), fkdbo->obj_short_name);
+ ul = xmlNewChild (div, NULL, "ul", tmp);
+ g_free (tmp);
+ }
+ tmp = g_strdup_printf ("%s --> %s.%s",
+ tfk->fk_names_array[ifk],
+ fkdbo->obj_short_name, tfk->ref_pk_names_array[ifk]);
+ xmlNewChild (ul, NULL, "li", tmp);
+ g_free (tmp);
+ }
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+/*
+ * Creates a new graph (in the GraphViz syntax) representation of @mstruct.
+ *
+ * Returns: a new string, or %NULL if an error occurred.
+ */
+static gchar *
+meta_struct_dump_as_graph (const ConnectionSetting *cs, GdaMetaStruct *mstruct, GdaMetaDbObject *central_dbo,
+ GError **error)
+{
+ GString *string;
+ gchar *result;
+ gchar *rfc_cnc_name;
+
+ g_return_val_if_fail (GDA_IS_META_STRUCT (mstruct), NULL);
+
+ rfc_cnc_name = gda_rfc1738_encode (cs->name);
+
+ string = g_string_new ("digraph G {\nrankdir = LR;\ndpi = 70;\nfontname = Helvetica;\nnode [shape = plaintext];\n");
+ GSList *dbo_list, *list;
+ dbo_list = gda_meta_struct_get_all_db_objects (mstruct);
+ for (list = dbo_list; list; list = list->next) {
+ gchar *objname, *fullname;
+ GdaMetaDbObject *dbo = GDA_META_DB_OBJECT (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 if (dbo->obj_schema)
+ objname = g_strdup_printf ("%s.%s", dbo->obj_schema, dbo->obj_name);
+ else
+ objname = g_strdup (dbo->obj_name);
+
+ /* URL */
+ gchar *e0, *e1, *url;
+ e0 = gda_rfc1738_encode (dbo->obj_schema);
+ e1 = gda_rfc1738_encode (dbo->obj_name);
+ url = g_strdup_printf ("/%s/%s/%s", rfc_cnc_name, e0, e1);
+ g_free (e0);
+ g_free (e1);
+
+ /* node */
+ switch (dbo->obj_type) {
+ case GDA_META_DB_UNKNOWN:
+ break;
+ case GDA_META_DB_TABLE:
+ g_string_append_printf (string, "\"%s\" [URL=\"%s\", tooltip=\"%s\", label=<<TABLE BORDER=\"1\" CELLBORDER=\"0\" CELLSPACING=\"0\">", fullname, url, objname);
+ if (dbo == central_dbo)
+ g_string_append_printf (string, "<TR><TD COLSPAN=\"2\" BGCOLOR=\"#729FCF;\" BORDER=\"3\">%s</TD></TR>", objname);
+ else
+ g_string_append_printf (string, "<TR><TD COLSPAN=\"2\" BGCOLOR=\"lightgrey\" BORDER=\"1\">%s</TD></TR>", objname);
+ break;
+ case GDA_META_DB_VIEW:
+ g_string_append_printf (string, "\"%s\" [URL=\"%s\", tooltip=\"%s\", label=<<TABLE BORDER=\"1\" CELLBORDER=\"0\" CELLSPACING=\"0\">", fullname, url, objname);
+ 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 label = \"%s\" ];", fullname, objname);
+ break;
+ }
+ g_free (url);
+
+ /* columns, only for tables */
+ if (dbo->obj_type == GDA_META_DB_TABLE) {
+ GdaMetaTable *mt = GDA_META_TABLE (dbo);
+ GSList *depend_dbo_list = NULL;
+ for (list = mt->columns; list; list = list->next) {
+ GdaMetaTableColumn *tcol = GDA_META_TABLE_COLUMN (list->data);
+ if (tcol->pkey)
+ g_string_append_printf (string, "<TR><TD ALIGN=\"left\"><FONT COLOR=\"blue\">%s</FONT></TD></TR>",
+ tcol->column_name);
+ else
+ g_string_append_printf (string, "<TR><TD ALIGN=\"left\">%s</TD></TR>",
+ tcol->column_name);
+ }
+ 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);
+ GString *st = NULL;
+ gint fki;
+ for (fki = 0; fki < tfk->cols_nb; fki++) {
+ if (tfk->fk_names_array && tfk->ref_pk_names_array) {
+ if (!st)
+ st = g_string_new ("");
+ else
+ g_string_append (st, "\\n");
+ g_string_append_printf (st, "%s = %s",
+ tfk->fk_names_array [fki],
+ tfk->ref_pk_names_array [fki]);
+ }
+ else
+ break;
+ }
+ if (tfk->depend_on->obj_type != GDA_META_DB_UNKNOWN) {
+ g_string_append_printf (string, "\"%s\" -> \"%s.%s.%s\" [fontsize=12, label=\"%s\"];\n",
+ fullname,
+ tfk->depend_on->obj_catalog, tfk->depend_on->obj_schema,
+ tfk->depend_on->obj_name,
+ st ? st->str : "");
+ depend_dbo_list = g_slist_prepend (depend_dbo_list, tfk->depend_on);
+ }
+ if (st)
+ g_string_free (st, TRUE);
+ }
+
+ /* 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_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");
+ /* 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, '}');
+ g_slist_free (dbo_list);
+
+ result = string->str;
+ g_string_free (string, FALSE);
+ return result;
+}
+
+static gboolean
+compute_view_details (const ConnectionSetting *cs, HtmlDoc *hdoc, GdaMetaStruct *mstruct,
+ GdaMetaDbObject *dbo, GError **error)
+{
+ GdaMetaView *view = GDA_META_VIEW (dbo);
+ if (view->view_def) {
+ xmlNodePtr div, code;
+ xmlNewChild (hdoc->content, NULL, "h1", _("View definition:"));
+ div = xmlNewChild (hdoc->content, NULL, "div", NULL);
+ code = xmlNewChild (div, NULL, "code", view->view_def);
+ xmlSetProp (code, "class", (xmlChar*) "ccode");
+ }
+ return TRUE;
+}
+
+/*
+ * compute information for an object assuming it's a trigger
+ *
+ * Returns: TRUE if the object was really a trigger
+ */
+static gboolean
+compute_trigger_content (HtmlDoc *hdoc, WebServer *webserver, const ConnectionSetting *cs,
+ const gchar *schema, const gchar *name, GError **error)
+{
+ GdaMetaStore *store;
+ GdaDataModel *model;
+ GValue *v0, *v1;
+ GValue *tschema = NULL, *tname = NULL;
+ gint i, nrows;
+ xmlNodePtr code, div = NULL, sdiv, ul, li;
+
+ store = gda_connection_get_meta_store (cs->cnc);
+ g_value_set_string ((v0 = gda_value_new (G_TYPE_STRING)), schema);
+ g_value_set_string ((v1 = gda_value_new (G_TYPE_STRING)), name);
+ model = gda_meta_store_extract (store, "SELECT trigger_short_name, action_statement, event_manipulation, "
+ "event_object_schema, event_object_table, trigger_comments, "
+ "action_orientation, condition_timing FROM _triggers "
+ "WHERE trigger_schema = ##tschema::string AND trigger_name = ##tname::string "
+ "ORDER BY event_object_schema, event_object_table, event_manipulation",
+ error, "tschema", v0, "tname", v1, NULL);
+ gda_value_free (v0);
+ gda_value_free (v1);
+ if (!model)
+ return FALSE;
+ nrows = gda_data_model_get_n_rows (model);
+ if (nrows == 0) {
+ g_object_unref (model);
+ return FALSE;
+ }
+
+ for (i = 0; i < nrows; i++) {
+ const GValue *cv0, *cv1, *cv2, *cv3, *cv4, *cv5, *cv6, *cv7;
+ gchar *tmp;
+
+ if (! (cv0 = gda_data_model_get_value_at (model, 0, i, error)))
+ break;
+ if (! (cv1 = gda_data_model_get_value_at (model, 1, i, error)))
+ break;
+ if (! (cv2 = gda_data_model_get_value_at (model, 2, i, error)))
+ break;
+ if (! (cv3 = gda_data_model_get_value_at (model, 3, i, error)))
+ break;
+ if (! (cv4 = gda_data_model_get_value_at (model, 4, i, error)))
+ break;
+ if (! (cv5 = gda_data_model_get_value_at (model, 5, i, error)))
+ break;
+ if (! (cv6 = gda_data_model_get_value_at (model, 6, i, error)))
+ break;
+ if (! (cv7 = gda_data_model_get_value_at (model, 7, i, error)))
+ break;
+
+ if ((!tschema || gda_value_differ (tschema, cv3)) ||
+ (!tname || gda_value_differ (tname, cv4))) {
+ if (tschema)
+ xmlNewChild (div, NULL, "br", NULL);
+ if (tschema)
+ gda_value_free (tschema);
+ if (tname)
+ gda_value_free (tname);
+ tschema = gda_value_copy (cv3);
+ tname = gda_value_copy (cv4);
+
+ tmp = g_strdup_printf (_("Trigger '%s' for the '%s.%s' table:"),
+ g_value_get_string (cv0),
+ g_value_get_string (tschema),
+ g_value_get_string (tname));
+ xmlNewChild (hdoc->content, NULL, "h1", tmp);
+ g_free (tmp);
+
+ div = xmlNewChild (hdoc->content, NULL, "div", NULL);
+ }
+
+ if (G_VALUE_TYPE (cv5) != GDA_TYPE_NULL)
+ tmp = g_strdup_printf ("On %s (%s):", g_value_get_string (cv2), g_value_get_string (cv5));
+ else
+ tmp = g_strdup_printf ("On %s:", g_value_get_string (cv2));
+ xmlNewChild (div, NULL, "h2", tmp);
+ g_free (tmp);
+
+ sdiv = xmlNewChild (div, NULL, "div", NULL);
+ ul = xmlNewChild (sdiv, NULL, "ul", NULL);
+
+ tmp = g_strdup_printf (_("Trigger fired for: %s"), g_value_get_string (cv6));
+ li = xmlNewChild (ul, NULL, "li", tmp);
+ g_free (tmp);
+
+ tmp = g_strdup_printf (_("Time at which the trigger is fired: %s"), g_value_get_string (cv7));
+ li = xmlNewChild (ul, NULL, "li", tmp);
+ g_free (tmp);
+
+ li = xmlNewChild (ul, NULL, "li", _("Action:"));
+ code = xmlNewChild (li, NULL, "code", g_value_get_string (cv1));
+ xmlSetProp (code, "class", (xmlChar*) "ccode");
+ }
+
+
+ g_object_unref (model);
+ return TRUE;
+}
+
+/*
+ * Give details about a database object
+ */
+static gboolean
+compute_object_content (HtmlDoc *hdoc, WebServer *webserver, const ConnectionSetting *cs,
+ const gchar *schema, const gchar *name, GError **error)
+{
+ GdaMetaStruct *mstruct;
+ GdaMetaDbObject *dbo;
+ GValue *v0, *v1;
+ gboolean retval;
+
+ if (gda_sql_identifier_needs_quotes (schema))
+ g_value_take_string ((v0 = gda_value_new (G_TYPE_STRING)),
+ gda_sql_identifier_add_quotes (schema));
+ else
+ g_value_set_string ((v0 = gda_value_new (G_TYPE_STRING)), schema);
+ if (gda_sql_identifier_needs_quotes (name))
+ g_value_take_string ((v1 = gda_value_new (G_TYPE_STRING)),
+ gda_sql_identifier_add_quotes (name));
+ else
+ g_value_set_string ((v1 = gda_value_new (G_TYPE_STRING)), name);
+
+ mstruct = gda_meta_struct_new (gda_connection_get_meta_store (cs->cnc),
+ GDA_META_STRUCT_FEATURE_ALL);
+ dbo = gda_meta_struct_complement (mstruct, GDA_META_DB_UNKNOWN, NULL, v0, v1, error);
+ gda_value_free (v0);
+ gda_value_free (v1);
+ if (!dbo) {
+ if (compute_trigger_content (hdoc, webserver, cs, schema, name, error))
+ return TRUE;
+ TO_IMPLEMENT;
+ return FALSE;
+ }
+
+ switch (dbo->obj_type) {
+ case GDA_META_DB_TABLE:
+ retval = compute_table_details (cs, hdoc, webserver, mstruct, dbo, error);
+ break;
+ case GDA_META_DB_VIEW:
+ retval = compute_table_details (cs, hdoc, webserver, mstruct, dbo, error);
+ if (retval)
+ retval = compute_view_details (cs, hdoc, mstruct, dbo, error);
+ break;
+ default:
+ TO_IMPLEMENT;
+ }
+ g_object_unref (mstruct);
+ return TRUE;
+}
+
+
+/*
+ * Lists all objects of a type (tables, view, ...)
+ */
+static gboolean
+compute_all_objects_content (HtmlDoc *hdoc, const ConnectionSetting *cs,
+ const gchar *human_obj_type,
+ const gchar *human_obj_type_in_schema,
+ const gchar *table_name,
+ const gchar *obj_prefix,
+ const gchar *filter,
+ GError **error)
+{
+ gboolean retval = FALSE;
+ gchar *rfc_cnc_name;
+ GdaMetaStore *store;
+ GdaDataModel *model;
+ gint i, nrows;
+ gchar *sql;
+ GValue *schema = NULL;
+ xmlNodePtr ul, li, a, div = NULL;
+ gboolean content_added = FALSE;
+
+ rfc_cnc_name = gda_rfc1738_encode (cs->name);
+
+ store = gda_connection_get_meta_store (cs->cnc);
+
+ /* objects directly accessible */
+ if (filter)
+ sql = g_strdup_printf ("SELECT %s_schema, %s_name FROM %s WHERE %s "
+ "AND %s_short_name != %s_full_name ORDER BY %s_schema, %s_name",
+ obj_prefix, obj_prefix, table_name, filter, obj_prefix, obj_prefix,
+ obj_prefix, obj_prefix);
+ else
+ sql = g_strdup_printf ("SELECT %s_schema, %s_name FROM %s WHERE "
+ "%s_short_name != %s_full_name ORDER BY %s_schema, %s_name",
+ obj_prefix, obj_prefix, table_name, obj_prefix, obj_prefix,
+ obj_prefix, obj_prefix);
+
+ model = gda_meta_store_extract (store, sql, error, NULL);
+ g_free (sql);
+ if (!model)
+ goto out;
+ nrows = gda_data_model_get_n_rows (model);
+ if (nrows > 0) {
+ xmlNewChild (hdoc->content, NULL, "h1", human_obj_type);
+ div = xmlNewChild (hdoc->content, NULL, "div", NULL);
+ xmlSetProp (div, "class", "clist");
+ ul = xmlNewChild (div, NULL, "ul", NULL);
+ content_added = TRUE;
+ }
+ for (i = 0; i < nrows; i++) {
+ const GValue *cv0, *cv1;
+ gchar *tmp, *e0, *e1;
+ cv0 = gda_data_model_get_value_at (model, 0, i, error);
+ if (!cv0)
+ goto out;
+ cv1 = gda_data_model_get_value_at (model, 1, i, error);
+ if (!cv1)
+ goto out;
+ li = xmlNewChild (ul, NULL, "li", NULL);
+ a = xmlNewChild (li, NULL, "a", g_value_get_string (cv1));
+ e0 = gda_rfc1738_encode (g_value_get_string (cv0));
+ e1 = gda_rfc1738_encode (g_value_get_string (cv1));
+ tmp = g_strdup_printf ("/%s/%s/%s", rfc_cnc_name, e0, e1);
+ g_free (e0);
+ g_free (e1);
+ xmlSetProp (a, "href", tmp);
+ g_free (tmp);
+ tmp = g_strdup_printf ("%s.%s", g_value_get_string (cv0), g_value_get_string (cv1));
+ xmlSetProp (a, "title", tmp);
+ g_free (tmp);
+ }
+ if (nrows > 0)
+ xmlNewChild (div, NULL, "br", NULL);
+ g_object_unref (model);
+
+ /* objects listed by schema */
+ if (filter)
+ sql = g_strdup_printf ("SELECT %s_schema, %s_name FROM %s WHERE %s "
+ "ORDER BY %s_schema, %s_name",
+ obj_prefix, obj_prefix, table_name, filter, obj_prefix, obj_prefix);
+ else
+ sql = g_strdup_printf ("SELECT %s_schema, %s_name FROM %s "
+ "ORDER BY %s_schema, %s_name",
+ obj_prefix, obj_prefix, table_name, obj_prefix, obj_prefix);
+ model = gda_meta_store_extract (store, sql, error, NULL);
+ g_free (sql);
+ if (!model)
+ goto out;
+
+ nrows = gda_data_model_get_n_rows (model);
+ for (i = 0; i < nrows; i++) {
+ const GValue *cv0, *cv1;
+ gchar *tmp, *e0, *e1;
+
+ cv0 = gda_data_model_get_value_at (model, 0, i, error);
+ if (!cv0)
+ goto out;
+ cv1 = gda_data_model_get_value_at (model, 1, i, error);
+ if (!cv1)
+ goto out;
+ if (!schema || gda_value_differ (schema, cv0)) {
+ xmlNodePtr header;
+ gchar *tmp;
+ if (schema) {
+ xmlNewChild (div, NULL, "br", NULL);
+ gda_value_free (schema);
+ }
+ schema = gda_value_copy (cv0);
+ tmp = g_strdup_printf (human_obj_type_in_schema, g_value_get_string (schema));
+ header = xmlNewChild (hdoc->content, NULL, "h1", tmp);
+ g_free (tmp);
+ content_added = TRUE;
+ div = xmlNewChild (hdoc->content, NULL, "div", NULL);
+ xmlSetProp (div, "class", "clist");
+ ul = xmlNewChild (div, NULL, "ul", NULL);
+ }
+
+ li = xmlNewChild (ul, NULL, "li", NULL);
+ a = xmlNewChild (li, NULL, "a", g_value_get_string (cv1));
+ e0 = gda_rfc1738_encode (g_value_get_string (cv0));
+ e1 = gda_rfc1738_encode (g_value_get_string (cv1));
+ tmp = g_strdup_printf ("/%s/%s/%s", rfc_cnc_name, e0, e1);
+ g_free (e0);
+ g_free (e1);
+ xmlSetProp (a, "href", tmp);
+ g_free (tmp);
+ }
+ if (nrows != 0)
+ xmlNewChild (div, NULL, "br", NULL);
+ retval = TRUE;
+
+ if (! content_added)
+ xmlNewChild (hdoc->content, NULL, "br", NULL);
+
+ out:
+ if (schema)
+ gda_value_free (schema);
+ if (model)
+ g_object_unref (model);
+ g_free (rfc_cnc_name);
+
+ return retval;
+}
+
+/*
+ * Lists all objects of a type (tables, view, ...)
+ */
+static gboolean
+compute_all_triggers_content (HtmlDoc *hdoc, const ConnectionSetting *cs, GError **error)
+{
+ gboolean retval = FALSE;
+ gchar *rfc_cnc_name;
+ GdaMetaStore *store;
+ GdaDataModel *model;
+ gint i, nrows;
+ GValue *schema = NULL, *tschema = NULL, *tname = NULL;
+ xmlNodePtr ul, sul, li, a, div = NULL, sdiv = NULL;
+ gboolean content_added = FALSE;
+
+ rfc_cnc_name = gda_rfc1738_encode (cs->name);
+
+ store = gda_connection_get_meta_store (cs->cnc);
+
+ model = gda_meta_store_extract (store, "SELECT trigger_schema, trigger_name, event_manipulation, "
+ "event_object_schema, event_object_table FROM _triggers WHERE "
+ "trigger_short_name != trigger_full_name "
+ "ORDER BY trigger_schema, trigger_name, event_object_schema, "
+ "event_object_table, event_manipulation",
+ error, NULL);
+ if (!model)
+ goto out;
+ nrows = gda_data_model_get_n_rows (model);
+ if (nrows > 0) {
+ xmlNewChild (hdoc->content, NULL, "h1", _("Triggers:"));
+ div = xmlNewChild (hdoc->content, NULL, "div", NULL);
+ xmlSetProp (div, "class", "clist");
+ content_added = TRUE;
+ }
+ for (i = 0; i < nrows; i++) {
+ const GValue *cv0, *cv1, *cv2, *cv3, *cv4;
+ gchar *tmp, *e0, *e1;
+
+ if (! (cv0 = gda_data_model_get_value_at (model, 0, i, error)))
+ goto out;
+ if (! (cv1 = gda_data_model_get_value_at (model, 1, i, error)))
+ goto out;
+ if (! (cv2 = gda_data_model_get_value_at (model, 2, i, error)))
+ goto out;
+ if (! (cv3 = gda_data_model_get_value_at (model, 3, i, error)))
+ goto out;
+ if (! (cv4 = gda_data_model_get_value_at (model, 4, i, error)))
+ goto out;
+
+ if ((!tschema || gda_value_differ (tschema, cv3)) ||
+ (!tname || gda_value_differ (tname, cv4))) {
+ gchar *tmp;
+ if (tschema)
+ xmlNewChild (sdiv, NULL, "br", NULL);
+ if (tschema)
+ gda_value_free (tschema);
+ if (tname)
+ gda_value_free (tname);
+ tschema = gda_value_copy (cv3);
+ tname = gda_value_copy (cv4);
+
+ tmp = g_strdup_printf (_("For the '%s.%s' table:"), g_value_get_string (tschema),
+ g_value_get_string (tname));
+ xmlNewChild (div, NULL, "h2", tmp);
+ g_free (tmp);
+
+ sdiv = xmlNewChild (div, NULL, "div", NULL);
+ xmlSetProp (sdiv, "class", "clist");
+ sul = xmlNewChild (sdiv, NULL, "ul", NULL);
+ }
+
+ li = xmlNewChild (sul, NULL, "li", NULL);
+ tmp = g_strdup_printf ("%s (%s)", g_value_get_string (cv1), g_value_get_string (cv2));
+ a = xmlNewChild (li, NULL, "a", tmp);
+ g_free (tmp);
+
+ e0 = gda_rfc1738_encode (g_value_get_string (cv0));
+ e1 = gda_rfc1738_encode (g_value_get_string (cv1));
+ tmp = g_strdup_printf ("/%s/%s/%s", rfc_cnc_name, e0, e1);
+ g_free (e0);
+ g_free (e1);
+ xmlSetProp (a, "href", tmp);
+ g_free (tmp);
+ }
+ if (nrows > 0)
+ xmlNewChild (sdiv, NULL, "br", NULL);
+ g_object_unref (model);
+ if (tschema) {
+ gda_value_free (tschema);
+ tschema = NULL;
+ }
+ if (tname) {
+ gda_value_free (tname);
+ tname = NULL;
+ }
+
+ /* objects listed by schema */
+ model = gda_meta_store_extract (store, "SELECT trigger_schema, trigger_name, event_manipulation, "
+ "event_object_schema, event_object_table FROM _triggers "
+ "ORDER BY trigger_schema, trigger_name, event_object_schema, "
+ "event_object_table, event_manipulation",
+ error, NULL);
+ if (!model)
+ goto out;
+
+ nrows = gda_data_model_get_n_rows (model);
+ for (i = 0; i < nrows; i++) {
+ const GValue *cv0, *cv1, *cv2, *cv3, *cv4;
+ gchar *tmp, *e0, *e1;
+
+ if (! (cv0 = gda_data_model_get_value_at (model, 0, i, error)))
+ goto out;
+ if (! (cv1 = gda_data_model_get_value_at (model, 1, i, error)))
+ goto out;
+ if (! (cv2 = gda_data_model_get_value_at (model, 2, i, error)))
+ goto out;
+ if (! (cv3 = gda_data_model_get_value_at (model, 3, i, error)))
+ goto out;
+ if (! (cv4 = gda_data_model_get_value_at (model, 4, i, error)))
+ goto out;
+ if (!schema || gda_value_differ (schema, cv0)) {
+ gchar *tmp;
+ if (schema) {
+ xmlNewChild (sdiv, NULL, "br", NULL);
+ gda_value_free (schema);
+ }
+ schema = gda_value_copy (cv0);
+ tmp = g_strdup_printf (_("Triggers in the '%s' schema:"), g_value_get_string (schema));
+ xmlNewChild (hdoc->content, NULL, "h1", tmp);
+ g_free (tmp);
+ content_added = TRUE;
+ div = xmlNewChild (hdoc->content, NULL, "div", NULL);
+ xmlSetProp (div, "class", "clist");
+
+ if (tschema) {
+ gda_value_free (tschema);
+ tschema = NULL;
+ }
+ if (tname) {
+ gda_value_free (tname);
+ tname = NULL;
+ }
+ }
+ if ((!tschema || gda_value_differ (tschema, cv3)) ||
+ (!tname || gda_value_differ (tname, cv4))) {
+ gchar *tmp;
+ if (tschema)
+ xmlNewChild (sdiv, NULL, "br", NULL);
+ if (tschema)
+ gda_value_free (tschema);
+ if (tname)
+ gda_value_free (tname);
+ tschema = gda_value_copy (cv3);
+ tname = gda_value_copy (cv4);
+
+ tmp = g_strdup_printf (_("For the '%s.%s' table:"), g_value_get_string (tschema),
+ g_value_get_string (tname));
+ xmlNewChild (div, NULL, "h2", tmp);
+ g_free (tmp);
+
+ sdiv = xmlNewChild (div, NULL, "div", NULL);
+ xmlSetProp (sdiv, "class", "clist");
+ sul = xmlNewChild (sdiv, NULL, "ul", NULL);
+ }
+
+ li = xmlNewChild (sul, NULL, "li", NULL);
+ tmp = g_strdup_printf ("%s (%s)", g_value_get_string (cv1), g_value_get_string (cv2));
+ a = xmlNewChild (li, NULL, "a", tmp);
+ g_free (tmp);
+
+ e0 = gda_rfc1738_encode (g_value_get_string (cv0));
+ e1 = gda_rfc1738_encode (g_value_get_string (cv1));
+ tmp = g_strdup_printf ("/%s/%s/%s", rfc_cnc_name, e0, e1);
+ g_free (e0);
+ g_free (e1);
+ xmlSetProp (a, "href", tmp);
+ g_free (tmp);
+ }
+ if (nrows != 0)
+ xmlNewChild (sdiv, NULL, "br", NULL);
+ retval = TRUE;
+
+ if (! content_added)
+ xmlNewChild (hdoc->content, NULL, "br", NULL);
+
+ out:
+ if (schema)
+ gda_value_free (schema);
+ if (tschema)
+ gda_value_free (tschema);
+ if (tname)
+ gda_value_free (tname);
+
+ if (model)
+ g_object_unref (model);
+ g_free (rfc_cnc_name);
+
+ return retval;
+}
Added: trunk/tools/web-server.h
==============================================================================
--- (empty file)
+++ trunk/tools/web-server.h Wed Dec 10 21:11:52 2008
@@ -0,0 +1,66 @@
+/* web-server.h
+ *
+ * Copyright (C) 2008 Vivien Malerba
+ *
+ * This Library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This Library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this Library; see the file COPYING.LIB. If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+
+#ifndef __WEB_SERVER_H_
+#define __WEB_SERVER_H_
+
+#include "gda-sql.h"
+
+G_BEGIN_DECLS
+
+#define WEB_TYPE_SERVER (web_server_get_type())
+#define WEB_SERVER(obj) G_TYPE_CHECK_INSTANCE_CAST (obj, web_server_get_type(), WebServer)
+#define WEB_SERVER_CLASS(klass) G_TYPE_CHECK_CLASS_CAST (klass, web_server_get_type (), WebServerClass)
+#define WEB_IS_SERVER(obj) G_TYPE_CHECK_INSTANCE_TYPE (obj, web_server_get_type ())
+
+typedef struct _WebServer WebServer;
+typedef struct _WebServerClass WebServerClass;
+typedef struct _WebServerPrivate WebServerPrivate;
+
+
+/* error reporting */
+extern GQuark web_server_error_quark (void);
+#define WEB_SERVER_ERROR web_server_error_quark ()
+
+typedef enum {
+ WEB_SERVER__ERROR,
+} WebServerError;
+
+/* struct for the object's data */
+struct _WebServer
+{
+ GObject object;
+ WebServerPrivate *priv;
+};
+
+
+/* struct for the object's class */
+struct _WebServerClass
+{
+ GObjectClass parent_class;
+};
+
+GType web_server_get_type (void) G_GNUC_CONST;
+WebServer *web_server_new (gint port);
+
+G_END_DECLS
+
+#endif
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]