implemented tdata tables conversion to new format
[public/netxms.git] / src / server / tools / nxdbmgr / import.cpp
1 /*
2 ** nxdbmgr - NetXMS database manager
3 ** Copyright (C) 2004-2010 Victor Kirhenshtein
4 **
5 ** This program is free software; you can redistribute it and/or modify
6 ** it under the terms of the GNU General Public License as published by
7 ** the Free Software Foundation; either version 2 of the License, or
8 ** (at your option) any later version.
9 **
10 ** This program 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
13 ** GNU General Public License for more details.
14 **
15 ** You should have received a copy of the GNU General Public License
16 ** along with this program; if not, write to the Free Software
17 ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 **
19 ** File: import.cpp
20 **
21 **/
22
23 #include "nxdbmgr.h"
24 #include "sqlite3.h"
25
26 /**
27 * Tables to import
28 */
29 extern const TCHAR *g_tables[];
30
31 /**
32 * Callback for import table
33 */
34 static int ImportTableCB(void *arg, int cols, char **data, char **names)
35 {
36 String query;
37 int i;
38
39 query.appendFormattedString(_T("INSERT INTO %s ("), arg);
40 for(i = 0; i < cols; i++)
41 {
42 query.appendMBString(names[i], strlen(names[i]), CP_UTF8);
43 query += _T(",");
44 }
45 query.shrink();
46 query += _T(") VALUES (");
47 for(i = 0; i < cols; i++)
48 {
49 if (data[i] != NULL)
50 {
51 #ifdef UNICODE
52 WCHAR *wcData = WideStringFromUTF8String(data[i]);
53 String prepData = DBPrepareString(g_hCoreDB, wcData);
54 free(wcData);
55 #else
56 String prepData = DBPrepareString(g_hCoreDB, data[i]);
57 #endif
58 query += (const TCHAR *)prepData;
59 query += _T(",");
60 }
61 else
62 {
63 query += _T("NULL,");
64 }
65 }
66 query.shrink();
67 query += _T(")");
68
69 return SQLQuery(query) ? 0 : 1;
70 }
71
72 /**
73 * Import single database table
74 */
75 static BOOL ImportTable(sqlite3 *db, const TCHAR *table)
76 {
77 char query[256], *errmsg;
78 int rc;
79
80 _tprintf(_T("Importing table %s\n"), table);
81
82 if (DBBegin(g_hCoreDB))
83 {
84 #ifdef UNICODE
85 char *mbTable = MBStringFromWideString(table);
86 snprintf(query, 256, "SELECT * FROM %s", mbTable);
87 free(mbTable);
88 #else
89 snprintf(query, 256, "SELECT * FROM %s", table);
90 #endif
91 rc = sqlite3_exec(db, query, ImportTableCB, (void *)table, &errmsg);
92 if (rc == SQLITE_OK)
93 {
94 DBCommit(g_hCoreDB);
95 }
96 else
97 {
98 _tprintf(_T("ERROR: SQL query \"%hs\" on import file failed (%hs)\n"), query, errmsg);
99 sqlite3_free(errmsg);
100 DBRollback(g_hCoreDB);
101 }
102 }
103 else
104 {
105 _tprintf(_T("ERROR: unable to start transaction in target database\n"));
106 rc = -1;
107 }
108 return rc == SQLITE_OK;
109 }
110
111 /**
112 * Import data tables
113 */
114 static BOOL ImportDataTables(sqlite3 *db)
115 {
116 int i, count;
117 TCHAR buffer[1024];
118
119 DB_RESULT hResult = SQLSelect(_T("SELECT id FROM nodes"));
120 if (hResult == NULL)
121 return FALSE;
122
123 // Create and import idata_xx tables for each node in "nodes" table
124 count = DBGetNumRows(hResult);
125 for(i = 0; i < count; i++)
126 {
127 DWORD id = DBGetFieldULong(hResult, i, 0);
128 if (!CreateIDataTable(id))
129 break; // Failed to create idata_xx table
130
131 _sntprintf(buffer, 1024, _T("idata_%d"), id);
132 if (!ImportTable(db, buffer))
133 break;
134
135 if (!CreateTDataTable(id))
136 break; // Failed to create tdata tables
137
138 _sntprintf(buffer, 1024, _T("tdata_%d"), id);
139 if (!ImportTable(db, buffer))
140 break;
141 }
142
143 DBFreeResult(hResult);
144 return i == count;
145 }
146
147 /**
148 * Callback for getting schema version
149 */
150 static int GetSchemaVersionCB(void *arg, int cols, char **data, char **names)
151 {
152 *((int *)arg) = strtol(data[0], NULL, 10);
153 return 0;
154 }
155
156 /**
157 * Import database
158 */
159 void ImportDatabase(const char *file)
160 {
161 sqlite3 *db;
162 char *errmsg;
163 int i;
164 BOOL success = FALSE;
165
166 // Open SQLite database
167 if (sqlite3_open(file, &db) != SQLITE_OK)
168 {
169 _tprintf(_T("ERROR: unable to open output file\nDatabase import failed.\n"));
170 return;
171 }
172
173 // Check schema version
174 int version = 0;
175 if (sqlite3_exec(db, "SELECT var_value FROM metadata WHERE var_name='SchemaVersion'", GetSchemaVersionCB, &version, &errmsg) != SQLITE_OK)
176 {
177 _tprintf(_T("ERROR: SQL query failed (%hs)\n"), errmsg);
178 sqlite3_free(errmsg);
179 goto cleanup;
180 }
181
182 if (version != DB_FORMAT_VERSION)
183 {
184 _tprintf(_T("ERROR: Import file was created for database format version %d, but this tool was compiled for database format version %d\n"), version, DB_FORMAT_VERSION);
185 goto cleanup;
186 }
187
188 if (!ClearDatabase(false))
189 goto cleanup;
190
191 // Import tables
192 for(i = 0; g_tables[i] != NULL; i++)
193 {
194 if (!ImportTable(db, g_tables[i]))
195 goto cleanup;
196 }
197 if (!ImportDataTables(db))
198 goto cleanup;
199
200 success = TRUE;
201
202 cleanup:
203 sqlite3_close(db);
204 _tprintf(success ? _T("Database import complete.\n") : _T("Database import failed.\n"));
205 }