1 /*
2  * Copyright (C) 2008 Murray Cumming <murrayc@murrayc.com>
3  * Copyright (C) 2008 - 2011 Vivien Malerba <malerba@gnome-db.org>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
18  * Boston, MA  02110-1301, USA.
19  */
20 
21 #include <glib/gi18n-lib.h>
22 #include <libgda/libgda.h>
23 #include "gda-jdbc-ddl.h"
24 
25 gchar *
gda_jdbc_render_CREATE_TABLE(GdaServerProvider * provider,GdaConnection * cnc,GdaServerOperation * op,GError ** error)26 gda_jdbc_render_CREATE_TABLE (GdaServerProvider *provider, GdaConnection *cnc,
27 			      GdaServerOperation *op, GError **error)
28 {
29 	GString *string;
30 	const GValue *value;
31 	gboolean allok = TRUE;
32 	gboolean hasfields = FALSE;
33 	gint nrows;
34 	gint i;
35 	gboolean first;
36 	GSList *pkfields = NULL; /* list of GValue* composing the pkey */
37 	gint nbpkfields = 0;
38 	gchar *sql = NULL;
39 	gchar *tmp;
40 
41 	/* CREATE TABLE */
42 	string = g_string_new ("CREATE TABLE ");
43 
44 	tmp = gda_server_operation_get_sql_identifier_at (op, cnc, provider, "/TABLE_DEF_P/TABLE_NAME");
45 	g_string_append (string, tmp);
46 	g_free (tmp);
47 	g_string_append (string, " (");
48 
49 	/* FIELDS */
50 	if (allok) {
51 		GdaServerOperationNode *node;
52 
53 		node = gda_server_operation_get_node_info (op, "/FIELDS_A");
54 		g_assert (node);
55 
56 		/* finding if there is a composed primary key */
57 		nrows = gda_data_model_get_n_rows (node->model);
58 		for (i = 0; i < nrows; i++) {
59 			value = gda_server_operation_get_value_at (op, "/FIELDS_A/@COLUMN_PKEY/%d", i);
60 			if (value && G_VALUE_HOLDS (value, G_TYPE_BOOLEAN) && g_value_get_boolean (value)) {
61 				tmp = gda_server_operation_get_sql_identifier_at (op, cnc, provider,
62 										  "/FIELDS_A/@COLUMN_NAME/%d", i);
63 				pkfields = g_slist_append (pkfields, tmp);
64 				nbpkfields++;
65 			}
66 		}
67 
68 		/* manually defined fields */
69 		first = TRUE;
70 		for (i = 0; i < nrows; i++) {
71 			hasfields = TRUE;
72 			if (first)
73 				first = FALSE;
74 			else
75 				g_string_append (string, ", ");
76 
77 			tmp = gda_server_operation_get_sql_identifier_at (op, cnc, provider,
78 									  "/FIELDS_A/@COLUMN_NAME/%d", i);
79 			g_string_append (string, tmp);
80 			g_free (tmp);
81 			g_string_append_c (string, ' ');
82 
83 			value = gda_server_operation_get_value_at (op, "/FIELDS_A/@COLUMN_TYPE/%d", i);
84 			g_string_append (string, g_value_get_string (value));
85 
86 			value = gda_server_operation_get_value_at (op, "/FIELDS_A/@COLUMN_DEFAULT/%d", i);
87 			if (value && G_VALUE_HOLDS (value, G_TYPE_STRING)) {
88 				const gchar *str = g_value_get_string (value);
89 				if (str && *str) {
90 					g_string_append (string, " DEFAULT ");
91 					g_string_append (string, str);
92 				}
93 			}
94 
95 			value = gda_server_operation_get_value_at (op, "/FIELDS_A/@COLUMN_NNUL/%d", i);
96 			if (value && G_VALUE_HOLDS (value, G_TYPE_BOOLEAN) && g_value_get_boolean (value))
97 				g_string_append (string, " NOT NULL");
98 
99 			value = gda_server_operation_get_value_at (op, "/FIELDS_A/@COLUMN_UNIQUE/%d", i);
100 			if (value && G_VALUE_HOLDS (value, G_TYPE_BOOLEAN) && g_value_get_boolean (value))
101 				g_string_append (string, " UNIQUE");
102 
103 			if (nbpkfields == 1) {
104 				value = gda_server_operation_get_value_at (op, "/FIELDS_A/@COLUMN_PKEY/%d", i);
105 				if (value && G_VALUE_HOLDS (value, G_TYPE_BOOLEAN) && g_value_get_boolean (value))
106 					g_string_append (string, " PRIMARY KEY");
107 			}
108 
109 			value = gda_server_operation_get_value_at (op, "/FIELDS_A/@COLUMN_CHECK/%d", i);
110 			if (value && G_VALUE_HOLDS (value, G_TYPE_STRING)) {
111 				const gchar *str = g_value_get_string (value);
112 				if (str && *str) {
113 					g_string_append (string, " CHECK (");
114 					g_string_append (string, str);
115 					g_string_append_c (string, ')');
116 				}
117 			}
118 		}
119 	}
120 
121 	/* composed primary key */
122 	if (nbpkfields > 1) {
123 		GSList *list;
124 
125 		g_string_append (string, ", PRIMARY KEY (");
126 		for (list = pkfields; list; list = list->next) {
127 			if (list != pkfields)
128 				g_string_append (string, ", ");
129 			g_string_append (string, (gchar*) list->data);
130 		}
131 		g_string_append_c (string, ')');
132 	}
133 	g_slist_foreach (pkfields, (GFunc) g_free, NULL);
134 	g_slist_free (pkfields);
135 
136 	g_string_append (string, ")");
137 
138 	if (!hasfields) {
139 		allok = FALSE;
140 		g_set_error (error, GDA_SERVER_OPERATION_ERROR,
141                              GDA_SERVER_OPERATION_INCORRECT_VALUE_ERROR,
142 			     "%s", _("Table to create must have at least one row"));
143 	}
144 
145 	sql = string->str;
146 	g_string_free (string, FALSE);
147 
148 	return sql;
149 }
150