77from qgis .PyQt .QtWidgets import (QVBoxLayout , QHBoxLayout , QFormLayout ,
88 QComboBox , QLineEdit , QPushButton , QGroupBox ,
99 QTableWidget , QTableWidgetItem , QMessageBox , QDialog , QDialogButtonBox ,
10- QLabel , QTextEdit , QHeaderView )
10+ QLabel , QTextEdit , QHeaderView , QCheckBox )
1111from qgis .PyQt .QtCore import Qt
1212from qgis .PyQt .QtGui import QFont
1313from .base_tab import BaseTab
@@ -140,12 +140,25 @@ def setup_ui(self):
140140 self .template_comment_edit = QLineEdit ()
141141 self .template_comment_edit .setPlaceholderText ("Optional description for the template (e.g., 'Production schema template for project X')" )
142142
143+ # Add checkbox for qgis_projects table protection
144+ self .protect_qgis_projects_checkbox = QCheckBox ("Preserve qgis_projects table data" )
145+ self .protect_qgis_projects_checkbox .setChecked (True ) # Default checked
146+ self .protect_qgis_projects_checkbox .setToolTip ("When checked, the 'qgis_projects' table will not be truncated and its data will be preserved in the template" )
147+
148+ # Add input for schema exclusions
149+ self .exclude_schemas_edit = QLineEdit ()
150+ self .exclude_schemas_edit .setText ("listen" ) # Prefill with "listen"
151+ self .exclude_schemas_edit .setPlaceholderText ("Comma-separated list of schemas to preserve (e.g., listen, metadata, system)" )
152+ self .exclude_schemas_edit .setToolTip ("Enter schema names separated by commas. Tables in these schemas will not be truncated and their data will be preserved in the template" )
153+
143154 self .create_template_btn = QPushButton ("Create Template" )
144155 self .create_template_btn .clicked .connect (self .create_template )
145156
146157 create_layout .addRow ("Source Database:" , self .source_db_combo )
147158 create_layout .addRow ("Template Name:" , self .template_name_edit )
148159 create_layout .addRow ("Comment:" , self .template_comment_edit )
160+ create_layout .addRow ("" , self .protect_qgis_projects_checkbox )
161+ create_layout .addRow ("Exclude Schemas:" , self .exclude_schemas_edit )
149162 create_layout .addWidget (self .create_template_btn )
150163
151164 layout .addWidget (create_group )
@@ -192,28 +205,31 @@ def _show_help_popup(self):
192205 "<li><b>Name the template:</b> Give your template a descriptive name</li>"
193206 "<li><b>Add comment (optional):</b> Provide a description to help identify the template's purpose, "
194207 "such as 'Production schema for customer management system' or 'Development environment template'</li>"
208+ "<li><b>Configure data preservation:</b> Choose which tables/schemas to preserve data from</li>"
195209 "<li><b>Structure copied:</b> All tables, views, functions, indexes are copied</li>"
196- "<li><b>Data removed :</b> Template contains no records (empty tables) </li>"
210+ "<li><b>Data handling :</b> By default, template contains no records, but you can preserve specific tables/schemas </li>"
197211 "<li><b>Template ready:</b> Use template to create new databases instantly</li>"
198212 "</ol>"
213+ "<h4>Data Preservation Options:</h4>"
214+ "<ul>"
215+ "<li><b>Preserve qgis_projects table:</b> When checked, the 'qgis_projects' table data will be kept in the template</li>"
216+ "<li><b>Exclude Schemas:</b> Comma-separated list of schema names whose tables will not be truncated</li>"
217+ "</ul>"
199218 "<h4>Template Comments:</h4>"
200219 "<p>The <b>comment field</b> allows you to add a descriptive note to your template that will be stored "
201- "in the PostgreSQL database catalog. This helps you and other users understand the purpose and content "
202- "of each template. Comments are especially useful when managing multiple templates.</p>"
220+ "in the PostgreSQL database catalog. This helps you and other users understand the purpose and content. </p>"
203221 "<h4>⚠️ Important notes:</h4>"
204222 "<ul>"
205223 "<li><b>Active connections:</b> All connections to source database will be dropped during creation</li>"
206- "<li><b>Structure only:</b> Templates preserve schema but remove all data</li>"
207- "<li><b>PostgreSQL feature:</b> Uses native PostgreSQL template functionality</li>"
208- "<li><b>Comments are permanent:</b> Once set, comments become part of the database metadata</li>"
224+ "<li><b>Structure preserved:</b> Templates preserve schema and optionally selected data</li>"
225+ "<li><b>Schema exclusions:</b> Tables in excluded schemas will keep their data in the template</li>"
209226 "</ul>"
210227 )
211228
212229 msg = QMessageBox (self )
213230 msg .setWindowTitle ("Help - PostgreSQL Template Manager" )
214231 msg .setTextFormat (1 ) # Rich text format
215232 msg .setText (help_text )
216- msg .setIcon (QMessageBox .Information )
217233 msg .setStandardButtons (QMessageBox .Ok )
218234 msg .exec_ ()
219235
@@ -271,6 +287,15 @@ def create_template(self):
271287 template_name = self .template_name_edit .text ().strip ()
272288 template_comment = self .template_comment_edit .text ().strip ()
273289
290+ # Get the new options
291+ preserve_qgis_projects = self .protect_qgis_projects_checkbox .isChecked ()
292+ exclude_schemas_text = self .exclude_schemas_edit .text ().strip ()
293+
294+ # Parse excluded schemas
295+ excluded_schemas = []
296+ if exclude_schemas_text :
297+ excluded_schemas = [schema .strip () for schema in exclude_schemas_text .split ("," ) if schema .strip ()]
298+
274299 if not self .validate_selection (self .source_db_combo , "source database" ):
275300 return
276301
@@ -305,11 +330,21 @@ def create_template(self):
305330 else :
306331 # No active connections, but still show a confirmation
307332 confirmation_text = f"Create template '{ template_name } ' from database '{ source_db } '?\n \n "
308- confirmation_text += "This will create a copy of the database structure without data."
333+ confirmation_text += "This will create a copy of the database structure with selected data preservation options ."
309334
310335 if template_comment :
311336 confirmation_text += f"\n \n Comment: { template_comment } "
312337
338+ # Add information about data preservation
339+ if preserve_qgis_projects or excluded_schemas :
340+ confirmation_text += "\n \n Data preservation settings:"
341+ if preserve_qgis_projects :
342+ confirmation_text += "\n • qgis_projects table data will be preserved"
343+ if excluded_schemas :
344+ confirmation_text += f"\n • Schemas excluded from truncation: { ', ' .join (excluded_schemas )} "
345+ else :
346+ confirmation_text += "\n \n All table data will be removed (standard template behavior)."
347+
313348 reply = QMessageBox .question (
314349 self ,
315350 "Create Template" ,
@@ -323,7 +358,13 @@ def create_template(self):
323358
324359 # Proceed with template creation
325360 self .emit_progress_started ()
326- self .db_manager .create_template (source_db , template_name , template_comment )
361+ self .db_manager .create_template (
362+ source_db ,
363+ template_name ,
364+ template_comment ,
365+ preserve_qgis_projects = preserve_qgis_projects ,
366+ excluded_schemas = excluded_schemas
367+ )
327368
328369 except Exception as e :
329370 self .emit_log (f"Error checking connections: { str (e )} " )
@@ -362,6 +403,9 @@ def on_operation_finished(self, success, message):
362403 self .emit_log (f"✓ { message } " )
363404 self .template_name_edit .clear ()
364405 self .template_comment_edit .clear ()
406+ # Reset data preservation options to defaults
407+ self .protect_qgis_projects_checkbox .setChecked (True )
408+ self .exclude_schemas_edit .setText ("listen" )
365409 self .refresh_templates ()
366410 else :
367411 self .emit_log (f"✗ { message } " )
0 commit comments