source: ogServer-Git/src/schema.c @ a7cce8d

Last change on this file since a7cce8d was a7cce8d, checked in by OpenGnSys Support Team <soporte-og@…>, 3 years ago

ogServer is AGPLv3+

Update license header in files.

  • Property mode set to 100644
File size: 6.0 KB
Line 
1/*
2 * Copyright (C) 2020-2021 Soleta Networks <info@soleta.eu>
3 *
4 * This program is free software: you can redistribute it and/or modify it under
5 * the terms of the GNU Affero General Public License as published by the
6 * Free Software Foundation; either version 3 of the License, or
7 * (at your option) any later version.
8 */
9
10#include <syslog.h>
11#include <netinet/in.h>
12#include <arpa/inet.h>
13#include <string.h>
14#include "dbi.h"
15#include "cfg.h"
16#include <syslog.h>
17#include <string.h>
18#include <stdio.h>
19
20#define OG_SCHEMA_STMTS_V2      7
21
22static const char *stmts_v2[OG_SCHEMA_STMTS_V2] = {
23        [0]     =       "ALTER TABLE `aulas` "
24                        "ADD CONSTRAINT FK_centros "
25                        "FOREIGN KEY (`idcentro`) "
26                        "REFERENCES `centros` (`idcentro`) ON DELETE CASCADE",
27        [1]     =       "ALTER TABLE `ordenadores` "
28                        "ADD CONSTRAINT FK_aulas "
29                        "FOREIGN KEY (`idaula`) "
30                        "REFERENCES `aulas` (`idaula`) ON DELETE CASCADE",
31        [2]     =       "ALTER TABLE `ordenadores_particiones` "
32                        "ADD CONSTRAINT FK_ordenadores "
33                        "FOREIGN KEY (`idordenador`) "
34                        "REFERENCES `ordenadores` (`idordenador`) ON DELETE CASCADE",
35        [3]     =       "DELETE PS FROM perfilessoft_softwares AS PS "
36                        "WHERE NOT EXISTS ("
37                        "SELECT null FROM softwares AS S "
38                        "WHERE S.idsoftware = PS.idsoftware)",
39        [4]     =       "ALTER TABLE `perfilessoft_softwares` "
40                        "ADD CONSTRAINT FK_softwares "
41                        "FOREIGN KEY (`idsoftware`) "
42                        "REFERENCES `softwares` (`idsoftware`) ON DELETE CASCADE",
43        [5]     =       "ALTER TABLE `perfilessoft_softwares` "
44                        "ADD CONSTRAINT FK_perfilessoft "
45                        "FOREIGN KEY (`idperfilsoft`) "
46                        "REFERENCES `perfilessoft` (`idperfilsoft`) ON DELETE CASCADE",
47        [6]     =       "UPDATE version SET version = 2",
48};
49
50struct og_server_cfg ogconfig;
51
52static int og_dbi_create_version(struct og_dbi *dbi)
53{
54        const char *msglog;
55        dbi_result result;
56
57        result = dbi_conn_queryf(dbi->conn, "CREATE TABLE `version` "
58                                            "(`version` smallint unsigned NOT NULL) "
59                                            "ENGINE='MyISAM' COLLATE 'utf8_general_ci'");
60        if (!result) {
61                dbi_conn_error(dbi->conn, &msglog);
62                syslog(LOG_INFO, "Could not create schema version table (%s:%d) %s\n",
63                       __func__, __LINE__, msglog);
64                return -1;
65        }
66        dbi_result_free(result);
67
68        result = dbi_conn_queryf(dbi->conn, "INSERT INTO `version` (`version`) VALUES ('0')");
69        if (!result) {
70                dbi_conn_error(dbi->conn, &msglog);
71                syslog(LOG_INFO, "Could not insert into schema version table (%s:%d) %s\n",
72                       __func__, __LINE__, msglog);
73                return -1;
74        }
75        dbi_result_free(result);
76
77        return 0;
78}
79static int og_dbi_schema_version(struct og_dbi *dbi)
80{
81        const char *msglog;
82        dbi_result result;
83        uint32_t version;
84
85        result = dbi_conn_queryf(dbi->conn, "SELECT * from version");
86        if (!result) {
87                dbi_conn_error(dbi->conn, &msglog);
88                syslog(LOG_INFO, "no version table found (%s:%d) %s\n",
89                       __func__, __LINE__, msglog);
90                return -1;
91        }
92
93        if (!dbi_result_last_row(result)) {
94                dbi_conn_error(dbi->conn, &msglog);
95                syslog(LOG_ERR, "cannot get last row from version table (%s:%d) %s\n",
96                       __func__, __LINE__, msglog);
97                return -1;
98        }
99
100        version = dbi_result_get_uint(result, "version");
101
102        dbi_result_free(result);
103
104        return version;
105}
106
107static int og_dbi_schema_v1(struct og_dbi *dbi)
108{
109        const char *msglog, *command;
110        dbi_result result, result_alter;
111
112        result = dbi_conn_queryf(dbi->conn, "SELECT concat('alter table `',TABLE_SCHEMA,'`.`',TABLE_NAME,'` engine=innodb;')"
113                                            "AS cmd FROM information_schema.TABLES WHERE TABLE_SCHEMA='%s'",
114                                            ogconfig.db.name);
115
116        while (dbi_result_next_row(result)) {
117                command = dbi_result_get_string(result, "cmd");
118
119                syslog(LOG_DEBUG, "Upgrading to innoDB: %s\n", command);
120                result_alter = dbi_conn_query(dbi->conn, command);
121                if (!result_alter) {
122                        dbi_conn_error(dbi->conn, &msglog);
123                        syslog(LOG_INFO, "Error when upgrading engine to innoDB (%s:%d) %s\n",
124                               __func__, __LINE__, msglog);
125                        return -1;
126                }
127                dbi_result_free(result_alter);
128        }
129        dbi_result_free(result);
130
131        result = dbi_conn_query(dbi->conn, "UPDATE version SET version = 1");
132        if (!result) {
133                dbi_conn_error(dbi->conn, &msglog);
134                syslog(LOG_INFO, "Could not update version row (%s:%d) %s\n",
135                       __func__, __LINE__, msglog);
136                return -1;
137        }
138        dbi_result_free(result);
139
140        return 0;
141}
142
143static int og_dbi_schema_v2(struct og_dbi *dbi)
144{
145        const char *msglog;
146        dbi_result result;
147        int ret, i;
148
149        ret = dbi_conn_transaction_begin(dbi->conn);
150        if (ret) {
151                syslog(LOG_DEBUG, "could not begin a transaction (%s:%d)\n",
152                       __func__, __LINE__);
153                goto err_no_trans;
154        }
155
156        for (i = 0; i < OG_SCHEMA_STMTS_V2; i++) {
157                result = dbi_conn_query(dbi->conn, stmts_v2[i]);
158                if (!result) {
159                        dbi_conn_error(dbi->conn, &msglog);
160                        syslog(LOG_ERR, "Statement number %d failed (%s:%d): %s\n",
161                                        i, __func__, __LINE__, msglog);
162                        goto err_trans;
163                }
164                dbi_result_free(result);
165        }
166
167        ret = dbi_conn_transaction_commit(dbi->conn);
168        if (ret) {
169                syslog(LOG_DEBUG, "could not commit a transaction (%s:%d)\n",
170                       __func__, __LINE__);
171                goto err_trans;
172        }
173        return 0;
174
175err_trans:
176        dbi_conn_transaction_rollback(dbi->conn);
177err_no_trans:
178        return -1;
179}
180
181static struct og_schema_version {
182        int     version;
183        int     (*update)(struct og_dbi *dbi);
184} schema_version[] = {
185        {       .version = 1,   .update = og_dbi_schema_v1      },
186        {       .version = 2,   .update = og_dbi_schema_v2      },
187        {       0,              NULL                            },
188};
189
190int og_dbi_schema_update(void)
191{
192        int version, i, err;
193        struct og_dbi *dbi;
194        const char *msglog;
195
196        dbi = og_dbi_open(&ogconfig.db);
197        if (!dbi) {
198                dbi_conn_error(dbi->conn, &msglog);
199                syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
200                       __func__, __LINE__, msglog);
201                return -1;
202        }
203
204        version = og_dbi_schema_version(dbi);
205
206        if (version < 0) {
207                syslog(LOG_INFO, "creating table version in schema\n");
208                og_dbi_create_version(dbi);
209        } else {
210                syslog(LOG_INFO, "database schema version %d\n", version);
211        }
212
213        for (i = 0; schema_version[i].version; i++) {
214                if (version >= schema_version[i].version)
215                        continue;
216
217                syslog(LOG_INFO, "upgrading to schema version %d\n", schema_version[i].version);
218
219                err = schema_version[i].update(dbi);
220                if (err < 0) {
221                        syslog(LOG_ERR, "failed to update schema!\n");
222                        og_dbi_close(dbi);
223                        return -1;
224                }
225        }
226
227        og_dbi_close(dbi);
228
229        return 0;
230}
Note: See TracBrowser for help on using the repository browser.