mirror of
https://codeberg.org/PostERG/xamxam.git
synced 2026-06-25 08:09:18 +02:00
fix: make schema.sql fully idempotent — add IF NOT EXISTS to all CREATE INDEX, CREATE TRIGGER, and CREATE VIEW statements
This commit is contained in:
1
TODO.md
1
TODO.md
@@ -11,6 +11,7 @@
|
|||||||
- [x] **Missing `v_smtp_active` view** on server — made all `CREATE VIEW` statements idempotent with `IF NOT EXISTS` in schema.sql
|
- [x] **Missing `v_smtp_active` view** on server — made all `CREATE VIEW` statements idempotent with `IF NOT EXISTS` in schema.sql
|
||||||
- [x] **`bars.svg` 404** — created `app/public/assets/img/bars.svg` (animated SVG spinner)
|
- [x] **`bars.svg` 404** — created `app/public/assets/img/bars.svg` (animated SVG spinner)
|
||||||
- [x] **Nginx rate limiting too aggressive** — increased admin zone to 300r/m, burst=30 to handle ~11 concurrent HTMX fragment requests on contenus.php page load
|
- [x] **Nginx rate limiting too aggressive** — increased admin zone to 300r/m, burst=30 to handle ~11 concurrent HTMX fragment requests on contenus.php page load
|
||||||
|
- [x] **Migration idempotency** — `CREATE INDEX` / `CREATE TRIGGER` / `CREATE VIEW` now use `IF NOT EXISTS` in schema.sql and generate-schema.py; migrate.sh no longer fails on re-run
|
||||||
- [ ] **Database readonly** — intermittent permission issue after deploy (added deploy-nginx recipe; permissions should be fixed by --chown + deploy-server.sh)
|
- [ ] **Database readonly** — intermittent permission issue after deploy (added deploy-nginx recipe; permissions should be fixed by --chown + deploy-server.sh)
|
||||||
|
|
||||||
## SQLite Backup & Data Integrity (docs/backup-plan.md)
|
## SQLite Backup & Data Integrity (docs/backup-plan.md)
|
||||||
|
|||||||
@@ -317,71 +317,71 @@ CREATE TABLE IF NOT EXISTS audit_log (
|
|||||||
-- INDEXES
|
-- INDEXES
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
|
|
||||||
CREATE INDEX idx_admin_audit_log_action ON admin_audit_log(action);
|
CREATE INDEX IF NOT EXISTS idx_admin_audit_log_action ON admin_audit_log(action);
|
||||||
|
|
||||||
CREATE INDEX idx_admin_audit_log_created_at ON admin_audit_log(created_at);
|
CREATE INDEX IF NOT EXISTS idx_admin_audit_log_created_at ON admin_audit_log(created_at);
|
||||||
|
|
||||||
CREATE INDEX idx_admin_audit_log_resource ON admin_audit_log(resource);
|
CREATE INDEX IF NOT EXISTS idx_admin_audit_log_resource ON admin_audit_log(resource);
|
||||||
|
|
||||||
CREATE INDEX idx_audit_log_table_record ON audit_log(table_name, record_id);
|
CREATE INDEX IF NOT EXISTS idx_audit_log_table_record ON audit_log(table_name, record_id);
|
||||||
|
|
||||||
CREATE INDEX idx_audit_log_timestamp ON audit_log(timestamp);
|
CREATE INDEX IF NOT EXISTS idx_audit_log_timestamp ON audit_log(timestamp);
|
||||||
|
|
||||||
CREATE INDEX idx_authors_email ON authors(email);
|
CREATE INDEX IF NOT EXISTS idx_authors_email ON authors(email);
|
||||||
|
|
||||||
CREATE INDEX idx_file_access_audit_request
|
CREATE INDEX IF NOT EXISTS idx_file_access_audit_request
|
||||||
ON file_access_audit(request_id);
|
ON file_access_audit(request_id);
|
||||||
|
|
||||||
CREATE INDEX idx_file_access_requests_email
|
CREATE INDEX IF NOT EXISTS idx_file_access_requests_email
|
||||||
ON file_access_requests(email);
|
ON file_access_requests(email);
|
||||||
|
|
||||||
CREATE INDEX idx_file_access_requests_status
|
CREATE INDEX IF NOT EXISTS idx_file_access_requests_status
|
||||||
ON file_access_requests(status);
|
ON file_access_requests(status);
|
||||||
|
|
||||||
CREATE INDEX idx_file_access_requests_thesis_id
|
CREATE INDEX IF NOT EXISTS idx_file_access_requests_thesis_id
|
||||||
ON file_access_requests(thesis_id);
|
ON file_access_requests(thesis_id);
|
||||||
|
|
||||||
CREATE INDEX idx_file_access_sessions_expires
|
CREATE INDEX IF NOT EXISTS idx_file_access_sessions_expires
|
||||||
ON file_access_sessions(expires_at);
|
ON file_access_sessions(expires_at);
|
||||||
|
|
||||||
CREATE INDEX idx_file_access_sessions_token
|
CREATE INDEX IF NOT EXISTS idx_file_access_sessions_token
|
||||||
ON file_access_sessions(session_token);
|
ON file_access_sessions(session_token);
|
||||||
|
|
||||||
CREATE INDEX idx_file_access_tokens_expires_at
|
CREATE INDEX IF NOT EXISTS idx_file_access_tokens_expires_at
|
||||||
ON file_access_tokens(expires_at);
|
ON file_access_tokens(expires_at);
|
||||||
|
|
||||||
CREATE INDEX idx_file_access_tokens_token
|
CREATE INDEX IF NOT EXISTS idx_file_access_tokens_token
|
||||||
ON file_access_tokens(token);
|
ON file_access_tokens(token);
|
||||||
|
|
||||||
CREATE INDEX idx_share_links_active ON share_links(is_active);
|
CREATE INDEX IF NOT EXISTS idx_share_links_active ON share_links(is_active);
|
||||||
|
|
||||||
CREATE INDEX idx_share_links_archived ON share_links(is_archived);
|
CREATE INDEX IF NOT EXISTS idx_share_links_archived ON share_links(is_archived);
|
||||||
|
|
||||||
CREATE INDEX idx_share_links_slug ON share_links(slug);
|
CREATE INDEX IF NOT EXISTS idx_share_links_slug ON share_links(slug);
|
||||||
|
|
||||||
CREATE INDEX idx_tags_name ON tags(name);
|
CREATE INDEX IF NOT EXISTS idx_tags_name ON tags(name);
|
||||||
|
|
||||||
CREATE INDEX idx_theses_access_type ON theses(access_type_id);
|
CREATE INDEX IF NOT EXISTS idx_theses_access_type ON theses(access_type_id);
|
||||||
|
|
||||||
CREATE INDEX idx_theses_ap_program ON theses(ap_program_id);
|
CREATE INDEX IF NOT EXISTS idx_theses_ap_program ON theses(ap_program_id);
|
||||||
|
|
||||||
CREATE INDEX idx_theses_identifier ON theses(identifier);
|
CREATE INDEX IF NOT EXISTS idx_theses_identifier ON theses(identifier);
|
||||||
|
|
||||||
CREATE INDEX idx_theses_orientation ON theses(orientation_id);
|
CREATE INDEX IF NOT EXISTS idx_theses_orientation ON theses(orientation_id);
|
||||||
|
|
||||||
CREATE INDEX idx_theses_pub_year ON theses(is_published, year DESC);
|
CREATE INDEX IF NOT EXISTS idx_theses_pub_year ON theses(is_published, year DESC);
|
||||||
|
|
||||||
CREATE INDEX idx_theses_published ON theses(is_published);
|
CREATE INDEX IF NOT EXISTS idx_theses_published ON theses(is_published);
|
||||||
|
|
||||||
CREATE INDEX idx_theses_year ON theses(year);
|
CREATE INDEX IF NOT EXISTS idx_theses_year ON theses(year);
|
||||||
|
|
||||||
CREATE INDEX idx_thesis_authors_author ON thesis_authors(author_id);
|
CREATE INDEX IF NOT EXISTS idx_thesis_authors_author ON thesis_authors(author_id);
|
||||||
|
|
||||||
CREATE INDEX idx_thesis_authors_thesis ON thesis_authors(thesis_id);
|
CREATE INDEX IF NOT EXISTS idx_thesis_authors_thesis ON thesis_authors(thesis_id);
|
||||||
|
|
||||||
CREATE INDEX idx_thesis_tags_tag ON thesis_tags(tag_id);
|
CREATE INDEX IF NOT EXISTS idx_thesis_tags_tag ON thesis_tags(tag_id);
|
||||||
|
|
||||||
CREATE INDEX idx_thesis_tags_thesis ON thesis_tags(thesis_id);
|
CREATE INDEX IF NOT EXISTS idx_thesis_tags_thesis ON thesis_tags(thesis_id);
|
||||||
|
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
-- VIEWS
|
-- VIEWS
|
||||||
@@ -458,37 +458,37 @@ WHERE is_published = 1;
|
|||||||
-- TRIGGERS
|
-- TRIGGERS
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
|
|
||||||
CREATE TRIGGER update_apropos_contents_timestamp
|
CREATE TRIGGER IF NOT EXISTS update_apropos_contents_timestamp
|
||||||
AFTER UPDATE ON apropos_contents
|
AFTER UPDATE ON apropos_contents
|
||||||
BEGIN
|
BEGIN
|
||||||
UPDATE apropos_contents SET updated_at = CURRENT_TIMESTAMP WHERE id = NEW.id;
|
UPDATE apropos_contents SET updated_at = CURRENT_TIMESTAMP WHERE id = NEW.id;
|
||||||
END;
|
END;
|
||||||
|
|
||||||
CREATE TRIGGER update_authors_timestamp
|
CREATE TRIGGER IF NOT EXISTS update_authors_timestamp
|
||||||
AFTER UPDATE ON authors
|
AFTER UPDATE ON authors
|
||||||
BEGIN
|
BEGIN
|
||||||
UPDATE authors SET updated_at = CURRENT_TIMESTAMP WHERE id = NEW.id;
|
UPDATE authors SET updated_at = CURRENT_TIMESTAMP WHERE id = NEW.id;
|
||||||
END;
|
END;
|
||||||
|
|
||||||
CREATE TRIGGER update_form_help_blocks_timestamp
|
CREATE TRIGGER IF NOT EXISTS update_form_help_blocks_timestamp
|
||||||
AFTER UPDATE ON form_help_blocks
|
AFTER UPDATE ON form_help_blocks
|
||||||
BEGIN
|
BEGIN
|
||||||
UPDATE form_help_blocks SET updated_at = CURRENT_TIMESTAMP WHERE key = NEW.key;
|
UPDATE form_help_blocks SET updated_at = CURRENT_TIMESTAMP WHERE key = NEW.key;
|
||||||
END;
|
END;
|
||||||
|
|
||||||
CREATE TRIGGER update_pages_timestamp
|
CREATE TRIGGER IF NOT EXISTS update_pages_timestamp
|
||||||
AFTER UPDATE ON pages
|
AFTER UPDATE ON pages
|
||||||
BEGIN
|
BEGIN
|
||||||
UPDATE pages SET updated_at = CURRENT_TIMESTAMP WHERE id = NEW.id;
|
UPDATE pages SET updated_at = CURRENT_TIMESTAMP WHERE id = NEW.id;
|
||||||
END;
|
END;
|
||||||
|
|
||||||
CREATE TRIGGER update_supervisors_timestamp
|
CREATE TRIGGER IF NOT EXISTS update_supervisors_timestamp
|
||||||
AFTER UPDATE ON supervisors
|
AFTER UPDATE ON supervisors
|
||||||
BEGIN
|
BEGIN
|
||||||
UPDATE supervisors SET updated_at = CURRENT_TIMESTAMP WHERE id = NEW.id;
|
UPDATE supervisors SET updated_at = CURRENT_TIMESTAMP WHERE id = NEW.id;
|
||||||
END;
|
END;
|
||||||
|
|
||||||
CREATE TRIGGER update_theses_timestamp
|
CREATE TRIGGER IF NOT EXISTS update_theses_timestamp
|
||||||
AFTER UPDATE ON theses
|
AFTER UPDATE ON theses
|
||||||
BEGIN
|
BEGIN
|
||||||
UPDATE theses SET updated_at = CURRENT_TIMESTAMP WHERE id = NEW.id;
|
UPDATE theses SET updated_at = CURRENT_TIMESTAMP WHERE id = NEW.id;
|
||||||
@@ -553,12 +553,12 @@ INSERT OR IGNORE INTO license_types (name) VALUES ('Domaine public');
|
|||||||
INSERT OR IGNORE INTO license_types (name) VALUES ('Tous droits réservés');
|
INSERT OR IGNORE INTO license_types (name) VALUES ('Tous droits réservés');
|
||||||
|
|
||||||
INSERT OR IGNORE INTO site_settings (key, value) VALUES ('access_type_interdit_enabled', '1');
|
INSERT OR IGNORE INTO site_settings (key, value) VALUES ('access_type_interdit_enabled', '1');
|
||||||
INSERT OR IGNORE INTO site_settings (key, value) VALUES ('access_type_interne_enabled', '0');
|
INSERT OR IGNORE INTO site_settings (key, value) VALUES ('access_type_interne_enabled', '1');
|
||||||
INSERT OR IGNORE INTO site_settings (key, value) VALUES ('access_type_libre_enabled', '0');
|
INSERT OR IGNORE INTO site_settings (key, value) VALUES ('access_type_libre_enabled', '0');
|
||||||
INSERT OR IGNORE INTO site_settings (key, value) VALUES ('objet_frart_enabled', '1');
|
INSERT OR IGNORE INTO site_settings (key, value) VALUES ('objet_frart_enabled', '0');
|
||||||
INSERT OR IGNORE INTO site_settings (key, value) VALUES ('objet_these_enabled', '1');
|
INSERT OR IGNORE INTO site_settings (key, value) VALUES ('objet_these_enabled', '0');
|
||||||
INSERT OR IGNORE INTO site_settings (key, value) VALUES ('peertube_upload_enabled', '0');
|
INSERT OR IGNORE INTO site_settings (key, value) VALUES ('peertube_upload_enabled', '0');
|
||||||
INSERT OR IGNORE INTO site_settings (key, value) VALUES ('restricted_files_enabled', '0');
|
INSERT OR IGNORE INTO site_settings (key, value) VALUES ('restricted_files_enabled', '1');
|
||||||
|
|
||||||
INSERT OR IGNORE INTO pages (slug, title, content, is_published) VALUES ('about', 'À propos', 'Contenu à venir', 1);
|
INSERT OR IGNORE INTO pages (slug, title, content, is_published) VALUES ('about', 'À propos', 'Contenu à venir', 1);
|
||||||
INSERT OR IGNORE INTO pages (slug, title, content, is_published) VALUES ('charte', 'Charte', 'Contenu à venir', 1);
|
INSERT OR IGNORE INTO pages (slug, title, content, is_published) VALUES ('charte', 'Charte', 'Contenu à venir', 1);
|
||||||
@@ -570,7 +570,7 @@ INSERT OR IGNORE INTO form_help_blocks (key, name, content, enabled, sort_order)
|
|||||||
INSERT OR IGNORE INTO form_help_blocks (key, name, content, enabled, sort_order) VALUES ('fieldset_synopsis', 'Note Synopsis', '', 0, 2);
|
INSERT OR IGNORE INTO form_help_blocks (key, name, content, enabled, sort_order) VALUES ('fieldset_synopsis', 'Note Synopsis', '', 0, 2);
|
||||||
INSERT OR IGNORE INTO form_help_blocks (key, name, content, enabled, sort_order) VALUES ('fieldset_jury', 'Composition du jury', '', 0, 3);
|
INSERT OR IGNORE INTO form_help_blocks (key, name, content, enabled, sort_order) VALUES ('fieldset_jury', 'Composition du jury', '', 0, 3);
|
||||||
INSERT OR IGNORE INTO form_help_blocks (key, name, content, enabled, sort_order) VALUES ('fieldset_academic', 'Cadre académique', '', 0, 4);
|
INSERT OR IGNORE INTO form_help_blocks (key, name, content, enabled, sort_order) VALUES ('fieldset_academic', 'Cadre académique', '', 0, 4);
|
||||||
INSERT OR IGNORE INTO form_help_blocks (key, name, content, enabled, sort_order) VALUES ('fieldset_files', 'Fichiers', '', 0, 5);
|
INSERT OR IGNORE INTO form_help_blocks (key, name, content, enabled, sort_order) VALUES ('fieldset_files', 'Fichiers', '', 1, 5);
|
||||||
INSERT OR IGNORE INTO form_help_blocks (key, name, content, enabled, sort_order) VALUES ('fieldset_access', 'Visibilité / Accès', 'qsldkjlfkjdsqmflkjq', 1, 6);
|
INSERT OR IGNORE INTO form_help_blocks (key, name, content, enabled, sort_order) VALUES ('fieldset_access', 'Visibilité / Accès', 'qsldkjlfkjdsqmflkjq', 1, 6);
|
||||||
INSERT OR IGNORE INTO form_help_blocks (key, name, content, enabled, sort_order) VALUES ('fieldset_email', 'E-mail de confirmation', '', 0, 7);
|
INSERT OR IGNORE INTO form_help_blocks (key, name, content, enabled, sort_order) VALUES ('fieldset_email', 'E-mail de confirmation', '', 0, 7);
|
||||||
INSERT OR IGNORE INTO form_help_blocks (key, name, content, enabled, sort_order) VALUES ('fieldset_languages', 'Langue(s)', 'Hahah', 0, 0);
|
INSERT OR IGNORE INTO form_help_blocks (key, name, content, enabled, sort_order) VALUES ('fieldset_languages', 'Langue(s)', 'Hahah', 0, 0);
|
||||||
|
|||||||
@@ -766,6 +766,19 @@
|
|||||||
+%%%%%%% diff from: somsyvxz 249f7943 "Bulk bar anti-shift, tags icons, AP no-wrap, credits reorder" (rebased revision)
|
+%%%%%%% diff from: somsyvxz 249f7943 "Bulk bar anti-shift, tags icons, AP no-wrap, credits reorder" (rebased revision)
|
||||||
+\\\\\\\ to: pylyqurz b7080cbb "feat(backup): deploy cron-based SQLite backups to production" (rebased revision)
|
+\\\\\\\ to: pylyqurz b7080cbb "feat(backup): deploy cron-based SQLite backups to production" (rebased revision)
|
||||||
++ $linkName = $link['name'] ?? '';
|
++ $linkName = $link['name'] ?? '';
|
||||||
|
++ $linkExpiresVal = $link['expires_at'] ? date('Y-m-d\TH:i', strtotime($link['expires_at'])) : '';
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff from: pylyqurz b7080cbb "feat(backup): deploy cron-based SQLite backups to production" (rebased revision)
|
||||||
|
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ to: somsyvxz 249f7943 "Bulk bar anti-shift, tags icons, AP no-wrap, credits reorder" (rebased revision)
|
||||||
|
- $linkName = $link['name'] ?? '';
|
||||||
|
- $linkExpiresVal = $link['expires_at'] ? date('Y-m-d\TH:i', strtotime($link['expires_at'])) : '';
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff from: somsyvxz 14a3cd10 "Bulk bar anti-shift, tags icons, AP no-wrap, credits reorder" (rebase destination)
|
||||||
|
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ to: qrtmmwro e81fdc2f "fix: make schema.sql fully idempotent — add IF NOT EXISTS to all CREATE INDEX, CREATE TRIGGER, and CREATE VIEW statements" (rebased revision)
|
||||||
|
$linkName = $link['name'] ?? '';
|
||||||
|
$linkExpiresVal = $link['expires_at'] ? date('Y-m-d\TH:i', strtotime($link['expires_at'])) : '';
|
||||||
|
$linkLockedYear = $link['locked_year'] ?? null;
|
||||||
|
+%%%%%%% diff from: somsyvxz 249f7943 "Bulk bar anti-shift, tags icons, AP no-wrap, credits reorder" (rebased revision)
|
||||||
|
+\\\\\\\ to: qrtmmwro c96116c4 "fix: make schema.sql fully idempotent — add IF NOT EXISTS to all CREATE INDEX, CREATE TRIGGER, and CREATE VIEW statements" (rebased revision)
|
||||||
|
++ $linkName = $link['name'] ?? '';
|
||||||
++ $linkExpiresVal = $link['expires_at'] ? date('Y-m-d\TH:i', strtotime($link['expires_at'])) : '';
|
++ $linkExpiresVal = $link['expires_at'] ? date('Y-m-d\TH:i', strtotime($link['expires_at'])) : '';
|
||||||
?>
|
?>
|
||||||
<tr class="admin-table-row" onclick="event.stopPropagation(); window.open('/partage/<?= urlencode($link['slug']) ?>', '_blank')" style="cursor:pointer">
|
<tr class="admin-table-row" onclick="event.stopPropagation(); window.open('/partage/<?= urlencode($link['slug']) ?>', '_blank')" style="cursor:pointer">
|
||||||
|
|||||||
3
justfile
3
justfile
@@ -284,8 +284,7 @@ deploy-backup: deploy-backup-script deploy-backup-cron
|
|||||||
|
|
||||||
[group('deploy')]
|
[group('deploy')]
|
||||||
deploy-check-backup-log:
|
deploy-check-backup-log:
|
||||||
# Show the last 20 lines of the SQLite backup log on the server.
|
ssh xamxam "tail -20 /var/log/sqlite-backup.log 2>/dev/null || echo '(log file empty or missing — will be created on first cron run)'"
|
||||||
ssh -t xamxam "sudo tail -20 /var/log/sqlite-backup.log 2>/dev/null || echo '(log file empty or missing — will be created on first cron run)'"
|
|
||||||
|
|
||||||
[group('deploy')]
|
[group('deploy')]
|
||||||
deploy-list-backups:
|
deploy-list-backups:
|
||||||
|
|||||||
@@ -131,6 +131,11 @@ for (sql,) in indexes:
|
|||||||
clean = sql.strip()
|
clean = sql.strip()
|
||||||
if not clean.endswith(';'):
|
if not clean.endswith(';'):
|
||||||
clean += ';'
|
clean += ';'
|
||||||
|
# Make idempotent — SQLite doesn't store IF NOT EXISTS in sqlite_master.sql
|
||||||
|
if clean.upper().startswith('CREATE INDEX ') and 'IF NOT EXISTS' not in clean.upper():
|
||||||
|
clean = clean.replace('CREATE INDEX ', 'CREATE INDEX IF NOT EXISTS ', 1)
|
||||||
|
if clean.upper().startswith('CREATE UNIQUE INDEX ') and 'IF NOT EXISTS' not in clean.upper():
|
||||||
|
clean = clean.replace('CREATE UNIQUE INDEX ', 'CREATE UNIQUE INDEX IF NOT EXISTS ', 1)
|
||||||
print(clean)
|
print(clean)
|
||||||
print()
|
print()
|
||||||
|
|
||||||
@@ -143,6 +148,9 @@ for (sql,) in views:
|
|||||||
clean = sql.strip()
|
clean = sql.strip()
|
||||||
if not clean.endswith(';'):
|
if not clean.endswith(';'):
|
||||||
clean += ';'
|
clean += ';'
|
||||||
|
# Make idempotent — SQLite doesn't store IF NOT EXISTS in sqlite_master.sql
|
||||||
|
if clean.upper().startswith('CREATE VIEW ') and 'IF NOT EXISTS' not in clean.upper():
|
||||||
|
clean = clean.replace('CREATE VIEW ', 'CREATE VIEW IF NOT EXISTS ', 1)
|
||||||
print(clean)
|
print(clean)
|
||||||
print()
|
print()
|
||||||
|
|
||||||
@@ -155,6 +163,9 @@ for (sql,) in triggers:
|
|||||||
clean = sql.strip()
|
clean = sql.strip()
|
||||||
if not clean.endswith(';'):
|
if not clean.endswith(';'):
|
||||||
clean += ';'
|
clean += ';'
|
||||||
|
# Make idempotent — SQLite doesn't store IF NOT EXISTS in sqlite_master.sql
|
||||||
|
if clean.upper().startswith('CREATE TRIGGER ') and 'IF NOT EXISTS' not in clean.upper():
|
||||||
|
clean = clean.replace('CREATE TRIGGER ', 'CREATE TRIGGER IF NOT EXISTS ', 1)
|
||||||
print(clean)
|
print(clean)
|
||||||
print()
|
print()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user