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)
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 ***********************************************************************/
15 #include <fc_config.h>
21 #include "capability.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
;
48 file
= secfile_load(filename
, FALSE
);
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");
58 caps
= secfile_lookup_str(file
, "info.options");
61 log_error("MPDB %s missing capability information", filename
);
62 secfile_destroy(file
);
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
);
77 bool all_read
= FALSE
;
80 for (i
= 0 ; !all_read
; i
++) {
84 fc_snprintf(buf
, sizeof(buf
), "modpacks.mp%d", i
);
86 str
= secfile_lookup_str_default(file
, NULL
, "%s.name", buf
);
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
),
102 secfile_destroy(file
);
106 /**************************************************************************
107 SQL query to database
108 **************************************************************************/
109 static int mpdb_query(sqlite3
*handle
, const char *query
)
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
);
131 /**************************************************************************
132 Create modpack database
133 **************************************************************************/
134 void create_mpdb(const char *filename
, bool scenario_db
)
138 int llen
= strlen(filename
) + 1;
139 char *local_name
= fc_malloc(llen
);
142 strncpy(local_name
, filename
, llen
);
143 for (i
= llen
- 1 ; local_name
[i
] != DIR_SEPARATOR_CHAR
; i
--) {
146 local_name
[i
] = '\0';
147 if (!make_dir(local_name
)) {
148 log_error(_("Can't create directory \"%s\" for modpack database."), local_name
);
153 handle
= &scenario_handle
;
155 handle
= &main_handle
;
158 ret
= sqlite3_open_v2(filename
, handle
, SQLITE_OPEN_READWRITE
| SQLITE_OPEN_CREATE
,
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
);
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
)
187 handle
= &scenario_handle
;
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 /**************************************************************************
201 **************************************************************************/
202 void close_mpdbs(void)
204 sqlite3_close(main_handle
);
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
,
220 if (type
== MPT_SCENARIO
) {
221 handle
= &scenario_handle
;
223 handle
= &main_handle
;
226 sqlite3_snprintf(sizeof(qbuf
), qbuf
, "select * from modpacks where name is '%q';",
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
);
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
)
261 if (type
== MPT_SCENARIO
) {
262 handle
= &scenario_handle
;
264 handle
= &main_handle
;
267 sqlite3_snprintf(sizeof(qbuf
), qbuf
,
268 "select * from modpacks where name is '%q';",
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);