-
Notifications
You must be signed in to change notification settings - Fork 36
Create data migration for moving to new tables #315
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,176 @@ | ||||||||||||||
| -- Add unique index to user_relays table to prevent duplicate entries | ||||||||||||||
| CREATE UNIQUE INDEX IF NOT EXISTS idx_user_relays_unique | ||||||||||||||
| ON user_relays (user_id, relay_id, relay_type); | ||||||||||||||
|
|
||||||||||||||
| -- Step 1: Migrate contacts to users table | ||||||||||||||
| INSERT INTO users (pubkey, metadata) | ||||||||||||||
| SELECT | ||||||||||||||
| pubkey, | ||||||||||||||
| CASE | ||||||||||||||
| WHEN metadata IS NOT NULL AND metadata != '' THEN json(metadata) | ||||||||||||||
| ELSE NULL | ||||||||||||||
| END as metadata | ||||||||||||||
| FROM contacts | ||||||||||||||
| WHERE NOT EXISTS (SELECT 1 FROM users WHERE users.pubkey = contacts.pubkey); | ||||||||||||||
|
Comment on lines
+13
to
+14
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Avoid inserting users with NULL/empty pubkeys. Rows with NULL/empty pubkey will pass the NOT EXISTS check and attempt to insert, likely violating NOT NULL/PK constraints. Apply: -FROM contacts
-WHERE NOT EXISTS (SELECT 1 FROM users WHERE users.pubkey = contacts.pubkey);
+FROM contacts
+WHERE pubkey IS NOT NULL
+ AND pubkey != ''
+ AND NOT EXISTS (SELECT 1 FROM users WHERE users.pubkey = contacts.pubkey);📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||
|
|
||||||||||||||
| -- Step 2: Extract and insert unique relay URLs from contacts | ||||||||||||||
| -- Extract from nip65_relays | ||||||||||||||
| INSERT OR IGNORE INTO relays (url) | ||||||||||||||
| SELECT DISTINCT | ||||||||||||||
| json_extract(relay_value.value, '$') as url | ||||||||||||||
| FROM contacts, | ||||||||||||||
| json_each(contacts.nip65_relays) as relay_value | ||||||||||||||
| WHERE json_valid(contacts.nip65_relays) | ||||||||||||||
| AND json_extract(relay_value.value, '$') IS NOT NULL | ||||||||||||||
| AND json_extract(relay_value.value, '$') != ''; | ||||||||||||||
|
|
||||||||||||||
| -- Extract from inbox_relays | ||||||||||||||
| INSERT OR IGNORE INTO relays (url) | ||||||||||||||
| SELECT DISTINCT | ||||||||||||||
| json_extract(relay_value.value, '$') as url | ||||||||||||||
| FROM contacts, | ||||||||||||||
| json_each(contacts.inbox_relays) as relay_value | ||||||||||||||
| WHERE json_valid(contacts.inbox_relays) | ||||||||||||||
| AND json_extract(relay_value.value, '$') IS NOT NULL | ||||||||||||||
| AND json_extract(relay_value.value, '$') != ''; | ||||||||||||||
|
|
||||||||||||||
| -- Extract from key_package_relays | ||||||||||||||
| INSERT OR IGNORE INTO relays (url) | ||||||||||||||
| SELECT DISTINCT | ||||||||||||||
| json_extract(relay_value.value, '$') as url | ||||||||||||||
| FROM contacts, | ||||||||||||||
| json_each(contacts.key_package_relays) as relay_value | ||||||||||||||
| WHERE json_valid(contacts.key_package_relays) | ||||||||||||||
| AND json_extract(relay_value.value, '$') IS NOT NULL | ||||||||||||||
| AND json_extract(relay_value.value, '$') != ''; | ||||||||||||||
|
|
||||||||||||||
| -- Step 3: Create user_relays relationships | ||||||||||||||
| -- Insert nip65_relays relationships | ||||||||||||||
| INSERT OR IGNORE INTO user_relays (user_id, relay_id, relay_type) | ||||||||||||||
| SELECT DISTINCT | ||||||||||||||
| u.id as user_id, | ||||||||||||||
| r.id as relay_id, | ||||||||||||||
| 'nip65' as relay_type | ||||||||||||||
| FROM contacts c | ||||||||||||||
| JOIN users u ON u.pubkey = c.pubkey | ||||||||||||||
| JOIN relays r ON r.url = json_extract(relay_value.value, '$'), | ||||||||||||||
| json_each(c.nip65_relays) as relay_value | ||||||||||||||
| WHERE json_valid(c.nip65_relays) | ||||||||||||||
|
Comment on lines
+56
to
+58
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fix JOIN order: ON clause references alias not yet in scope (will error in SQLite). In each block, the JOIN relays r ... ON ... references Apply these diffs: --- Step 3: nip65_relays
-FROM contacts c
-JOIN users u ON u.pubkey = c.pubkey
-JOIN relays r ON r.url = json_extract(relay_value.value, '$'),
- json_each(c.nip65_relays) as relay_value
+FROM contacts c
+JOIN users u ON u.pubkey = c.pubkey
+CROSS JOIN json_each(c.nip65_relays) AS relay_value
+JOIN relays r ON r.url = json_extract(relay_value.value, '$')
WHERE json_valid(c.nip65_relays)--- Step 3: inbox_relays
-FROM contacts c
-JOIN users u ON u.pubkey = c.pubkey
-JOIN relays r ON r.url = json_extract(relay_value.value, '$'),
- json_each(c.inbox_relays) as relay_value
+FROM contacts c
+JOIN users u ON u.pubkey = c.pubkey
+CROSS JOIN json_each(c.inbox_relays) AS relay_value
+JOIN relays r ON r.url = json_extract(relay_value.value, '$')
WHERE json_valid(c.inbox_relays)--- Step 3: key_package_relays
-FROM contacts c
-JOIN users u ON u.pubkey = c.pubkey
-JOIN relays r ON r.url = json_extract(relay_value.value, '$'),
- json_each(c.key_package_relays) as relay_value
+FROM contacts c
+JOIN users u ON u.pubkey = c.pubkey
+CROSS JOIN json_each(c.key_package_relays) AS relay_value
+JOIN relays r ON r.url = json_extract(relay_value.value, '$')
WHERE json_valid(c.key_package_relays)Also applies to: 66-68, 80-82 🤖 Prompt for AI Agents |
||||||||||||||
| AND json_extract(relay_value.value, '$') IS NOT NULL | ||||||||||||||
| AND json_extract(relay_value.value, '$') != ''; | ||||||||||||||
|
|
||||||||||||||
| -- Insert inbox_relays relationships | ||||||||||||||
| INSERT OR IGNORE INTO user_relays (user_id, relay_id, relay_type) | ||||||||||||||
| SELECT DISTINCT | ||||||||||||||
| u.id as user_id, | ||||||||||||||
| r.id as relay_id, | ||||||||||||||
| 'inbox' as relay_type | ||||||||||||||
| FROM contacts c | ||||||||||||||
| JOIN users u ON u.pubkey = c.pubkey | ||||||||||||||
| JOIN relays r ON r.url = json_extract(relay_value.value, '$'), | ||||||||||||||
| json_each(c.inbox_relays) as relay_value | ||||||||||||||
| WHERE json_valid(c.inbox_relays) | ||||||||||||||
| AND json_extract(relay_value.value, '$') IS NOT NULL | ||||||||||||||
| AND json_extract(relay_value.value, '$') != ''; | ||||||||||||||
|
|
||||||||||||||
| -- Insert key_package_relays relationships | ||||||||||||||
| INSERT OR IGNORE INTO user_relays (user_id, relay_id, relay_type) | ||||||||||||||
| SELECT DISTINCT | ||||||||||||||
| u.id as user_id, | ||||||||||||||
| r.id as relay_id, | ||||||||||||||
| 'key_package' as relay_type | ||||||||||||||
| FROM contacts c | ||||||||||||||
| JOIN users u ON u.pubkey = c.pubkey | ||||||||||||||
| JOIN relays r ON r.url = json_extract(relay_value.value, '$'), | ||||||||||||||
| json_each(c.key_package_relays) as relay_value | ||||||||||||||
| WHERE json_valid(c.key_package_relays) | ||||||||||||||
| AND json_extract(relay_value.value, '$') IS NOT NULL | ||||||||||||||
| AND json_extract(relay_value.value, '$') != ''; | ||||||||||||||
|
|
||||||||||||||
| -- Step 4: Extract and insert unique relay URLs from accounts table | ||||||||||||||
| -- Extract from accounts.nip65_relays | ||||||||||||||
| INSERT OR IGNORE INTO relays (url) | ||||||||||||||
| SELECT DISTINCT | ||||||||||||||
| json_extract(relay_value.value, '$') as url | ||||||||||||||
| FROM accounts, | ||||||||||||||
| json_each(accounts.nip65_relays) as relay_value | ||||||||||||||
| WHERE json_valid(accounts.nip65_relays) | ||||||||||||||
| AND json_extract(relay_value.value, '$') IS NOT NULL | ||||||||||||||
| AND json_extract(relay_value.value, '$') != ''; | ||||||||||||||
|
|
||||||||||||||
| -- Extract from accounts.inbox_relays | ||||||||||||||
| INSERT OR IGNORE INTO relays (url) | ||||||||||||||
| SELECT DISTINCT | ||||||||||||||
| json_extract(relay_value.value, '$') as url | ||||||||||||||
| FROM accounts, | ||||||||||||||
| json_each(accounts.inbox_relays) as relay_value | ||||||||||||||
| WHERE json_valid(accounts.inbox_relays) | ||||||||||||||
| AND json_extract(relay_value.value, '$') IS NOT NULL | ||||||||||||||
| AND json_extract(relay_value.value, '$') != ''; | ||||||||||||||
|
|
||||||||||||||
| -- Extract from accounts.key_package_relays | ||||||||||||||
| INSERT OR IGNORE INTO relays (url) | ||||||||||||||
| SELECT DISTINCT | ||||||||||||||
| json_extract(relay_value.value, '$') as url | ||||||||||||||
| FROM accounts, | ||||||||||||||
| json_each(accounts.key_package_relays) as relay_value | ||||||||||||||
| WHERE json_valid(accounts.key_package_relays) | ||||||||||||||
| AND json_extract(relay_value.value, '$') IS NOT NULL | ||||||||||||||
| AND json_extract(relay_value.value, '$') != ''; | ||||||||||||||
|
|
||||||||||||||
| -- Step 5: Create user_relays relationships from accounts table | ||||||||||||||
| -- Insert accounts.nip65_relays relationships | ||||||||||||||
| INSERT OR IGNORE INTO user_relays (user_id, relay_id, relay_type) | ||||||||||||||
| SELECT DISTINCT | ||||||||||||||
| u.id as user_id, | ||||||||||||||
| r.id as relay_id, | ||||||||||||||
| 'nip65' as relay_type | ||||||||||||||
| FROM accounts a | ||||||||||||||
| JOIN users u ON u.pubkey = a.pubkey | ||||||||||||||
| JOIN relays r ON r.url = json_extract(relay_value.value, '$'), | ||||||||||||||
| json_each(a.nip65_relays) as relay_value | ||||||||||||||
| WHERE json_valid(a.nip65_relays) | ||||||||||||||
|
Comment on lines
+130
to
+132
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same JOIN scoping bug in Step 5; reorder to bring json_each into scope before joining relays. These three blocks have the same issue; reorder as in Step 3. Apply these diffs: --- Step 5: accounts.nip65_relays
-FROM accounts a
-JOIN users u ON u.pubkey = a.pubkey
-JOIN relays r ON r.url = json_extract(relay_value.value, '$'),
- json_each(a.nip65_relays) as relay_value
+FROM accounts a
+JOIN users u ON u.pubkey = a.pubkey
+CROSS JOIN json_each(a.nip65_relays) AS relay_value
+JOIN relays r ON r.url = json_extract(relay_value.value, '$')
WHERE json_valid(a.nip65_relays)--- Step 5: accounts.inbox_relays
-FROM accounts a
-JOIN users u ON u.pubkey = a.pubkey
-JOIN relays r ON r.url = json_extract(relay_value.value, '$'),
- json_each(a.inbox_relays) as relay_value
+FROM accounts a
+JOIN users u ON u.pubkey = a.pubkey
+CROSS JOIN json_each(a.inbox_relays) AS relay_value
+JOIN relays r ON r.url = json_extract(relay_value.value, '$')
WHERE json_valid(a.inbox_relays)--- Step 5: accounts.key_package_relays
-FROM accounts a
-JOIN users u ON u.pubkey = a.pubkey
-JOIN relays r ON r.url = json_extract(relay_value.value, '$'),
- json_each(a.key_package_relays) as relay_value
+FROM accounts a
+JOIN users u ON u.pubkey = a.pubkey
+CROSS JOIN json_each(a.key_package_relays) AS relay_value
+JOIN relays r ON r.url = json_extract(relay_value.value, '$')
WHERE json_valid(a.key_package_relays)Also applies to: 140-142, 154-156 |
||||||||||||||
| AND json_extract(relay_value.value, '$') IS NOT NULL | ||||||||||||||
| AND json_extract(relay_value.value, '$') != ''; | ||||||||||||||
|
|
||||||||||||||
| -- Insert accounts.inbox_relays relationships | ||||||||||||||
| INSERT OR IGNORE INTO user_relays (user_id, relay_id, relay_type) | ||||||||||||||
| SELECT DISTINCT | ||||||||||||||
| u.id as user_id, | ||||||||||||||
| r.id as relay_id, | ||||||||||||||
| 'inbox' as relay_type | ||||||||||||||
| FROM accounts a | ||||||||||||||
| JOIN users u ON u.pubkey = a.pubkey | ||||||||||||||
| JOIN relays r ON r.url = json_extract(relay_value.value, '$'), | ||||||||||||||
| json_each(a.inbox_relays) as relay_value | ||||||||||||||
| WHERE json_valid(a.inbox_relays) | ||||||||||||||
| AND json_extract(relay_value.value, '$') IS NOT NULL | ||||||||||||||
| AND json_extract(relay_value.value, '$') != ''; | ||||||||||||||
|
|
||||||||||||||
| -- Insert accounts.key_package_relays relationships | ||||||||||||||
| INSERT OR IGNORE INTO user_relays (user_id, relay_id, relay_type) | ||||||||||||||
| SELECT DISTINCT | ||||||||||||||
| u.id as user_id, | ||||||||||||||
| r.id as relay_id, | ||||||||||||||
| 'key_package' as relay_type | ||||||||||||||
| FROM accounts a | ||||||||||||||
| JOIN users u ON u.pubkey = a.pubkey | ||||||||||||||
| JOIN relays r ON r.url = json_extract(relay_value.value, '$'), | ||||||||||||||
| json_each(a.key_package_relays) as relay_value | ||||||||||||||
| WHERE json_valid(a.key_package_relays) | ||||||||||||||
| AND json_extract(relay_value.value, '$') IS NOT NULL | ||||||||||||||
| AND json_extract(relay_value.value, '$') != ''; | ||||||||||||||
|
|
||||||||||||||
| -- Step 6: Migrate accounts to accounts_new table | ||||||||||||||
| INSERT INTO accounts_new (pubkey, user_id, settings, last_synced_at) | ||||||||||||||
| SELECT | ||||||||||||||
| a.pubkey, | ||||||||||||||
| u.id as user_id, | ||||||||||||||
| a.settings, | ||||||||||||||
| CASE | ||||||||||||||
| WHEN a.last_synced IS NOT NULL THEN datetime(a.last_synced, 'unixepoch') | ||||||||||||||
| ELSE NULL | ||||||||||||||
| END as last_synced_at | ||||||||||||||
| FROM accounts a | ||||||||||||||
| JOIN users u ON u.pubkey = a.pubkey | ||||||||||||||
| WHERE NOT EXISTS (SELECT 1 FROM accounts_new WHERE accounts_new.pubkey = a.pubkey); | ||||||||||||||
|
Comment on lines
+164
to
+176
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Accounts with no matching user are dropped; insert missing users from accounts first. Currently, accounts_new is populated by joining to users. If a pubkey exists in accounts but not in contacts (Step 1), its account will be skipped. Insert any missing users from accounts before Step 6. Add this block right after Step 1 (before Step 2): -- Step 1b: Ensure all account pubkeys exist in users
INSERT INTO users (pubkey, metadata)
SELECT DISTINCT a.pubkey, NULL
FROM accounts a
WHERE a.pubkey IS NOT NULL
AND a.pubkey != ''
AND NOT EXISTS (SELECT 1 FROM users u WHERE u.pubkey = a.pubkey);🤖 Prompt for AI Agents |
||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Avoid nullifying metadata: only call json() on valid JSON.
json(metadata) returns NULL on invalid JSON, which will drop non-JSON-but-previously-populated metadata. Check json_valid first.
🤖 Prompt for AI Agents