Add initial support for optional luadata.txt datafile
[freeciv.git] / tools / mpdb.c
blob5b3cf4269f5f19194decebaa6712c688aca240bd
1 /***********************************************************************
2 Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2, or (at your option)
6 any later version.
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12 ***********************************************************************/
14 #ifdef HAVE_CONFIG_H
15 #include <fc_config.h>
16 #endif
18 #include <sqlite3.h>
20 /* utility */
21 #include "capability.h"
22 #include "fcintl.h"
23 #include "mem.h"
24 #include "registry.h"
26 /* modinst */
27 #include "download.h"
29 #include "mpdb.h"
31 #define MPDB_CAPSTR "+mpdb"
33 #define MPDB_FORMAT_VERSION "1"
35 static sqlite3 *main_handle = NULL;
36 static sqlite3 *scenario_handle = NULL;
38 static int mpdb_query(sqlite3 *handle, const char *query);
40 /**************************************************************************
41 Construct install info list from file.
42 **************************************************************************/
43 void load_install_info_list(const char *filename)
45 struct section_file *file;
46 const char *caps;
48 file = secfile_load(filename, FALSE);
50 if (file == NULL) {
51 /* This happens in first run - or actually all runs until something is
52 * installed. Previous run has not saved database. */
53 log_debug("No install info file");
55 return;
58 caps = secfile_lookup_str(file, "info.options");
60 if (caps == NULL) {
61 log_error("MPDB %s missing capability information", filename);
62 secfile_destroy(file);
63 return;
66 if (!has_capabilities(MPDB_CAPSTR, caps)) {
67 log_error("Incompatible mpdb file %s:", filename);
68 log_error(" file options: %s", caps);
69 log_error(" supported options: %s", MPDB_CAPSTR);
71 secfile_destroy(file);
73 return;
76 if (file != NULL) {
77 bool all_read = FALSE;
78 int i;
80 for (i = 0 ; !all_read ; i++) {
81 const char *str;
82 char buf[80];
84 fc_snprintf(buf, sizeof(buf), "modpacks.mp%d", i);
86 str = secfile_lookup_str_default(file, NULL, "%s.name", buf);
88 if (str != NULL) {
89 const char *type;
90 const char *ver;
92 type = secfile_lookup_str(file, "%s.type", buf);
93 ver = secfile_lookup_str(file, "%s.version", buf);
95 mpdb_update_modpack(str, modpack_type_by_name(type, fc_strcasecmp),
96 ver);
97 } else {
98 all_read = TRUE;
102 secfile_destroy(file);
106 /**************************************************************************
107 SQL query to database
108 **************************************************************************/
109 static int mpdb_query(sqlite3 *handle, const char *query)
111 int ret;
112 sqlite3_stmt *stmt;
114 ret = sqlite3_prepare_v2(handle, query, -1, &stmt, NULL);
116 if (ret == SQLITE_OK) {
117 ret = sqlite3_step(stmt);
120 if (ret == SQLITE_DONE) {
121 ret = sqlite3_finalize(stmt);
124 if (ret != SQLITE_OK) {
125 log_error("Query \"%s\" failed. (%d)", query, ret);
128 return ret;
131 /**************************************************************************
132 Create modpack database
133 **************************************************************************/
134 void create_mpdb(const char *filename, bool scenario_db)
136 sqlite3 **handle;
137 int ret;
138 int llen = strlen(filename) + 1;
139 char *local_name = fc_malloc(llen);
140 int i;
142 strncpy(local_name, filename, llen);
143 for (i = llen - 1 ; local_name[i] != DIR_SEPARATOR_CHAR ; i--) {
144 /* Nothing */
146 local_name[i] = '\0';
147 if (!make_dir(local_name)) {
148 log_error(_("Can't create directory \"%s\" for modpack database."), local_name);
149 return;
152 if (scenario_db) {
153 handle = &scenario_handle;
154 } else {
155 handle = &main_handle;
158 ret = sqlite3_open_v2(filename, handle, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
159 NULL);
161 if (ret == SQLITE_OK) {
162 ret = mpdb_query(*handle,
163 "create table meta (version INTEGER default " MPDB_FORMAT_VERSION ");");
166 if (ret == SQLITE_OK) {
167 ret = mpdb_query(*handle,
168 "create table modpacks (name VARCHAR(60) NOT NULL, type VARCHAR(32), version VARCHAR(32) NOT NULL);");
171 if (ret == SQLITE_OK) {
172 log_debug("Created %s", filename);
173 } else {
174 log_error(_("Creating \"%s\" failed: %s"), filename, sqlite3_errstr(ret));
178 /**************************************************************************
179 Open existing database
180 **************************************************************************/
181 void open_mpdb(const char *filename, bool scenario_db)
183 sqlite3 **handle;
184 int ret;
186 if (scenario_db) {
187 handle = &scenario_handle;
188 } else {
189 handle = &main_handle;
192 ret = sqlite3_open_v2(filename, handle, SQLITE_OPEN_READWRITE, NULL);
194 if (ret != SQLITE_OK) {
195 log_error(_("Opening \"%s\" failed: %s"), filename, sqlite3_errstr(ret));
199 /**************************************************************************
200 Close open databases
201 **************************************************************************/
202 void close_mpdbs(void)
204 sqlite3_close(main_handle);
205 main_handle = NULL;
206 sqlite3_close(scenario_handle);
207 scenario_handle = NULL;
210 /**************************************************************************
211 Update modpack information in database
212 **************************************************************************/
213 bool mpdb_update_modpack(const char *name, enum modpack_type type,
214 const char *version)
216 sqlite3 **handle;
217 int ret;
218 char qbuf[2048];
220 if (type == MPT_SCENARIO) {
221 handle = &scenario_handle;
222 } else {
223 handle = &main_handle;
226 sqlite3_snprintf(sizeof(qbuf), qbuf, "select * from modpacks where name is '%q';",
227 name);
228 ret = mpdb_query(*handle, qbuf);
230 if (ret == SQLITE_ROW) {
231 sqlite3_snprintf(sizeof(qbuf), qbuf,
232 "update modpacks set type = '%q', version = '%q' where name is '%q';",
233 modpack_type_name(type), version, name);
234 ret = mpdb_query(*handle, qbuf);
235 } else {
236 /* Completely new modpack */
237 sqlite3_snprintf(sizeof(qbuf), qbuf,
238 "insert into modpacks values ('%q', '%q', '%q');",
239 name, modpack_type_name(type), version);
240 ret = mpdb_query(*handle, qbuf);
243 if (ret != SQLITE_OK) {
244 log_error(_("Failed to insert modpack '%s' information"), name);
247 return ret != SQLITE_OK;
250 /**************************************************************************
251 Return version of modpack.
252 **************************************************************************/
253 const char *mpdb_installed_version(const char *name,
254 enum modpack_type type)
256 sqlite3 **handle;
257 int ret;
258 char qbuf[2048];
259 sqlite3_stmt *stmt;
261 if (type == MPT_SCENARIO) {
262 handle = &scenario_handle;
263 } else {
264 handle = &main_handle;
267 sqlite3_snprintf(sizeof(qbuf), qbuf,
268 "select * from modpacks where name is '%q';",
269 name);
270 ret = sqlite3_prepare_v2(*handle, qbuf, -1, &stmt, NULL);
272 if (ret == SQLITE_OK) {
273 ret = sqlite3_step(stmt);
276 if (ret == SQLITE_DONE) {
277 ret = sqlite3_finalize(stmt);
280 if (ret == SQLITE_ROW) {
281 return (const char *)sqlite3_column_text(stmt, 2);
284 return NULL;