1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
|
#ifndef EXPORTPLUGIN_H
#define EXPORTPLUGIN_H
#include "plugin.h"
#include "db/sqlquery.h"
#include "db/queryexecutor.h"
#include "services/exportmanager.h"
#include "parser/ast/sqlitecreatetable.h"
#include "parser/ast/sqlitecreateindex.h"
#include "parser/ast/sqlitecreatetrigger.h"
#include "parser/ast/sqlitecreateview.h"
#include "parser/ast/sqlitecreatevirtualtable.h"
class CfgMain;
/**
* @brief Provides support for particular export format.
*
* All export methods in this class should report any warnings, error messages, etc through the NotifyManager,
* that is by using notifyError() and its family methods.
*/
class ExportPlugin : virtual public Plugin
{
public:
/**
* @brief Provides name of the format that the plugin exports to.
* @return Format name that will be displayed on UI.
*
* Format must be a single word name.
*/
virtual QString getFormatName() const = 0;
/**
* @brief Tells what standard exporting options should be displayed to the user on UI.
* @return OR-ed set of option enum values.
*/
virtual ExportManager::StandardConfigFlags standardOptionsToEnable() const = 0;
/**
* @brief Tells which character encoding use by default in export dialog.
* @return Name of the encoding.
*
* If the plugin doesn't return ExportManager::CODEC in results from standardOptionsToEnable(), then result
* of this function is ignored and it can return null string.
*/
virtual QString getDefaultEncoding() const = 0;
/**
* @brief Provides set of modes supported by this export plugin.
* @return OR-ed set of supported modes.
*
* Some export plugins might not support some of exporting modes. For example CSV export plugin
* will not support DATABASE exporting, because CSV cannot represent schema of the database.
*
* If a plugin doesn't return some mode in this method, then that plugin will be excluded
* from list of available formats to export, when user requests to export in this mode.
*/
virtual ExportManager::ExportModes getSupportedModes() const = 0;
/**
* @brief Provides set of flags for additional information that needs to be provided for this plugin.
* @return OR-ed set of flags.
*
* Some plugins might need to know what is a total number of rows that are expected to be
* exported for each table or query results. Other plugins might want to know
* what is the maximum number of characters/bytes in each exported table column,
* so they can calculate column widths when drawing them in the exported files, documents, etc.
*
* Those additional information are not provided by default, because they are gathered with extra queries
* to the database and for huge tables it might cause the table to be exported much longer, even if
* those information wasn't required by some plugin.
*
* See ExportManager::ExportProviderFlags for list of possible flags and what they mean.
*/
virtual ExportManager::ExportProviderFlags getProviderFlags() const = 0;
/**
* @brief Provides config object that holds configuration for exporting.
* @return Config object, or null if the exporting with this plugin is not configurable.
*/
virtual CfgMain* getConfig() = 0;
/**
* @brief Provides name of the form to use for configuration of exporting in given mode.
* @param mode Mode for which the form is requested for.
* @return Name of the form (toplevel QWidget in the ui file).
*
* If exporting with this plugin is not configurable (i.e. getConfig() returns null),
* then this method is not even called, so it can return anything, just to satisfy method
* return type. In that case good idea is to always return QString().
*
* @see FormManager
*/
virtual QString getExportConfigFormName() const = 0;
/**
* @brief Tells plugin what is going to be the next export mode.
* @param mode Mode that the next export is going to be performed for.
*
* Plugin should remember this and use later when some logic is depended on what the mode is.
* For example getConfigFormName() (as well as getConfig()) might return different config forms
* for different modes.
*/
virtual void setExportMode(ExportManager::ExportMode mode) = 0;
/**
* @brief Called when the UI expects any configuration options to be re-validated.
*
* When user interacts with the UI in a way that it doesn't change the config values,
* but it still requires some options to be re-validated, this method is called.
*
* It should validate any configuration values defined with CFG_CATEGORY and CFG_ENTRY
* and post the validation results by calling EXPORT_MANAGER->handleValidationFromPlugin()
* for every validated CfgEntry.
*
* This is also a good idea to connect to the CfgEntry::changed() signal for entries that should be validated
* and call this method from the slot, so any changes to the configuration values will be
* immediately validated and reflected on the UI.
*/
virtual void validateOptions() = 0;
/**
* @brief Provides usual file name extension used with this format.
* @return File name extension (like ".csv").
*
* This extension will be automatically appended to file name when user picked file name
* with file dialog, but the file extension part in the selected file was ommited.
*/
virtual QString defaultFileExtension() const = 0;
/**
* @brief Mime type for when exporting binary format to clipboard.
* @return Mime type, like "image/png".
*
* Value returned from this method is used to set mime type when the exporting is done into the system clipboard.
* The clipboard needs mime type to identify what kind of data is in it.
*
* See details http://qt-project.org/doc/qt-5/qmimedata.html#setData
*
* If the plugin exports just a string, then this method can return QString() and SqliteStudio will assume
* that the data is of "text/plain" type.
*/
virtual QString getMimeType() const = 0;
/**
* @brief Tells if the data being exported is a binary or text.
* @return true for binary data, false for textual data.
*
* This is used by the SQLiteStudio to configure output device properly. For example CSV format is textual,
* but PNG is considered binary.
*/
virtual bool isBinaryData() const = 0;
/**
* @brief Provides common state values before the export process begins.
* @param db Database that the export will be performed on.
* @param output Output device to write exporting data to.
* @param config Common exporting configuration, like file name, codec, etc.
* @return true for success, or false in case of a fatal error.
*
* This is called exactly once before every export process (that is once per each export called by user).
* Use it to remember database, output device, config for further method calls, or write a file header.
* This method will be followed by any of *export*() methods from this interface.
*
* There's a convenient class GenericExportPlugin, which you can extend instead of ExportPlugin. If you use
* GenericExportPlugin for a base class of exprt plugin, then this method is already implemented there
* and it stores all these parameters in protected class members so you can use them in other methods.
*/
virtual bool initBeforeExport(Db* db, QIODevice* output, const ExportManager::StandardExportConfig& config) = 0;
/**
* @brief Does initial entry for exported query results.
* @param query Query that was executed to get the results.
* @param columns Columns returned from the query.
* @param providedData All data entries requested by the plugin in the return value of getProviderFlags().
* @return true for success, or false in case of a fatal error.
*
* It's called just before actual data entries are exported (with exportQueryResultsRow()).
* It's called exactly once for single query results export.
*/
virtual bool beforeExportQueryResults(const QString& query, QList<QueryExecutor::ResultColumnPtr>& columns,
const QHash<ExportManager::ExportProviderFlag,QVariant> providedData) = 0;
/**
* @brief Does export entry for a single row of data.
* @param row Single data row.
* @return true for success, or false in case of a fatal error.
*
* It's called for each data row returned from the query.
*/
virtual bool exportQueryResultsRow(SqlResultsRowPtr row) = 0;
/**
* @brief Does final entry for exported query results.
* @return true for success, or false in case of a fatal error.
*
* It's called once after all data from the query was exported.
*/
virtual bool afterExportQueryResults() = 0;
/**
* @brief Prepares for exporting tables from database.
* @return true for success, or false in case of a fatal error.
*
* This is called only for database export. For single table export only exportTable() is called.
*/
virtual bool beforeExportTables() = 0;
/**
* @brief Does initial entry for exported table.
* @param database "Attach" name of the database that the table belongs to. Can be "main", "temp", or any attach name.
* @param table Name of the table to export.
* @param columnNames Name of columns in the table, in order they will appear in the rows passed to exportTableRow().
* @param ddl The DDL of the table.
* @param createTable Table DDL parsed into an object.
* @param providedData All data entries requested by the plugin in the return value of getProviderFlags().
* @return true for success, or false in case of a fatal error.
*/
virtual bool exportTable(const QString& database, const QString& table, const QStringList& columnNames, const QString& ddl, SqliteCreateTablePtr createTable,
const QHash<ExportManager::ExportProviderFlag,QVariant> providedData) = 0;
/**
* @brief Does initial entry for exported virtual table.
* @param database "Attach" name of the database that the table belongs to. Can be "main", "temp", or any attach name.
* @param table Name of the table to export.
* @param columnNames Name of columns in the table, in order they will appear in the rows passed to exportTableRow().
* This will be empty if data is not being exported. This is different than for exportTable(), where columnNames are always present.
* @param ddl The DDL of the table.
* @param createTable Table DDL parsed into an object.
* @param providedData All data entries requested by the plugin in the return value of getProviderFlags().
* @return true for success, or false in case of a fatal error.
*/
virtual bool exportVirtualTable(const QString& database, const QString& table, const QStringList& columnNames, const QString& ddl,
SqliteCreateVirtualTablePtr createTable, const QHash<ExportManager::ExportProviderFlag,QVariant> providedData) = 0;
/**
* @brief Does export entry for a single row of data.
* @param data Single data row.
* @return true for success, or false in case of a fatal error.
*
* This method will be called only if StandardExportConfig::exportData in initBeforeExport() was true.
*/
virtual bool exportTableRow(SqlResultsRowPtr data) = 0;
/**
* @brief Does final entry for exported table, after its data was exported.
* @return true for success, or false in case of a fatal error.
*/
virtual bool afterExportTable() = 0;
/**
* @brief Does final entries after all tables have been exported.
* @return true for success, or false in case of a fatal error.
*
* This is called only for database export. For single table export only exportTable() is called.
* After table exporting also an afterExport() is called, so you can use that for any postprocessing.
*/
virtual bool afterExportTables() = 0;
/**
* @brief Does initial entry for the entire database export.
* @param database Database name (as listed in database list).
* @return true for success, or false in case of a fatal error.
*
* It's called just once, before each database object gets exported.
* This method will be followed by calls to (in this order): beforeExportTables(), exportTable(), exportVirtualTable(), exportTableRow(), afterExportTable(),
* afterExportTables(), beforeExportIndexes(), exportIndex(), afterExportIndexes(), beforeExportTriggers(), exportTrigger(), afterExportTriggers(),
* beforeExportViews(), exportView(), afterExportViews() and afterExportDatabase().
* Note, that exportTableRow() will be called only if StandardExportConfig::exportData in initBeforeExport() was true.
*/
virtual bool beforeExportDatabase(const QString& database) = 0;
/**
* @brief Prepares for exporting indexes from database.
* @return true for success, or false in case of a fatal error.
*/
virtual bool beforeExportIndexes() = 0;
/**
* @brief Does entire export entry for an index.
* @param database "Attach" name of the database that the index belongs to. Can be "main", "temp", or any attach name.
* @param table Name of the index to export.
* @param ddl The DDL of the index.
* @param createIndex Index DDL parsed into an object.
* @return true for success, or false in case of a fatal error.
*
* This is the only method called for index export.
*/
virtual bool exportIndex(const QString& database, const QString& name, const QString& ddl, SqliteCreateIndexPtr createIndex) = 0;
/**
* @brief Does final entries after all indexes have been exported.
* @return true for success, or false in case of a fatal error.
*/
virtual bool afterExportIndexes() = 0;
/**
* @brief Prepares for exporting triggers from database.
* @return true for success, or false in case of a fatal error.
*/
virtual bool beforeExportTriggers() = 0;
/**
* @brief Does entire export entry for an trigger.
* @param database "Attach" name of the database that the trigger belongs to. Can be "main", "temp", or any attach name.
* @param table Name of the trigger to export.
* @param ddl The DDL of the trigger.
* @param createTrigger Trigger DDL parsed into an object.
* @return true for success, or false in case of a fatal error.
*
* This is the only method called for trigger export.
*/
virtual bool exportTrigger(const QString& database, const QString& name, const QString& ddl, SqliteCreateTriggerPtr createTrigger) = 0;
/**
* @brief Does final entries after all triggers have been exported.
* @return true for success, or false in case of a fatal error.
*/
virtual bool afterExportTriggers() = 0;
/**
* @brief Prepares for exporting views from database.
* @return true for success, or false in case of a fatal error.
*/
virtual bool beforeExportViews() = 0;
/**
* @brief Does entire export entry for an view.
* @param database "Attach" name of the database that the view belongs to. Can be "main", "temp", or any attach name.
* @param table Name of the trigger to view.
* @param ddl The DDL of the view.
* @param createView View DDL parsed into an object.
* @return true for success, or false in case of a fatal error.
*
* This is the only method called for view export.
*/
virtual bool exportView(const QString& database, const QString& name, const QString& ddl, SqliteCreateViewPtr view) = 0;
/**
* @brief Does final entries after all views have been exported.
* @return true for success, or false in case of a fatal error.
*/
virtual bool afterExportViews() = 0;
/**
* @brief Does final entry for the entire database export.
* @return true for success, or false in case of a fatal error.
*
* It's called just once, after all database object get exported.
*/
virtual bool afterExportDatabase() = 0;
/**
* @brief Does final entry for any export process.
* @return true for success, or false in case of a fatal error.
*
* This is similar to afterExportDatabase() when the export mode is database,
* but this is called at the end for any export mode, not only for database export.
*
* Use it to write a footer, or anything like that.
*/
virtual bool afterExport() = 0;
/**
* @brief Called after every export, even failed one.
*
* Implementation of this method should cleanup any resources used during each single export process.
* This method is guaranteed to be executed, no matter if export was successful or not.
*/
virtual void cleanupAfterExport() = 0;
};
#endif // EXPORTPLUGIN_H
|