fixed collected data export/import for non-node data collection targets (issue #NX...
[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 IntegerArray<UINT32> *targets = GetDataCollectionTargets();
117 if (targets == NULL)
118 return false;
119
120 // Create and import idata_xx tables for each data collection target
121 bool success = true;
122 for(int i = 0; i < targets->size(); i++)
123 {
124 UINT32 id = targets->get(i);
125 if (!CreateIDataTable(id))
126 {
127 success = false;
128 break; // Failed to create idata_xx table
129 }
130
131 TCHAR table[64];
132 _sntprintf(table, 64, _T("idata_%d"), id);
133 if (!ImportTable(db, table))
134 {
135 success = false;
136 break;
137 }
138
139 if (!CreateTDataTable(id))
140 {
141 success = false;
142 break; // Failed to create tdata tables
143 }
144
145 _sntprintf(table, 64, _T("tdata_%d"), id);
146 if (!ImportTable(db, table))
147 {
148 success = false;
149 break;
150 }
151 }
152
153 delete targets;
154 return success;
155 }
156
157 /**
158 * Callback for getting schema version
159 */
160 static int GetSchemaVersionCB(void *arg, int cols, char **data, char **names)
161 {
162 *((int *)arg) = strtol(data[0], NULL, 10);
163 return 0;
164 }
165
166 /**
167 * Import database
168 */
169 void ImportDatabase(const char *file)
170 {
171 sqlite3 *db;
172 char *errmsg;
173 int i;
174 BOOL success = FALSE;
175
176 // Open SQLite database
177 if (sqlite3_open(file, &db) != SQLITE_OK)
178 {
179 _tprintf(_T("ERROR: unable to open output file\nDatabase import failed.\n"));
180 return;
181 }
182
183 // Check schema version
184 int version = 0;
185 if (sqlite3_exec(db, "SELECT var_value FROM metadata WHERE var_name='SchemaVersion'", GetSchemaVersionCB, &version, &errmsg) != SQLITE_OK)
186 {
187 _tprintf(_T("ERROR: SQL query failed (%hs)\n"), errmsg);
188 sqlite3_free(errmsg);
189 goto cleanup;
190 }
191
192 if (version != DB_FORMAT_VERSION)
193 {
194 _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);
195 goto cleanup;
196 }
197
198 if (!ClearDatabase(false))
199 goto cleanup;
200
201 // Import tables
202 for(i = 0; g_tables[i] != NULL; i++)
203 {
204 if (!ImportTable(db, g_tables[i]))
205 goto cleanup;
206 }
207 if (!ImportDataTables(db))
208 goto cleanup;
209
210 success = TRUE;
211
212 cleanup:
213 sqlite3_close(db);
214 _tprintf(success ? _T("Database import complete.\n") : _T("Database import failed.\n"));
215 }