25 # TODO: add a submenu with action for the commands with command options |
25 # TODO: add a submenu with action for the commands with command options |
26 class MigrateProject(QObject): |
26 class MigrateProject(QObject): |
27 """ |
27 """ |
28 Class implementing the flask-migrate project support. |
28 Class implementing the flask-migrate project support. |
29 """ |
29 """ |
|
30 |
30 def __init__(self, plugin, project, parent=None): |
31 def __init__(self, plugin, project, parent=None): |
31 """ |
32 """ |
32 Constructor |
33 Constructor |
33 |
34 |
34 @param plugin reference to the plugin object |
35 @param plugin reference to the plugin object |
35 @type ProjectFlaskPlugin |
36 @type ProjectFlaskPlugin |
36 @param project reference to the project object |
37 @param project reference to the project object |
37 @type Project |
38 @type Project |
38 @param parent parent |
39 @param parent parent |
39 @type QObject |
40 @type QObject |
40 """ |
41 """ |
41 super().__init__(parent) |
42 super().__init__(parent) |
42 |
43 |
43 self.__plugin = plugin |
44 self.__plugin = plugin |
44 self.__project = project |
45 self.__project = project |
45 |
46 |
46 self.__ericProject = ericApp().getObject("Project") |
47 self.__ericProject = ericApp().getObject("Project") |
47 |
48 |
48 self.__migrationSummaryDialog = None |
49 self.__migrationSummaryDialog = None |
49 |
50 |
50 def initActions(self): |
51 def initActions(self): |
51 """ |
52 """ |
52 Public method to define the flask-migrate actions. |
53 Public method to define the flask-migrate actions. |
53 """ |
54 """ |
54 self.actions = [] |
55 self.actions = [] |
55 |
56 |
56 self.migrateConfigAct = EricAction( |
57 self.migrateConfigAct = EricAction( |
57 self.tr('Configure Migrate'), |
58 self.tr("Configure Migrate"), |
58 self.tr('C&onfigure Migrate'), |
59 self.tr("C&onfigure Migrate"), |
59 0, 0, |
60 0, |
60 self, 'flask_config_migrate') |
61 0, |
61 self.migrateConfigAct.setStatusTip(self.tr( |
62 self, |
62 'Shows a dialog to edit the configuration for flask-migrate')) |
63 "flask_config_migrate", |
63 self.migrateConfigAct.setWhatsThis(self.tr( |
64 ) |
64 """<b>Configure Migrate</b>""" |
65 self.migrateConfigAct.setStatusTip( |
65 """<p>Shows a dialog to edit the configuration for""" |
66 self.tr("Shows a dialog to edit the configuration for flask-migrate") |
66 """ flask-migrate.</p>""" |
67 ) |
67 )) |
68 self.migrateConfigAct.setWhatsThis( |
68 self.migrateConfigAct.triggered.connect( |
69 self.tr( |
69 self.__configureMigrate) |
70 """<b>Configure Migrate</b>""" |
|
71 """<p>Shows a dialog to edit the configuration for""" |
|
72 """ flask-migrate.</p>""" |
|
73 ) |
|
74 ) |
|
75 self.migrateConfigAct.triggered.connect(self.__configureMigrate) |
70 self.actions.append(self.migrateConfigAct) |
76 self.actions.append(self.migrateConfigAct) |
71 |
77 |
72 self.migrateInstallAct = EricAction( |
78 self.migrateInstallAct = EricAction( |
73 self.tr('Install flask-migrate'), |
79 self.tr("Install flask-migrate"), |
74 self.tr('Install &flask-migrate'), |
80 self.tr("Install &flask-migrate"), |
75 0, 0, |
81 0, |
76 self, 'flask_install_migrate') |
82 0, |
77 self.migrateInstallAct.setStatusTip(self.tr( |
83 self, |
78 'Installs the flask-migrate extension into the configured' |
84 "flask_install_migrate", |
79 ' environment')) |
85 ) |
80 self.migrateInstallAct.setWhatsThis(self.tr( |
86 self.migrateInstallAct.setStatusTip( |
81 """<b>Install flask-migrate</b>""" |
87 self.tr( |
82 """<p>Installs the flask-migrate extension into the configured""" |
88 "Installs the flask-migrate extension into the configured" |
83 """ environment using the pip interface.</p>""" |
89 " environment" |
84 )) |
90 ) |
85 self.migrateInstallAct.triggered.connect( |
91 ) |
86 self.__installFlaskMigrate) |
92 self.migrateInstallAct.setWhatsThis( |
|
93 self.tr( |
|
94 """<b>Install flask-migrate</b>""" |
|
95 """<p>Installs the flask-migrate extension into the configured""" |
|
96 """ environment using the pip interface.</p>""" |
|
97 ) |
|
98 ) |
|
99 self.migrateInstallAct.triggered.connect(self.__installFlaskMigrate) |
87 self.actions.append(self.migrateInstallAct) |
100 self.actions.append(self.migrateInstallAct) |
88 |
101 |
89 self.migrateAvailabilityAct = EricAction( |
102 self.migrateAvailabilityAct = EricAction( |
90 self.tr('Check flask-migrate Availability'), |
103 self.tr("Check flask-migrate Availability"), |
91 self.tr('Check flask-migrate &Availability'), |
104 self.tr("Check flask-migrate &Availability"), |
92 0, 0, |
105 0, |
93 self, 'flask_check_migrate') |
106 0, |
94 self.migrateAvailabilityAct.setStatusTip(self.tr( |
107 self, |
95 'Check the availability of the flask-migrate extension')) |
108 "flask_check_migrate", |
96 self.migrateAvailabilityAct.setWhatsThis(self.tr( |
109 ) |
97 """<b>Check flask-migrate Availability</b>""" |
110 self.migrateAvailabilityAct.setStatusTip( |
98 """<p>Check the availability of the flask-migrate extension.</p>""" |
111 self.tr("Check the availability of the flask-migrate extension") |
99 )) |
112 ) |
100 self.migrateAvailabilityAct.triggered.connect( |
113 self.migrateAvailabilityAct.setWhatsThis( |
101 self.__checkAvailability) |
114 self.tr( |
|
115 """<b>Check flask-migrate Availability</b>""" |
|
116 """<p>Check the availability of the flask-migrate extension.</p>""" |
|
117 ) |
|
118 ) |
|
119 self.migrateAvailabilityAct.triggered.connect(self.__checkAvailability) |
102 self.actions.append(self.migrateAvailabilityAct) |
120 self.actions.append(self.migrateAvailabilityAct) |
103 |
121 |
104 ######################################################### |
122 ######################################################### |
105 ## action to initialize the database migration system |
123 ## action to initialize the database migration system |
106 ######################################################### |
124 ######################################################### |
107 |
125 |
108 self.migrateInitAct = EricAction( |
126 self.migrateInitAct = EricAction( |
109 self.tr('Initialize Migrations'), |
127 self.tr("Initialize Migrations"), |
110 self.tr('&Initialize Migrations'), |
128 self.tr("&Initialize Migrations"), |
111 0, 0, |
129 0, |
112 self, 'flask_init_migrations') |
130 0, |
113 self.migrateInitAct.setStatusTip(self.tr( |
131 self, |
114 'Initialize support for database migrations')) |
132 "flask_init_migrations", |
115 self.migrateInitAct.setWhatsThis(self.tr( |
133 ) |
116 """<b>Initialize Migrations</b>""" |
134 self.migrateInitAct.setStatusTip( |
117 """<p>Initializes the support for database migrations to be""" |
135 self.tr("Initialize support for database migrations") |
118 """ stored in the configured migrations directory.</p>""" |
136 ) |
119 )) |
137 self.migrateInitAct.setWhatsThis( |
120 self.migrateInitAct.triggered.connect( |
138 self.tr( |
121 self.__initMigrations) |
139 """<b>Initialize Migrations</b>""" |
|
140 """<p>Initializes the support for database migrations to be""" |
|
141 """ stored in the configured migrations directory.</p>""" |
|
142 ) |
|
143 ) |
|
144 self.migrateInitAct.triggered.connect(self.__initMigrations) |
122 self.actions.append(self.migrateInitAct) |
145 self.actions.append(self.migrateInitAct) |
123 |
146 |
124 ######################################################### |
147 ######################################################### |
125 ## action to create a new database migration |
148 ## action to create a new database migration |
126 ######################################################### |
149 ######################################################### |
127 |
150 |
128 self.migrateCreateAct = EricAction( |
151 self.migrateCreateAct = EricAction( |
129 self.tr('Create Migration'), |
152 self.tr("Create Migration"), |
130 self.tr('&Create Migration'), |
153 self.tr("&Create Migration"), |
131 0, 0, |
154 0, |
132 self, 'flask_create_migration') |
155 0, |
133 self.migrateCreateAct.setStatusTip(self.tr( |
156 self, |
134 'Create a new migration for the current database')) |
157 "flask_create_migration", |
135 self.migrateCreateAct.setWhatsThis(self.tr( |
158 ) |
136 """<b>Create Migration</b>""" |
159 self.migrateCreateAct.setStatusTip( |
137 """<p>Creates a new migration for the current database""" |
160 self.tr("Create a new migration for the current database") |
138 """ and stores it in the configured migrations directory.</p>""" |
161 ) |
139 )) |
162 self.migrateCreateAct.setWhatsThis( |
140 self.migrateCreateAct.triggered.connect( |
163 self.tr( |
141 self.__createMigration) |
164 """<b>Create Migration</b>""" |
|
165 """<p>Creates a new migration for the current database""" |
|
166 """ and stores it in the configured migrations directory.</p>""" |
|
167 ) |
|
168 ) |
|
169 self.migrateCreateAct.triggered.connect(self.__createMigration) |
142 self.actions.append(self.migrateCreateAct) |
170 self.actions.append(self.migrateCreateAct) |
143 |
171 |
144 ######################################################### |
172 ######################################################### |
145 ## action to up- and downgrade a databse |
173 ## action to up- and downgrade a databse |
146 ######################################################### |
174 ######################################################### |
147 |
175 |
148 self.upgradeDatabaseAct = EricAction( |
176 self.upgradeDatabaseAct = EricAction( |
149 self.tr('Upgrade Database'), |
177 self.tr("Upgrade Database"), |
150 self.tr('&Upgrade Database'), |
178 self.tr("&Upgrade Database"), |
151 0, 0, |
179 0, |
152 self, 'flask_upgrade_database') |
180 0, |
153 self.upgradeDatabaseAct.setStatusTip(self.tr( |
181 self, |
154 'Upgrade the database to the current migration')) |
182 "flask_upgrade_database", |
155 self.upgradeDatabaseAct.setWhatsThis(self.tr( |
183 ) |
156 """<b>Upgrade Database</b>""" |
184 self.upgradeDatabaseAct.setStatusTip( |
157 """<p>Upgrades the database to the current migration.</p>""" |
185 self.tr("Upgrade the database to the current migration") |
158 )) |
186 ) |
159 self.upgradeDatabaseAct.triggered.connect( |
187 self.upgradeDatabaseAct.setWhatsThis( |
160 self.upgradeDatabase) |
188 self.tr( |
|
189 """<b>Upgrade Database</b>""" |
|
190 """<p>Upgrades the database to the current migration.</p>""" |
|
191 ) |
|
192 ) |
|
193 self.upgradeDatabaseAct.triggered.connect(self.upgradeDatabase) |
161 self.actions.append(self.upgradeDatabaseAct) |
194 self.actions.append(self.upgradeDatabaseAct) |
162 |
195 |
163 self.downgradeDatabaseAct = EricAction( |
196 self.downgradeDatabaseAct = EricAction( |
164 self.tr('Downgrade Database'), |
197 self.tr("Downgrade Database"), |
165 self.tr('&Downgrade Database'), |
198 self.tr("&Downgrade Database"), |
166 0, 0, |
199 0, |
167 self, 'flask_downgrade_database') |
200 0, |
168 self.downgradeDatabaseAct.setStatusTip(self.tr( |
201 self, |
169 'Downgrade the database to the previous version')) |
202 "flask_downgrade_database", |
170 self.downgradeDatabaseAct.setWhatsThis(self.tr( |
203 ) |
171 """<b>Downgrade Database</b>""" |
204 self.downgradeDatabaseAct.setStatusTip( |
172 """<p>Downgrades the database to the previous version.</p>""" |
205 self.tr("Downgrade the database to the previous version") |
173 )) |
206 ) |
174 self.downgradeDatabaseAct.triggered.connect( |
207 self.downgradeDatabaseAct.setWhatsThis( |
175 self.downgradeDatabase) |
208 self.tr( |
|
209 """<b>Downgrade Database</b>""" |
|
210 """<p>Downgrades the database to the previous version.</p>""" |
|
211 ) |
|
212 ) |
|
213 self.downgradeDatabaseAct.triggered.connect(self.downgradeDatabase) |
176 self.actions.append(self.downgradeDatabaseAct) |
214 self.actions.append(self.downgradeDatabaseAct) |
177 |
215 |
178 ######################################################### |
216 ######################################################### |
179 ## actions to show migrations history information |
217 ## actions to show migrations history information |
180 ######################################################### |
218 ######################################################### |
181 |
219 |
182 self.migrationSummaryAct = EricAction( |
220 self.migrationSummaryAct = EricAction( |
183 self.tr('Show Migrations Summary'), |
221 self.tr("Show Migrations Summary"), |
184 self.tr('Show Migrations &Summary'), |
222 self.tr("Show Migrations &Summary"), |
185 0, 0, |
223 0, |
186 self, 'flask_show_migrations_summary') |
224 0, |
187 self.migrationSummaryAct.setStatusTip(self.tr( |
225 self, |
188 'Show a summary of the created database migrations')) |
226 "flask_show_migrations_summary", |
189 self.migrationSummaryAct.setWhatsThis(self.tr( |
227 ) |
190 """<b>Show Migrations Summary</b>""" |
228 self.migrationSummaryAct.setStatusTip( |
191 """<p>Shows a summary list of the created database""" |
229 self.tr("Show a summary of the created database migrations") |
192 """ migrations.</p>""" |
230 ) |
193 )) |
231 self.migrationSummaryAct.setWhatsThis( |
194 self.migrationSummaryAct.triggered.connect( |
232 self.tr( |
195 self.__showMigrationsSummary) |
233 """<b>Show Migrations Summary</b>""" |
|
234 """<p>Shows a summary list of the created database""" |
|
235 """ migrations.</p>""" |
|
236 ) |
|
237 ) |
|
238 self.migrationSummaryAct.triggered.connect(self.__showMigrationsSummary) |
196 self.actions.append(self.migrationSummaryAct) |
239 self.actions.append(self.migrationSummaryAct) |
197 |
240 |
198 self.migrationHistoryAct = EricAction( |
241 self.migrationHistoryAct = EricAction( |
199 self.tr('Show Migrations History'), |
242 self.tr("Show Migrations History"), |
200 self.tr('Show Migrations &History'), |
243 self.tr("Show Migrations &History"), |
201 0, 0, |
244 0, |
202 self, 'flask_show_migrations_history') |
245 0, |
203 self.migrationHistoryAct.setStatusTip(self.tr( |
246 self, |
204 'Show the full history of the created database migrations')) |
247 "flask_show_migrations_history", |
205 self.migrationHistoryAct.setWhatsThis(self.tr( |
248 ) |
206 """<b>Show Migrations History</b>""" |
249 self.migrationHistoryAct.setStatusTip( |
207 """<p>Shows the full history of the created database""" |
250 self.tr("Show the full history of the created database migrations") |
208 """ migrations.</p>""" |
251 ) |
209 )) |
252 self.migrationHistoryAct.setWhatsThis( |
210 self.migrationHistoryAct.triggered.connect( |
253 self.tr( |
211 self.__showMigrationsHistory) |
254 """<b>Show Migrations History</b>""" |
|
255 """<p>Shows the full history of the created database""" |
|
256 """ migrations.</p>""" |
|
257 ) |
|
258 ) |
|
259 self.migrationHistoryAct.triggered.connect(self.__showMigrationsHistory) |
212 self.actions.append(self.migrationHistoryAct) |
260 self.actions.append(self.migrationHistoryAct) |
213 |
261 |
214 def initMenu(self): |
262 def initMenu(self): |
215 """ |
263 """ |
216 Public method to initialize the flask-migrate menu. |
264 Public method to initialize the flask-migrate menu. |
217 |
265 |
218 @return the menu generated |
266 @return the menu generated |
219 @rtype QMenu |
267 @rtype QMenu |
220 """ |
268 """ |
221 menu = QMenu(self.tr("Database")) |
269 menu = QMenu(self.tr("Database")) |
222 menu.setTearOffEnabled(True) |
270 menu.setTearOffEnabled(True) |
223 |
271 |
224 menu.addAction(self.migrateConfigAct) |
272 menu.addAction(self.migrateConfigAct) |
225 menu.addSeparator() |
273 menu.addSeparator() |
226 menu.addAction(self.migrateInitAct) |
274 menu.addAction(self.migrateInitAct) |
227 menu.addSeparator() |
275 menu.addSeparator() |
228 menu.addAction(self.migrateCreateAct) |
276 menu.addAction(self.migrateCreateAct) |
233 menu.addAction(self.migrationSummaryAct) |
281 menu.addAction(self.migrationSummaryAct) |
234 menu.addAction(self.migrationHistoryAct) |
282 menu.addAction(self.migrationHistoryAct) |
235 menu.addSeparator() |
283 menu.addSeparator() |
236 menu.addAction(self.migrateAvailabilityAct) |
284 menu.addAction(self.migrateAvailabilityAct) |
237 menu.addAction(self.migrateInstallAct) |
285 menu.addAction(self.migrateInstallAct) |
238 |
286 |
239 return menu |
287 return menu |
240 |
288 |
241 def determineCapability(self): |
289 def determineCapability(self): |
242 """ |
290 """ |
243 Public method to determine the availability of flask-migrate. |
291 Public method to determine the availability of flask-migrate. |
244 """ |
292 """ |
245 available = ( |
293 available = ( |
246 self.__project.getData("flask", "flask_migrate_available") |
294 self.__project.getData("flask", "flask_migrate_available") |
247 if self.__project.getData("flask", "flask_migrate_override") else |
295 if self.__project.getData("flask", "flask_migrate_override") |
248 self.__flaskMigrateAvailable() |
296 else self.__flaskMigrateAvailable() |
249 ) |
297 ) |
250 self.__project.setCapability("flask-migrate", available) |
298 self.__project.setCapability("flask-migrate", available) |
251 |
299 |
252 self.migrateInstallAct.setEnabled(not available) |
300 self.migrateInstallAct.setEnabled(not available) |
253 |
301 |
254 for act in ( |
302 for act in ( |
255 self.migrateConfigAct, self.migrateInitAct, |
303 self.migrateConfigAct, |
|
304 self.migrateInitAct, |
256 self.migrateCreateAct, |
305 self.migrateCreateAct, |
257 self.upgradeDatabaseAct, self.downgradeDatabaseAct, |
306 self.upgradeDatabaseAct, |
258 self.migrationSummaryAct, self.migrationHistoryAct, |
307 self.downgradeDatabaseAct, |
|
308 self.migrationSummaryAct, |
|
309 self.migrationHistoryAct, |
259 ): |
310 ): |
260 act.setEnabled(available) |
311 act.setEnabled(available) |
261 |
312 |
262 def __flaskMigrateAvailable(self): |
313 def __flaskMigrateAvailable(self): |
263 """ |
314 """ |
264 Private method to check, if the 'flask-babel' package is available. |
315 Private method to check, if the 'flask-babel' package is available. |
265 |
316 |
266 @return flag indicating the availability of 'flask-babel' |
317 @return flag indicating the availability of 'flask-babel' |
267 @rtype bool |
318 @rtype bool |
268 """ |
319 """ |
269 interpreter = self.__project.getVirtualenvInterpreter() |
320 interpreter = self.__project.getVirtualenvInterpreter() |
270 if interpreter and Utilities.isinpath(interpreter): |
321 if interpreter and Utilities.isinpath(interpreter): |
271 detector = os.path.join( |
322 detector = os.path.join( |
272 os.path.dirname(__file__), "FlaskMigrateDetector.py") |
323 os.path.dirname(__file__), "FlaskMigrateDetector.py" |
|
324 ) |
273 proc = QProcess() |
325 proc = QProcess() |
274 proc.setProcessChannelMode( |
326 proc.setProcessChannelMode(QProcess.ProcessChannelMode.MergedChannels) |
275 QProcess.ProcessChannelMode.MergedChannels) |
|
276 proc.start(interpreter, [detector]) |
327 proc.start(interpreter, [detector]) |
277 finished = proc.waitForFinished(30000) |
328 finished = proc.waitForFinished(30000) |
278 if finished and proc.exitCode() == 0: |
329 if finished and proc.exitCode() == 0: |
279 return True |
330 return True |
280 |
331 |
281 return False |
332 return False |
282 |
333 |
283 def __migrationsDirectory(self, abspath=False): |
334 def __migrationsDirectory(self, abspath=False): |
284 """ |
335 """ |
285 Private method to calculate the path of the configured migrations |
336 Private method to calculate the path of the configured migrations |
286 directory. |
337 directory. |
287 |
338 |
288 @param abspath flag indicating to return an absolute path |
339 @param abspath flag indicating to return an absolute path |
289 @type bool |
340 @type bool |
290 @return path of the migrations directory |
341 @return path of the migrations directory |
291 @rtype str |
342 @rtype str |
292 """ |
343 """ |
293 migrations = "" |
344 migrations = "" |
294 |
345 |
295 self.__ensureMigrateConfigured() |
346 self.__ensureMigrateConfigured() |
296 |
347 |
297 migrations = self.__project.getData("flask-migrate", |
348 migrations = self.__project.getData("flask-migrate", "migrationsDirectory") |
298 "migrationsDirectory") |
|
299 if migrations: |
349 if migrations: |
300 if abspath: |
350 if abspath: |
301 migrations = self.__ericProject.getAbsoluteUniversalPath( |
351 migrations = self.__ericProject.getAbsoluteUniversalPath(migrations) |
302 migrations) |
|
303 else: |
352 else: |
304 workdir = self.__project.getApplication()[0] |
353 workdir = self.__project.getApplication()[0] |
305 migrations = os.path.relpath( |
354 migrations = os.path.relpath( |
306 self.__ericProject.getAbsoluteUniversalPath(migrations), |
355 self.__ericProject.getAbsoluteUniversalPath(migrations), workdir |
307 workdir |
|
308 ) |
356 ) |
309 else: |
357 else: |
310 if abspath: |
358 if abspath: |
311 migrations = self.__ericProject.getAbsoluteUniversalPath( |
359 migrations = self.__ericProject.getAbsoluteUniversalPath("migrations") |
312 "migrations") |
360 |
313 |
|
314 return migrations |
361 return migrations |
315 |
362 |
316 def projectClosed(self): |
363 def projectClosed(self): |
317 """ |
364 """ |
318 Public method to handle the closing of a project. |
365 Public method to handle the closing of a project. |
319 """ |
366 """ |
320 for dlg in (self.__migrationSummaryDialog,): |
367 for dlg in (self.__migrationSummaryDialog,): |
321 if dlg is not None: |
368 if dlg is not None: |
322 dlg.close() |
369 dlg.close() |
323 |
370 |
324 ######################################################## |
371 ######################################################## |
325 ## Menu related slots below |
372 ## Menu related slots below |
326 ######################################################## |
373 ######################################################## |
327 |
374 |
328 @pyqtSlot() |
375 @pyqtSlot() |
329 def __configureMigrate(self): |
376 def __configureMigrate(self): |
330 """ |
377 """ |
331 Private slot to show a dialog to edit the migrate configuration. |
378 Private slot to show a dialog to edit the migrate configuration. |
332 """ |
379 """ |
333 from .MigrateConfigDialog import MigrateConfigDialog |
380 from .MigrateConfigDialog import MigrateConfigDialog |
334 |
381 |
335 config = self.__project.getData("flask-migrate", "") |
382 config = self.__project.getData("flask-migrate", "") |
336 dlg = MigrateConfigDialog(config) |
383 dlg = MigrateConfigDialog(config) |
337 if dlg.exec() == QDialog.DialogCode.Accepted: |
384 if dlg.exec() == QDialog.DialogCode.Accepted: |
338 config = dlg.getConfiguration() |
385 config = dlg.getConfiguration() |
339 self.__project.setData("flask-migrate", "", config) |
386 self.__project.setData("flask-migrate", "", config) |
340 |
387 |
341 def __ensureMigrateConfigured(self): |
388 def __ensureMigrateConfigured(self): |
342 """ |
389 """ |
343 Private method to ensure, that flask-migrate has been configured. |
390 Private method to ensure, that flask-migrate has been configured. |
344 """ |
391 """ |
345 config = self.__project.getData("flask-migrate", "") |
392 config = self.__project.getData("flask-migrate", "") |
346 if not config: |
393 if not config: |
347 self.__configureMigrate() |
394 self.__configureMigrate() |
348 |
395 |
349 @pyqtSlot() |
396 @pyqtSlot() |
350 def __installFlaskMigrate(self): |
397 def __installFlaskMigrate(self): |
351 """ |
398 """ |
352 Private slot to install the flask-migrate extension into the configured |
399 Private slot to install the flask-migrate extension into the configured |
353 environment. |
400 environment. |
360 self.determineCapability() |
407 self.determineCapability() |
361 else: |
408 else: |
362 EricMessageBox.critical( |
409 EricMessageBox.critical( |
363 None, |
410 None, |
364 self.tr("Install flask-migrate"), |
411 self.tr("Install flask-migrate"), |
365 self.tr("The 'flask-migrate' extension could not be installed" |
412 self.tr( |
366 " because no virtual environment has been" |
413 "The 'flask-migrate' extension could not be installed" |
367 " configured.")) |
414 " because no virtual environment has been" |
368 |
415 " configured." |
|
416 ), |
|
417 ) |
|
418 |
369 @pyqtSlot() |
419 @pyqtSlot() |
370 def __checkAvailability(self): |
420 def __checkAvailability(self): |
371 """ |
421 """ |
372 Private slot to check the availability of the 'flask-babel' extension. |
422 Private slot to check the availability of the 'flask-babel' extension. |
373 """ |
423 """ |
374 self.determineCapability() |
424 self.determineCapability() |
375 msg = ( |
425 msg = ( |
376 self.tr("The 'flask-migrate' extension is installed.") |
426 self.tr("The 'flask-migrate' extension is installed.") |
377 if self.__project.hasCapability("flask-migrate") else |
427 if self.__project.hasCapability("flask-migrate") |
378 self.tr("The 'flask-migrate' extension is not installed.") |
428 else self.tr("The 'flask-migrate' extension is not installed.") |
379 ) |
429 ) |
380 EricMessageBox.information( |
430 EricMessageBox.information(None, self.tr("flask-migrate Availability"), msg) |
381 None, |
431 |
382 self.tr("flask-migrate Availability"), |
|
383 msg) |
|
384 |
|
385 ######################################################### |
432 ######################################################### |
386 ## slot to initialize the database migration system |
433 ## slot to initialize the database migration system |
387 ######################################################### |
434 ######################################################### |
388 |
435 |
389 @pyqtSlot() |
436 @pyqtSlot() |
390 def __initMigrations(self): |
437 def __initMigrations(self): |
391 """ |
438 """ |
392 Private slot to initialize the database migration system. |
439 Private slot to initialize the database migration system. |
393 """ |
440 """ |
394 title = self.tr("Initialize Migrations") |
441 title = self.tr("Initialize Migrations") |
395 |
442 |
396 self.__ensureMigrateConfigured() |
443 self.__ensureMigrateConfigured() |
397 migrations = self.__migrationsDirectory() |
444 migrations = self.__migrationsDirectory() |
398 |
445 |
399 args = ["init"] |
446 args = ["init"] |
400 if migrations: |
447 if migrations: |
401 args += ["--directory", migrations] |
448 args += ["--directory", migrations] |
402 |
449 |
403 multidb = EricMessageBox.yesNo( |
450 multidb = EricMessageBox.yesNo( |
404 None, |
451 None, |
405 self.tr("Multiple Databases"), |
452 self.tr("Multiple Databases"), |
406 self.tr("""Shall the support for multiple databases be""" |
453 self.tr( |
407 """ activated?""")) |
454 """Shall the support for multiple databases be""" """ activated?""" |
|
455 ), |
|
456 ) |
408 if multidb: |
457 if multidb: |
409 args.append("--multidb") |
458 args.append("--multidb") |
410 |
459 |
411 dlg = FlaskCommandDialog( |
460 dlg = FlaskCommandDialog( |
412 self.__project, title=title, |
461 self.__project, |
413 msgSuccess=self.tr("\nMigrations initialized successfully.") |
462 title=title, |
|
463 msgSuccess=self.tr("\nMigrations initialized successfully."), |
414 ) |
464 ) |
415 if dlg.startCommand("db", args): |
465 if dlg.startCommand("db", args): |
416 dlg.exec() |
466 dlg.exec() |
417 if dlg.normalExit(): |
467 if dlg.normalExit(): |
418 for root, _dirs, files in os.walk( |
468 for root, _dirs, files in os.walk( |
419 self.__migrationsDirectory(abspath=True) |
469 self.__migrationsDirectory(abspath=True) |
420 ): |
470 ): |
421 for fileName in files: |
471 for fileName in files: |
422 fullName = os.path.join(root, fileName) |
472 fullName = os.path.join(root, fileName) |
423 self.__ericProject.appendFile(fullName) |
473 self.__ericProject.appendFile(fullName) |
424 |
474 |
425 browser = (ericApp().getObject("ProjectBrowser") |
475 browser = ( |
426 .getProjectBrowser("others")) |
476 ericApp().getObject("ProjectBrowser").getProjectBrowser("others") |
|
477 ) |
427 alembic = os.path.join( |
478 alembic = os.path.join( |
428 self.__migrationsDirectory(abspath=True), |
479 self.__migrationsDirectory(abspath=True), "alembic.ini" |
429 "alembic.ini" |
|
430 ) |
480 ) |
431 browser.sourceFile.emit(alembic) |
481 browser.sourceFile.emit(alembic) |
432 |
482 |
433 ######################################################### |
483 ######################################################### |
434 ## slot to create a new database migration |
484 ## slot to create a new database migration |
435 ######################################################### |
485 ######################################################### |
436 |
486 |
437 @pyqtSlot() |
487 @pyqtSlot() |
438 def __createMigration(self): |
488 def __createMigration(self): |
439 """ |
489 """ |
440 Private slot to create a new database migration. |
490 Private slot to create a new database migration. |
441 """ |
491 """ |
442 title = self.tr("Create Migration") |
492 title = self.tr("Create Migration") |
443 |
493 |
444 self.__ensureMigrateConfigured() |
494 self.__ensureMigrateConfigured() |
445 migrations = self.__migrationsDirectory() |
495 migrations = self.__migrationsDirectory() |
446 |
496 |
447 message, ok = QInputDialog.getText( |
497 message, ok = QInputDialog.getText( |
448 None, |
498 None, |
449 title, |
499 title, |
450 self.tr("Enter a short message for the migration:"), |
500 self.tr("Enter a short message for the migration:"), |
451 QLineEdit.EchoMode.Normal) |
501 QLineEdit.EchoMode.Normal, |
|
502 ) |
452 if ok: |
503 if ok: |
453 args = ["migrate"] |
504 args = ["migrate"] |
454 if migrations: |
505 if migrations: |
455 args += ["--directory", migrations] |
506 args += ["--directory", migrations] |
456 if message: |
507 if message: |
457 args += ["--message", message] |
508 args += ["--message", message] |
458 |
509 |
459 dlg = FlaskCommandDialog( |
510 dlg = FlaskCommandDialog( |
460 self.__project, title=title, |
511 self.__project, |
461 msgSuccess=self.tr("\nMigration created successfully.") |
512 title=title, |
|
513 msgSuccess=self.tr("\nMigration created successfully."), |
462 ) |
514 ) |
463 if dlg.startCommand("db", args): |
515 if dlg.startCommand("db", args): |
464 dlg.exec() |
516 dlg.exec() |
465 if dlg.normalExit(): |
517 if dlg.normalExit(): |
466 versionsPattern = os.path.join( |
518 versionsPattern = os.path.join( |
467 self.__migrationsDirectory(abspath=True), |
519 self.__migrationsDirectory(abspath=True), "versions", "*.py" |
468 "versions", "*.py") |
520 ) |
469 for fileName in glob.iglob(versionsPattern): |
521 for fileName in glob.iglob(versionsPattern): |
470 self.__ericProject.appendFile(fileName) |
522 self.__ericProject.appendFile(fileName) |
471 |
523 |
472 ######################################################### |
524 ######################################################### |
473 ## slots to up- and downgrade a databse |
525 ## slots to up- and downgrade a databse |
474 ######################################################### |
526 ######################################################### |
475 |
527 |
476 @pyqtSlot() |
528 @pyqtSlot() |
477 def upgradeDatabase(self, revision=None): |
529 def upgradeDatabase(self, revision=None): |
478 """ |
530 """ |
479 Public slot to upgrade the database to the current migration. |
531 Public slot to upgrade the database to the current migration. |
480 |
532 |
481 @param revision migration revision to upgrade to |
533 @param revision migration revision to upgrade to |
482 @type str |
534 @type str |
483 """ |
535 """ |
484 title = self.tr("Upgrade Database") |
536 title = self.tr("Upgrade Database") |
485 |
537 |
486 self.__ensureMigrateConfigured() |
538 self.__ensureMigrateConfigured() |
487 migrations = self.__migrationsDirectory() |
539 migrations = self.__migrationsDirectory() |
488 |
540 |
489 args = ["upgrade"] |
541 args = ["upgrade"] |
490 if migrations: |
542 if migrations: |
491 args += ["--directory", migrations] |
543 args += ["--directory", migrations] |
492 if revision: |
544 if revision: |
493 args.append(revision) |
545 args.append(revision) |
494 |
546 |
495 dlg = FlaskCommandDialog( |
547 dlg = FlaskCommandDialog( |
496 self.__project, title=title, |
548 self.__project, |
497 msgSuccess=self.tr("\nDatabase upgraded successfully.") |
549 title=title, |
|
550 msgSuccess=self.tr("\nDatabase upgraded successfully."), |
498 ) |
551 ) |
499 if dlg.startCommand("db", args): |
552 if dlg.startCommand("db", args): |
500 dlg.exec() |
553 dlg.exec() |
501 |
554 |
502 @pyqtSlot() |
555 @pyqtSlot() |
503 def downgradeDatabase(self, revision=None): |
556 def downgradeDatabase(self, revision=None): |
504 """ |
557 """ |
505 Public slot to downgrade the database to the previous version. |
558 Public slot to downgrade the database to the previous version. |
506 |
559 |
507 @param revision migration revision to downgrade to |
560 @param revision migration revision to downgrade to |
508 @type str |
561 @type str |
509 """ |
562 """ |
510 title = self.tr("Downgrade Database") |
563 title = self.tr("Downgrade Database") |
511 |
564 |
512 self.__ensureMigrateConfigured() |
565 self.__ensureMigrateConfigured() |
513 migrations = self.__migrationsDirectory() |
566 migrations = self.__migrationsDirectory() |
514 |
567 |
515 args = ["downgrade"] |
568 args = ["downgrade"] |
516 if migrations: |
569 if migrations: |
517 args += ["--directory", migrations] |
570 args += ["--directory", migrations] |
518 if revision: |
571 if revision: |
519 args.append(revision) |
572 args.append(revision) |
520 |
573 |
521 dlg = FlaskCommandDialog( |
574 dlg = FlaskCommandDialog( |
522 self.__project, title=title, |
575 self.__project, |
523 msgSuccess=self.tr("\nDatabase downgraded successfully.") |
576 title=title, |
|
577 msgSuccess=self.tr("\nDatabase downgraded successfully."), |
524 ) |
578 ) |
525 if dlg.startCommand("db", args): |
579 if dlg.startCommand("db", args): |
526 dlg.exec() |
580 dlg.exec() |
527 |
581 |
528 ######################################################### |
582 ######################################################### |
529 ## slots to show migrations history information |
583 ## slots to show migrations history information |
530 ######################################################### |
584 ######################################################### |
531 |
585 |
532 @pyqtSlot() |
586 @pyqtSlot() |
533 def __showMigrationsSummary(self): |
587 def __showMigrationsSummary(self): |
534 """ |
588 """ |
535 Private slot to show a migrations history summary. |
589 Private slot to show a migrations history summary. |
536 """ |
590 """ |
537 from .MigrateSummaryDialog import MigrateSummaryDialog |
591 from .MigrateSummaryDialog import MigrateSummaryDialog |
538 |
592 |
539 self.__ensureMigrateConfigured() |
593 self.__ensureMigrateConfigured() |
540 migrations = self.__migrationsDirectory() |
594 migrations = self.__migrationsDirectory() |
541 |
595 |
542 if self.__migrationSummaryDialog is None: |
596 if self.__migrationSummaryDialog is None: |
543 self.__migrationSummaryDialog = MigrateSummaryDialog( |
597 self.__migrationSummaryDialog = MigrateSummaryDialog( |
544 self.__project, self, migrations=migrations) |
598 self.__project, self, migrations=migrations |
545 |
599 ) |
|
600 |
546 self.__migrationSummaryDialog.showSummary() |
601 self.__migrationSummaryDialog.showSummary() |
547 |
602 |
548 @pyqtSlot() |
603 @pyqtSlot() |
549 def __showMigrationsHistory(self): |
604 def __showMigrationsHistory(self): |
550 """ |
605 """ |
551 Private slot to show the full migrations history. |
606 Private slot to show the full migrations history. |
552 """ |
607 """ |
553 title = self.tr("Migrations History") |
608 title = self.tr("Migrations History") |
554 |
609 |
555 self.__ensureMigrateConfigured() |
610 self.__ensureMigrateConfigured() |
556 migrations = self.__migrationsDirectory() |
611 migrations = self.__migrationsDirectory() |
557 |
612 |
558 args = ["history", "--indicate-current", "--verbose"] |
613 args = ["history", "--indicate-current", "--verbose"] |
559 if migrations: |
614 if migrations: |
560 args += ["--directory", migrations] |
615 args += ["--directory", migrations] |
561 |
616 |
562 dlg = FlaskCommandDialog(self.__project, title=title) |
617 dlg = FlaskCommandDialog(self.__project, title=title) |
563 if dlg.startCommand("db", args): |
618 if dlg.startCommand("db", args): |
564 dlg.exec() |
619 dlg.exec() |