1 /* MDB Tools - A library for reading MS Access database file
2  * Copyright (C) 2000 Brian Bruns
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17  */
18 
19 /* this utility dumps the schema for an existing database */
20 #include "mdbtools.h"
21 #include "mdbver.h"
22 
23 int
main(int argc,char ** argv)24 main (int argc, char **argv)
25 {
26 	MdbHandle *mdb;
27 	char *tabname = NULL;
28 	char *namespace = NULL;
29 	guint32 export_options;
30 	int opt_drop_table = MDB_SHEXP_DEFAULT & MDB_SHEXP_DROPTABLE;
31 	int opt_not_null = MDB_SHEXP_DEFAULT & MDB_SHEXP_CST_NOTNULL;
32 	int opt_def_values = MDB_SHEXP_DEFAULT & MDB_SHEXP_DEFVALUES;
33 	int opt_not_empty = MDB_SHEXP_DEFAULT & MDB_SHEXP_CST_NOTEMPTY;
34 	int opt_comments = MDB_SHEXP_DEFAULT & MDB_SHEXP_COMMENTS;
35 	int opt_indexes = MDB_SHEXP_DEFAULT & MDB_SHEXP_INDEXES;
36 	int opt_relations = MDB_SHEXP_DEFAULT & MDB_SHEXP_RELATIONS;
37 	int success = 0;
38 	int print_mdbver = 0;
39 
40 	GOptionEntry entries[] = {
41 		{ "table", 'T', 0, G_OPTION_ARG_STRING, &tabname, "Only create schema for named table", "table"},
42 		{ "namespace", 'N', 0, G_OPTION_ARG_STRING, &namespace, "Prefix identifiers with namespace", "namespace"},
43 		{ "drop-table", 0, 0, G_OPTION_ARG_NONE, &opt_drop_table, "Include DROP TABLE statements", NULL},
44 		{ "no-drop-table", 0, G_OPTION_FLAG_REVERSE, G_OPTION_ARG_NONE, &opt_drop_table, "Don't include DROP TABLE statements", NULL},
45 		{ "not-null", 0, 0, G_OPTION_ARG_NONE, &opt_not_null, "Include NOT NULL constraints", NULL},
46 		{ "no-not-null", 0, G_OPTION_FLAG_REVERSE, G_OPTION_ARG_NONE, &opt_not_null, "Don't include NOT NULL constraints", NULL},
47 		{ "default-values", 0, 0, G_OPTION_ARG_NONE, &opt_def_values, "Include default values", NULL},
48 		{ "no-default-values", 0, G_OPTION_FLAG_REVERSE, G_OPTION_ARG_NONE, &opt_def_values, "Don't include default values", NULL},
49 		{ "not-empty", 0, 0, G_OPTION_ARG_NONE, &opt_not_empty, "Include not empty constraints", NULL},
50 		{ "no-not_empty", 0, G_OPTION_FLAG_REVERSE, G_OPTION_ARG_NONE, &opt_not_empty, "Don't include not empty constraints", NULL},
51 		{ "comments", 0, 0, G_OPTION_ARG_NONE, &opt_comments, "Include COMMENT ON statements", NULL},
52 		{ "no-comments", 0, G_OPTION_FLAG_REVERSE, G_OPTION_ARG_NONE, &opt_comments, "Don't include COMMENT statements.", NULL},
53 		{ "indexes", 0, 0, G_OPTION_ARG_NONE, &opt_indexes, "Include indexes", NULL},
54 		{ "no-indexes", 0, G_OPTION_FLAG_REVERSE, G_OPTION_ARG_NONE, &opt_indexes, "Don't include indexes", NULL},
55 		{ "relations", 0, 0, G_OPTION_ARG_NONE, &opt_relations, "Include foreign key constraints", NULL},
56 		{ "no-relations", 0, G_OPTION_FLAG_REVERSE, G_OPTION_ARG_NONE, &opt_relations, "Don't include foreign key constraints", NULL},
57 		{"version", 0, 0, G_OPTION_ARG_NONE, &print_mdbver, "Show mdbtools version and exit", NULL},
58 		{ NULL },
59 	};
60 	GError *error = NULL;
61 	GOptionContext *opt_context;
62 	char *old_locale = setlocale(LC_CTYPE, "");
63 
64 	opt_context = g_option_context_new("<file> [<backend>] - Dump schema");
65 	g_option_context_add_main_entries(opt_context, entries, NULL /*i18n*/);
66 	// g_option_context_set_strict_posix(opt_context, TRUE); /* options first, requires glib 2.44 */
67 	if (!g_option_context_parse (opt_context, &argc, &argv, &error))
68 	{
69 		fprintf(stderr, "option parsing failed: %s\n", error->message);
70 		fputs(g_option_context_get_help(opt_context, TRUE, NULL), stderr);
71 		exit (1);
72 	}
73 	if (print_mdbver) {
74 		if (argc > 1) {
75 			fputs(g_option_context_get_help(opt_context, TRUE, NULL), stderr);
76 		}
77 		fprintf(stdout,"%s\n", MDB_FULL_VERSION);
78 		exit(argc > 1);
79 	}
80 
81 	setlocale(LC_CTYPE, old_locale);
82 
83 	if (argc < 2 || argc > 3) {
84 		fputs("Wrong number of arguments.\n\n", stderr);
85 		fputs(g_option_context_get_help(opt_context, TRUE, NULL), stderr);
86 		exit(1);
87 	}
88 
89 	/* open the database */
90 	mdb = mdb_open (argv[1], MDB_NOFLAGS);
91 	if (!mdb) {
92 		fprintf(stderr, "Could not open file\n");
93 		exit(1);
94 	}
95 
96 	if (argc == 3) {
97 		if (!mdb_set_default_backend(mdb, argv[2])) {
98 			fprintf(stderr, "Invalid backend type\n");
99 			exit(1);
100 		}
101 	}
102 
103 	/* read the catalog */
104  	if (!mdb_read_catalog (mdb, MDB_TABLE)) {
105 		fputs("File does not appear to be an Access database\n", stderr);
106 		exit(1);
107 	}
108 
109 	export_options = 0;
110 	if (opt_drop_table)
111 		export_options |= MDB_SHEXP_DROPTABLE;
112 	if (opt_not_null)
113 		export_options |= MDB_SHEXP_CST_NOTNULL;
114 	if (opt_def_values)
115 		export_options |= MDB_SHEXP_DEFVALUES;
116 	if (opt_not_empty)
117 		export_options |= MDB_SHEXP_CST_NOTEMPTY;
118 	if (opt_comments)
119 		export_options |= MDB_SHEXP_COMMENTS;
120 	if (opt_indexes)
121 		export_options |= MDB_SHEXP_INDEXES;
122 	if (opt_relations)
123 		export_options |= MDB_SHEXP_RELATIONS;
124 
125 	success = mdb_print_schema(mdb, stdout, tabname, namespace, export_options);
126 	if (tabname && !success) {
127 		fprintf(stderr, "Error: No table named \"%s\" found in the database\n", tabname);
128 	}
129 
130 	mdb_close (mdb);
131 
132 	g_option_context_free(opt_context);
133 	g_free(namespace);
134 	g_free(tabname);
135 	return !success;
136 }
137 
138