Last active 1 day ago

Do not change anything in lol, change the SQLITE_DB and DB_* variables in migrate.py

swee revised this gist 1 day ago. Go to revision

1 file changed, 17 insertions, 1 deletion

migrate.py

@@ -32,6 +32,17 @@ print("[...] Starting dry run...")
32 32 sqdb = sqlite3.connect(SQLITE_DB)
33 33 sqursor = sqdb.cursor()
34 34
35 + for table, col in rules.items():
36 + colstring = ", ".join(["\"" + x.replace("*", "").replace("!", "") + "\"" for x in col])
37 + items = sqursor.execute(f"SELECT {colstring} FROM {table};").fetchall()
38 + for row in items:
39 + newrow = []
40 + for i, cols in enumerate(col):
41 + if cols[0] == "*":
42 + newrow.append(int_to_bool(row[i]))
43 + elif cols[0] == "!":
44 + newrow.append(timestamp_conversion(row[i]))
45 +
35 46 bad = 0
36 47
37 48 for table, col in rules.items():
@@ -47,7 +58,6 @@ for table, col in rules.items():
47 58 if bad:
48 59 print(f"[!!!] {bad} tables found with not enough items")
49 60
50 - print("[OK] Everything is okay!")
51 61 input("Press enter to start, press ctrl+c to stop...")
52 62
53 63 conn = psycopg2.connect(database=DB_NAME,
@@ -75,5 +85,11 @@ for table, col in rules.items():
75 85 cursor.execute(f"INSERT INTO \"{table}\" ({colstring}) VALUES ({ph})", newrow)
76 86 print("\r[OK] Done working on " + table)
77 87
88 + print("Fixing sequences..")
89 + seqs = sqursor.execute("SELECT * FROM sqlite_sequence").fetchall()
90 + for table, seq in seqs:
91 + if seq:
92 + cursor.execute(f"SELECT setval(%s, %s, true);", (f"{table}_id_seq", seq))
93 +
78 94 conn.commit()
79 95 print("[FIN] Migration is done! Enjoy!")

swee revised this gist 1 day ago. Go to revision

2 files changed, 459 insertions

lol(file created)

@@ -0,0 +1,380 @@
1 + version
2 + id, version
3 +
4 + forgejo_version
5 + id, version
6 +
7 + forgejo_sem_ver
8 + version
9 +
10 + forgejo_migration
11 + id, created_unix
12 +
13 + dbfs_meta
14 + id, full_path, block_size, file_size, create_timestamp, modify_timestamp
15 +
16 + dbfs_data
17 + id, revision, meta_id, blob_offset, blob_size, blob_data
18 +
19 + email_hash
20 + hash, email
21 +
22 + access_token
23 + id, uid, name, token_hash, token_salt, token_last_eight, scope, created_unix, updated_unix
24 +
25 + oauth2_application
26 + id, uid, name, client_id, client_secret, *confidential_client, redirect_uris, created_unix, updated_unix
27 +
28 + oauth2_authorization_code
29 + id, grant_id, code, code_challenge, code_challenge_method, redirect_uri, valid_until
30 +
31 + oauth2_grant
32 + id, user_id, application_id, counter, scope, nonce, created_unix, updated_unix
33 +
34 + session
35 + key, data, expiry
36 +
37 + login_source
38 + id, type, name, *is_active, *is_sync_enabled, cfg, created_unix, updated_unix
39 +
40 + two_factor
41 + id, uid, scratch_salt, scratch_hash, last_used_passcode, created_unix, updated_unix, secret
42 +
43 + webauthn_credential
44 + id, name, lower_name, user_id, credential_id, public_key, attestation_type, aaguid, sign_count, *clone_warning, created_unix, updated_unix, *backup_eligible, *backup_state, *legacy
45 +
46 + abuse_report
47 + id, status, reporter_id, content_type, content_id, category, remarks, shadow_copy_id, created_unix, resolved_unix
48 +
49 + abuse_report_shadow_copy
50 + id, raw_value, created_unix
51 +
52 + app_state
53 + id, revision, content
54 +
55 + notice
56 + id, type, description, created_unix
57 +
58 + system_setting
59 + id, setting_key, setting_value, version, created, updated
60 +
61 + hook_task
62 + id, hook_id, uuid, payload_content, payload_version, event_type, *is_delivered, delivered, *is_succeed, request_content, response_content
63 +
64 + webhook
65 + id, repo_id, owner_id, *is_system_webhook, url, http_method, content_type, secret, events, *is_active, type, meta, last_status, header_authorization_encrypted, created_unix, updated_unix
66 +
67 + federation_host
68 + id, host_fqdn, software_name, !latest_activity, created, updated, key_id, public_key, host_port, host_schema
69 +
70 + badge
71 + id, description, image_url
72 +
73 + user_badge
74 + id, badge_id, user_id
75 +
76 + forgejo_blocked_user
77 + id, block_id, user_id, created_unix
78 +
79 + email_address
80 + id, uid, email, lower_email, *is_activated, *is_primary
81 +
82 + external_login_user
83 + external_id, user_id, login_source_id, raw_data, provider, email, name, first_name, last_name, nick_name, description, avatar_url, location, access_token, access_token_secret, refresh_token, !expires_at
84 +
85 + follow
86 + id, user_id, follow_id, created_unix
87 +
88 + user_open_id
89 + id, uid, uri, *show
90 +
91 + user_redirect
92 + id, lower_name, redirect_user_id, created_unix
93 +
94 + user_setting
95 + id, user_id, setting_key, setting_value
96 +
97 + federated_user
98 + id, user_id, external_id, federation_host_id, key_id, public_key, normalized_original_url, inbox_path
99 +
100 + federated_user_follower
101 + id, followed_user_id, following_user_id
102 +
103 + repo_archive_download_count
104 + id, repo_id, release_id, type, count
105 +
106 + repo_archiver
107 + id, repo_id, type, status, commit_id, created_unix
108 +
109 + user
110 + id, lower_name, name, full_name, email, *keep_email_private, email_notifications_preference, passwd, passwd_hash_algo, *must_change_password, login_type, login_name, type, location, website, pronouns, rands, salt, language, description, created_unix, last_login_unix, *last_repo_visibility, max_repo_creation, *is_active, *is_admin, *is_restricted, *allow_git_hook, *allow_import_local, *allow_create_organization, *prohibit_login, avatar, avatar_email, *use_custom_avatar, num_followers, num_following, num_stars, num_repos, num_teams, num_members, visibility, *repo_admin_change_team_access, diff_view_style, theme, *keep_activity_private, *enable_repo_unit_hints, *keep_pronouns_private, login_source, updated_unix
111 +
112 + attachment
113 + id, uuid, repo_id, issue_id, release_id, uploader_id, comment_id, name, download_count, size, created_unix, external_url
114 +
115 + language_stat
116 + id, repo_id, commit_id, *is_primary, language, size, created_unix
117 +
118 + mirror
119 + id, repo_id, interval, *enable_prune, updated_unix, next_update_unix, *lfs_enabled, lfs_endpoint, remote_address
120 +
121 + push_mirror
122 + id, repo_id, remote_name, remote_address, *sync_on_commit, interval, created_unix, last_update, last_error, public_key, private_key, branch_filter
123 +
124 + repo_redirect
125 + id, owner_id, lower_name, redirect_repo_id
126 +
127 + release
128 + id, repo_id, publisher_id, tag_name, original_author, original_author_id, lower_tag_name, target, title, sha1, *hide_archive_links, num_commits, note, *is_draft, *is_prerelease, *is_tag, created_unix
129 +
130 + forgejo_repo_flag
131 + id, repo_id, name
132 +
133 + repo_indexer_status
134 + id, repo_id, commit_sha, indexer_type
135 +
136 + following_repo
137 + id, repo_id, external_id, federation_host_id, uri
138 +
139 + repo_unit
140 + id, repo_id, type, config, created_unix, default_permissions
141 +
142 + star
143 + id, uid, repo_id, created_unix
144 +
145 + topic
146 + id, name, repo_count, created_unix, updated_unix
147 +
148 + repo_topic
149 + repo_id, topic_id
150 +
151 + upload
152 + id, uuid, name
153 +
154 + watch
155 + id, user_id, repo_id, mode, created_unix, updated_unix
156 +
157 + action_artifact
158 + id, run_id, runner_id, repo_id, owner_id, commit_sha, storage_path, file_size, file_compressed_size, content_encoding, artifact_path, artifact_name, status, created_unix, updated_unix, expired_unix
159 +
160 + action_run
161 + id, title, repo_id, owner_id, workflow_id, index, trigger_user_id, schedule_id, ref, commit_sha, *is_fork_pull_request, *need_approval, approved_by, event, event_payload, trigger_event, status, version, started, stopped, previous_duration, created, updated, *notify_email, pre_execution_error, concurrency_group, concurrency_type, pull_request_poster_id, pull_request_id, workflow_directory, pre_execution_error_code, pre_execution_error_details
162 +
163 + action_run_index
164 + group_id, max_index
165 +
166 + action_run_job
167 + id, run_id, repo_id, owner_id, commit_sha, *is_fork_pull_request, name, attempt, workflow_payload, job_id, needs, runs_on, task_id, status, started, stopped, created, updated
168 +
169 + action_runner
170 + id, uuid, name, version, owner_id, repo_id, description, base, repo_range, token_hash, token_salt, last_online, last_active, agent_labels, created, updated, deleted
171 +
172 + action_runner_token
173 + id, token, owner_id, repo_id, *is_active, created, updated, deleted
174 +
175 + action_schedule
176 + id, title, specs, repo_id, owner_id, workflow_id, trigger_user_id, ref, commit_sha, event, event_payload, content, created, updated, workflow_directory
177 +
178 + action_schedule_spec
179 + id, repo_id, schedule_id, next, prev, spec, created, updated
180 +
181 + action_task
182 + id, job_id, attempt, runner_id, status, started, stopped, repo_id, owner_id, commit_sha, *is_fork_pull_request, token_hash, token_salt, token_last_eight, log_filename, *log_in_storage, log_length, log_size, log_indexes, *log_expired, created, updated
183 +
184 + action_task_output
185 + id, task_id, output_key, output_value
186 +
187 + action_task_step
188 + id, name, task_id, index, repo_id, status, log_index, log_length, started, stopped, created, updated
189 +
190 + action_tasks_version
191 + id, owner_id, repo_id, version, created_unix, updated_unix
192 +
193 + action_variable
194 + id, owner_id, repo_id, name, data, created_unix, updated_unix
195 +
196 + task
197 + id, doer_id, owner_id, repo_id, type, status, start_time, end_time, payload_content, message, created
198 +
199 + gpg_key
200 + id, owner_id, key_id, primary_key_id, content, created_unix, expired_unix, added_unix, emails, *verified, *can_sign, *can_encrypt_comms, *can_encrypt_storage, *can_certify
201 +
202 + gpg_key_import
203 + key_id, content
204 +
205 + public_key
206 + id, owner_id, name, fingerprint, content, mode, type, login_source_id, created_unix, updated_unix, *verified
207 +
208 + deploy_key
209 + id, key_id, repo_id, name, fingerprint, mode, created_unix, updated_unix
210 +
211 + project_board
212 + id, title, *default, sorting, color, project_id, creator_id, created_unix, updated_unix
213 +
214 + project_issue
215 + id, issue_id, project_id, project_board_id, sorting
216 +
217 + project
218 + id, title, description, owner_id, repo_id, creator_id, *is_closed, board_type, card_type, type, created_unix, updated_unix, closed_date_unix
219 +
220 + pull_auto_merge
221 + id, pull_id, doer_id, merge_style, message, created_unix, *delete_branch_after_merge
222 +
223 + review_state
224 + id, user_id, pull_id, commit_sha, updated_files, updated_unix
225 +
226 + secret
227 + id, owner_id, repo_id, name, created_unix, data
228 +
229 + org_user
230 + id, uid, org_id, *is_public
231 +
232 + team
233 + id, org_id, lower_name, name, description, authorize, num_repos, num_members, *includes_all_repositories, *can_create_org_repo
234 +
235 + team_user
236 + id, org_id, team_id, uid
237 +
238 + team_repo
239 + id, org_id, team_id, repo_id
240 +
241 + team_unit
242 + id, org_id, team_id, type, access_mode
243 +
244 + team_invite
245 + id, token, inviter_id, org_id, team_id, email, created_unix, updated_unix
246 +
247 + branch
248 + id, repo_id, name, commit_id, commit_message, pusher_id, *is_deleted, deleted_by_id, deleted_unix, commit_time, created_unix, updated_unix
249 +
250 + renamed_branch
251 + id, repo_id, from, to, created_unix
252 +
253 + commit_status
254 + id, index, repo_id, state, sha, target_url, description, context_hash, context, creator_id, created_unix, updated_unix
255 +
256 + commit_status_index
257 + id, repo_id, sha, max_index
258 +
259 + commit_status_summary
260 + id, repo_id, sha, state, target_url
261 +
262 + lfs_meta_object
263 + id, oid, size, repository_id, created_unix, updated_unix
264 +
265 + lfs_lock
266 + id, repo_id, owner_id, path, !created
267 +
268 + protected_branch
269 + id, repo_id, branch_name, *can_push, *enable_whitelist, whitelist_user_i_ds, whitelist_team_i_ds, *enable_merge_whitelist, whitelist_deploy_keys, merge_whitelist_user_i_ds, merge_whitelist_team_i_ds, *enable_status_check, status_check_contexts, *enable_approvals_whitelist, approvals_whitelist_user_i_ds, approvals_whitelist_team_i_ds, required_approvals, *block_on_rejected_reviews, *block_on_official_review_requests, *block_on_outdated_branch, *dismiss_stale_approvals, *require_signed_commits, protected_file_patterns, unprotected_file_patterns, *apply_to_admins, created_unix, updated_unix, *ignore_stale_approvals
270 +
271 + protected_tag
272 + id, repo_id, name_pattern, allowlist_user_i_ds, allowlist_team_i_ds, created_unix, updated_unix
273 +
274 + package
275 + id, owner_id, repo_id, type, name, lower_name, *semver_compatible, *is_internal
276 +
277 + package_blob
278 + id, size, hash_md5, hash_sha1, hash_sha256, hash_sha512, created_unix, hash_blake2b
279 +
280 + package_blob_upload
281 + id, bytes_received, hash_state_bytes, created_unix, updated_unix
282 +
283 + package_cleanup_rule
284 + id, *enabled, owner_id, type, keep_count, keep_pattern, remove_days, remove_pattern, *match_full_name, created_unix, updated_unix
285 +
286 + package_file
287 + id, version_id, blob_id, name, lower_name, composite_key, *is_lead, created_unix
288 +
289 + package_property
290 + id, ref_type, ref_id, name, value
291 +
292 + package_version
293 + id, package_id, creator_id, version, lower_version, created_unix, *is_internal, metadata_json, download_count
294 +
295 + quota_rule
296 + name, limit, subjects
297 +
298 + quota_group
299 + name
300 +
301 + quota_group_rule_mapping
302 + id, group_name, rule_name
303 +
304 + quota_group_mapping
305 + id, kind, mapped_id, group_name
306 +
307 + issue_assignees
308 + id, assignee_id, issue_id
309 +
310 + comment
311 + id, type, poster_id, original_author, original_author_id, issue_id, label_id, old_project_id, project_id, old_milestone_id, milestone_id, time_id, assignee_id, *removed_assignee, assignee_team_id, resolve_doer_id, old_title, new_title, old_ref, new_ref, dependent_issue_id, commit_id, line, tree_path, content, content_version, patch, created_unix, updated_unix, commit_sha, review_id, *invalidated, ref_repo_id, ref_issue_id, ref_comment_id, ref_action, *ref_is_pull
312 +
313 + issue_content_history
314 + id, poster_id, issue_id, comment_id, edited_unix, content_text, *is_first_created, *is_deleted
315 +
316 + issue_dependency
317 + id, user_id, issue_id, dependency_id, created_unix, updated_unix
318 +
319 + issue_index
320 + group_id, max_index
321 +
322 + issue_user
323 + id, uid, issue_id, *is_read, *is_mentioned
324 +
325 + issue_watch
326 + id, user_id, issue_id, *is_watching, created_unix, updated_unix
327 +
328 + label
329 + id, repo_id, org_id, name, *exclusive, description, color, num_issues, num_closed_issues, created_unix, updated_unix, archived_unix
330 +
331 + issue_label
332 + id, issue_id, label_id
333 +
334 + milestone
335 + id, repo_id, name, content, *is_closed, num_issues, num_closed_issues, completeness, created_unix, updated_unix, deadline_unix, closed_date_unix
336 +
337 + reaction
338 + id, type, issue_id, comment_id, user_id, original_author_id, original_author, created_unix
339 +
340 + review
341 + id, type, reviewer_id, reviewer_team_id, original_author, original_author_id, issue_id, content, *official, commit_id, *stale, *dismissed, created_unix, updated_unix
342 +
343 + repo_transfer
344 + id, doer_id, recipient_id, repo_id, team_i_ds, created_unix, updated_unix
345 +
346 + action
347 + id, user_id, op_type, act_user_id, repo_id, comment_id, ref_name, *is_private, content, created_unix
348 +
349 + federated_user_activity
350 + id, user_id, actor_id, actor_uri, note_content, note_url, original_note, created
351 +
352 + notification
353 + id, user_id, repo_id, status, source, issue_id, comment_id, created_unix, updated_unix
354 +
355 + forgejo_auth_token
356 + id, uid, lookup_key, hashed_validator, expiry, purpose
357 +
358 + repository
359 + id, owner_id, owner_name, lower_name, name, description, website, original_service_type, original_url, default_branch, wiki_branch, num_watches, num_stars, num_forks, num_milestones, num_closed_milestones, num_projects, num_closed_projects, *is_private, *is_empty, *is_archived, *is_mirror, status, *is_fork, fork_id, *is_template, template_id, size, git_size, lfs_size, *is_fsck_enabled, *close_issues_via_commit_in_any_branch, object_format_name, trust_model, avatar, created_unix, updated_unix, archived_unix, topics
360 +
361 + collaboration
362 + id, repo_id, user_id, mode, created_unix, updated_unix
363 +
364 + action_user
365 + id, user_id, repo_id, *trusted_with_pull_requests, last_access
366 +
367 + access
368 + id, user_id, repo_id, mode
369 +
370 + issue
371 + id, repo_id, index, poster_id, original_author, original_author_id, name, content, content_version, milestone_id, priority, *is_closed, *is_pull, num_comments, ref, pin_order, deadline_unix, created, created_unix, updated_unix, closed_unix, *is_locked
372 +
373 + pull_request
374 + id, type, status, conflicted_files, commits_ahead, commits_behind, changed_protected_files, issue_id, index, head_repo_id, head_branch, base_branch, merge_base, *allow_maintainer_edit, *has_merged, merger_id, flow, base_repo_id, merged_unix, merged_commit_id
375 +
376 + stopwatch
377 + id, issue_id, user_id, created_unix
378 +
379 + tracked_time
380 + id, issue_id, user_id, created_unix, time, *deleted

migrate.py(file created)

@@ -0,0 +1,79 @@
1 + import sqlite3
2 + import psycopg2
3 + import re
4 + from datetime import datetime
5 +
6 + # Change these
7 + SQLITE_DB = "forgejo.db"
8 + DB_NAME = "forgejodb"
9 + DB_USER = "forgejo"
10 + DB_PASS = "hunter2"
11 + DB_HOST = "localhost"
12 + DB_PORT = "5432"
13 +
14 + rules = {x.split("\n")[0].strip(): x.split("\n")[1].strip().split(", ") for x in re.split(r'\n\s*\n', open("lol").read().strip())}
15 +
16 + print("[OK] Rules loaded.")
17 +
18 + # Prefix: !
19 + def timestamp_conversion(ts):
20 + if not ts:
21 + return None
22 + return datetime.strptime(ts, "%Y-%m-%d %H:%M:%S")
23 +
24 + # Prefix: *
25 + def int_to_bool(integ):
26 + return integ == 1
27 +
28 + # Dry run, verify the thingies all exist
29 +
30 + print("[...] Starting dry run...")
31 +
32 + sqdb = sqlite3.connect(SQLITE_DB)
33 + sqursor = sqdb.cursor()
34 +
35 + bad = 0
36 +
37 + for table, col in rules.items():
38 + sqursor.execute(f"PRAGMA table_info({table});")
39 + tables_there = sqursor.fetchall()
40 + if len(col) != len(tables_there):
41 + extras = [x[1] for x in tables_there]
42 + for i in col:
43 + extras.remove(i.replace("*", "").replace("!", ""))
44 + print("[!!!] " + table + f" extra columns: {extras}")
45 + bad += 1
46 +
47 + if bad:
48 + print(f"[!!!] {bad} tables found with not enough items")
49 +
50 + print("[OK] Everything is okay!")
51 + input("Press enter to start, press ctrl+c to stop...")
52 +
53 + conn = psycopg2.connect(database=DB_NAME,
54 + user=DB_USER,
55 + password=DB_PASS,
56 + host=DB_HOST,
57 + port=DB_PORT)
58 +
59 + cursor = conn.cursor()
60 +
61 + for table, col in rules.items():
62 + print("[...] Working on " + table, end="", flush=True)
63 + colstring = ", ".join(["\"" + x.replace("*", "").replace("!", "") + "\"" for x in col])
64 + ph = ", ".join(["%s"] * len(col))
65 + items = sqursor.execute(f"SELECT {colstring} FROM {table};").fetchall()
66 + for row in items:
67 + newrow = []
68 + for i, cols in enumerate(col):
69 + if cols[0] == "*":
70 + newrow.append(int_to_bool(row[i]))
71 + elif cols[0] == "!":
72 + newrow.append(timestamp_conversion(row[i]))
73 + else:
74 + newrow.append(row[i])
75 + cursor.execute(f"INSERT INTO \"{table}\" ({colstring}) VALUES ({ph})", newrow)
76 + print("\r[OK] Done working on " + table)
77 +
78 + conn.commit()
79 + print("[FIN] Migration is done! Enjoy!")
Newer Older