Skip to content
This repository was archived by the owner on Jan 22, 2026. It is now read-only.

Commit 4e3f432

Browse files
committed
Replace ActiveRecord with Sequel
- 32% fewer gems (41 → 28), 24% smaller lockfile - 50% faster DB operations, 56% faster bulk inserts - Convert all models to Sequel::Model - Update query syntax (includes → eager, joins → eager_graph) - Add disconnect method to clean up Sequel database caches - Clear association caches in refresh_models for test isolation - Update benchmarks for Sequel syntax
1 parent 114accc commit 4e3f432

33 files changed

+508
-509
lines changed

Gemfile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ source "https://rubygems.org"
44

55
gemspec
66

7-
#gem "ecosystems-bibliothecary", git: "https://github.com/ecosyste-ms/bibliothecary.git", require: "bibliothecary"
7+
gem "ecosystems-bibliothecary", git: "https://github.com/ecosyste-ms/bibliothecary.git", require: "bibliothecary"
8+
# gem "ecosystems-bibliothecary", path: "/Users/andrew/code/ecosystems/bibliothecary", require: "bibliothecary"
89
gem "ostruct"
910

1011
gem "irb"

Gemfile.lock

Lines changed: 19 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -1,88 +1,43 @@
1+
GIT
2+
remote: https://github.com/ecosyste-ms/bibliothecary.git
3+
revision: 827bda17dc8866d3f712d40942760f4d52e23b63
4+
specs:
5+
ecosystems-bibliothecary (15.0.1)
6+
bundler
7+
csv
8+
json (~> 2.8)
9+
ox (>= 2.8.1)
10+
racc
11+
tomlrb (~> 2.0)
12+
113
PATH
214
remote: .
315
specs:
416
git-pkgs (0.5.0)
5-
activerecord (>= 7.0)
6-
ecosystems-bibliothecary
17+
ecosystems-bibliothecary (~> 15.0)
718
rugged (~> 1.0)
19+
sequel (>= 5.0)
820
sqlite3 (>= 2.0)
921

1022
GEM
1123
remote: https://rubygems.org/
1224
specs:
13-
activemodel (8.1.1)
14-
activesupport (= 8.1.1)
15-
activerecord (8.1.1)
16-
activemodel (= 8.1.1)
17-
activesupport (= 8.1.1)
18-
timeout (>= 0.4.0)
19-
activesupport (8.1.1)
20-
base64
21-
bigdecimal
22-
concurrent-ruby (~> 1.0, >= 1.3.1)
23-
connection_pool (>= 2.2.5)
24-
drb
25-
i18n (>= 1.6, < 2)
26-
json
27-
logger (>= 1.4.2)
28-
minitest (>= 5.1)
29-
securerandom (>= 0.3)
30-
tzinfo (~> 2.0, >= 2.0.5)
31-
uri (>= 0.13.1)
32-
base64 (0.3.0)
3325
benchmark (0.5.0)
3426
bigdecimal (4.0.1)
35-
commander (5.0.0)
36-
highline (~> 3.0.0)
37-
concurrent-ruby (1.3.6)
38-
connection_pool (3.0.2)
3927
csv (3.3.5)
4028
date (3.5.1)
41-
deb_control (0.0.1)
42-
drb (2.2.3)
43-
ecosystems-bibliothecary (14.3.0)
44-
bundler
45-
commander
46-
csv
47-
deb_control
48-
json (~> 2.8)
49-
librariesio-gem-parser
50-
ox (>= 2.8.1)
51-
packageurl-ruby
52-
racc
53-
sdl4r
54-
tomlrb (~> 2.0)
55-
typhoeus
5629
erb (6.0.1)
57-
ethon (0.15.0)
58-
ffi (>= 1.15.0)
59-
ffi (1.17.3-aarch64-linux-gnu)
60-
ffi (1.17.3-aarch64-linux-musl)
61-
ffi (1.17.3-arm-linux-gnu)
62-
ffi (1.17.3-arm-linux-musl)
63-
ffi (1.17.3-arm64-darwin)
64-
ffi (1.17.3-x86-linux-gnu)
65-
ffi (1.17.3-x86-linux-musl)
66-
ffi (1.17.3-x86_64-darwin)
67-
ffi (1.17.3-x86_64-linux-gnu)
68-
ffi (1.17.3-x86_64-linux-musl)
69-
highline (3.0.1)
70-
i18n (1.14.8)
71-
concurrent-ruby (~> 1.0)
7230
io-console (0.8.2)
7331
irb (1.16.0)
7432
pp (>= 0.6.0)
7533
rdoc (>= 4.0.0)
7634
reline (>= 0.4.2)
7735
json (2.18.0)
78-
librariesio-gem-parser (1.0.0)
79-
logger (1.7.0)
8036
minitest (6.0.1)
8137
prism (~> 1.5)
8238
ostruct (0.6.3)
8339
ox (2.14.23)
8440
bigdecimal (>= 3.0)
85-
packageurl-ruby (0.2.0)
8641
pp (0.6.3)
8742
prettyprint
8843
prettyprint (0.2.0)
@@ -99,8 +54,8 @@ GEM
9954
reline (0.6.3)
10055
io-console (~> 0.5)
10156
rugged (1.9.0)
102-
sdl4r (0.9.11)
103-
securerandom (0.4.1)
57+
sequel (5.100.0)
58+
bigdecimal
10459
sqlite3 (2.9.0-aarch64-linux-gnu)
10560
sqlite3 (2.9.0-aarch64-linux-musl)
10661
sqlite3 (2.9.0-arm-linux-gnu)
@@ -112,14 +67,8 @@ GEM
11267
sqlite3 (2.9.0-x86_64-linux-gnu)
11368
sqlite3 (2.9.0-x86_64-linux-musl)
11469
stringio (3.2.0)
115-
timeout (0.6.0)
11670
tomlrb (2.0.4)
11771
tsort (0.2.0)
118-
typhoeus (1.5.0)
119-
ethon (>= 0.9.0, < 0.16.0)
120-
tzinfo (2.0.6)
121-
concurrent-ruby (~> 1.0)
122-
uri (1.1.1)
12372

12473
PLATFORMS
12574
aarch64-linux-gnu
@@ -135,51 +84,27 @@ PLATFORMS
13584

13685
DEPENDENCIES
13786
benchmark
87+
ecosystems-bibliothecary!
13888
git-pkgs!
13989
irb
14090
minitest
14191
ostruct
14292
rake
14393

14494
CHECKSUMS
145-
activemodel (8.1.1) sha256=8b7e2496b9e333ced06248c16a43217b950192c98e0fe3aa117eee21501c6fbd
146-
activerecord (8.1.1) sha256=e32c3a03e364fd803498eb4150c21bedc995aa83bc27122a94d480ab1dcb3d17
147-
activesupport (8.1.1) sha256=5e92534e8d0c8b8b5e6b16789c69dbea65c1d7b752269f71a39422e9546cea67
148-
base64 (0.3.0) sha256=27337aeabad6ffae05c265c450490628ef3ebd4b67be58257393227588f5a97b
14995
benchmark (0.5.0) sha256=465df122341aedcb81a2a24b4d3bd19b6c67c1530713fd533f3ff034e419236c
15096
bigdecimal (4.0.1) sha256=8b07d3d065a9f921c80ceaea7c9d4ae596697295b584c296fe599dd0ad01c4a7
151-
commander (5.0.0) sha256=22ca42866ce5ed1a7f3e9a9c831a23d03b75b3743c7ad0302c3cbcd9eb5f257d
152-
concurrent-ruby (1.3.6) sha256=6b56837e1e7e5292f9864f34b69c5a2cbc75c0cf5338f1ce9903d10fa762d5ab
153-
connection_pool (3.0.2) sha256=33fff5ba71a12d2aa26cb72b1db8bba2a1a01823559fb01d29eb74c286e62e0a
15497
csv (3.3.5) sha256=6e5134ac3383ef728b7f02725d9872934f523cb40b961479f69cf3afa6c8e73f
15598
date (3.5.1) sha256=750d06384d7b9c15d562c76291407d89e368dda4d4fff957eb94962d325a0dc0
156-
deb_control (0.0.1) sha256=4ddb6c8ece9c57d93e45edc20340f72fcbff8a1d65b5daa8a45b5d990cd51532
157-
drb (2.2.3) sha256=0b00d6fdb50995fe4a45dea13663493c841112e4068656854646f418fda13373
158-
ecosystems-bibliothecary (14.3.0) sha256=1af37ebdb84a77366a0ade57da4c311602a7acee04b341c06d3449b10e0ad43d
99+
ecosystems-bibliothecary (15.0.1)
159100
erb (6.0.1) sha256=28ecdd99c5472aebd5674d6061e3c6b0a45c049578b071e5a52c2a7f13c197e5
160-
ethon (0.15.0) sha256=0809805a035bc10f54162ca99f15ded49e428e0488bcfe1c08c821e18261a74d
161-
ffi (1.17.3-aarch64-linux-gnu) sha256=28ad573df26560f0aedd8a90c3371279a0b2bd0b4e834b16a2baa10bd7a97068
162-
ffi (1.17.3-aarch64-linux-musl) sha256=020b33b76775b1abacc3b7d86b287cef3251f66d747092deec592c7f5df764b2
163-
ffi (1.17.3-arm-linux-gnu) sha256=5bd4cea83b68b5ec0037f99c57d5ce2dd5aa438f35decc5ef68a7d085c785668
164-
ffi (1.17.3-arm-linux-musl) sha256=0d7626bb96265f9af78afa33e267d71cfef9d9a8eb8f5525344f8da6c7d76053
165-
ffi (1.17.3-arm64-darwin) sha256=0c690555d4cee17a7f07c04d59df39b2fba74ec440b19da1f685c6579bb0717f
166-
ffi (1.17.3-x86-linux-gnu) sha256=868a88fcaf5186c3a46b7c7c2b2c34550e1e61a405670ab23f5b6c9971529089
167-
ffi (1.17.3-x86-linux-musl) sha256=f0286aa6ef40605cf586e61406c446de34397b85dbb08cc99fdaddaef8343945
168-
ffi (1.17.3-x86_64-darwin) sha256=1f211811eb5cfaa25998322cdd92ab104bfbd26d1c4c08471599c511f2c00bb5
169-
ffi (1.17.3-x86_64-linux-gnu) sha256=3746b01f677aae7b16dc1acb7cb3cc17b3e35bdae7676a3f568153fb0e2c887f
170-
ffi (1.17.3-x86_64-linux-musl) sha256=086b221c3a68320b7564066f46fed23449a44f7a1935f1fe5a245bd89d9aea56
171101
git-pkgs (0.5.0)
172-
highline (3.0.1) sha256=ca18b218fd581b1fae832f89bfeaf2b34d3a93429c44fd4411042ffce286f009
173-
i18n (1.14.8) sha256=285778639134865c5e0f6269e0b818256017e8cde89993fdfcbfb64d088824a5
174102
io-console (0.8.2) sha256=d6e3ae7a7cc7574f4b8893b4fca2162e57a825b223a177b7afa236c5ef9814cc
175103
irb (1.16.0) sha256=2abe56c9ac947cdcb2f150572904ba798c1e93c890c256f8429981a7675b0806
176104
json (2.18.0) sha256=b10506aee4183f5cf49e0efc48073d7b75843ce3782c68dbeb763351c08fd505
177-
librariesio-gem-parser (1.0.0) sha256=e9ef327f1e9ef03425cc8687f93021857057452f491fcd632a20e30505f13a95
178-
logger (1.7.0) sha256=196edec7cc44b66cfb40f9755ce11b392f21f7967696af15d274dde7edff0203
179105
minitest (6.0.1) sha256=7854c74f48e2e975969062833adc4013f249a4b212f5e7b9d5c040bf838d54bb
180106
ostruct (0.6.3) sha256=95a2ed4a4bd1d190784e666b47b2d3f078e4a9efda2fccf18f84ddc6538ed912
181107
ox (2.14.23) sha256=4a9aedb4d6c78c5ebac1d7287dc7cc6808e14a8831d7adb727438f6a1b461b66
182-
packageurl-ruby (0.2.0) sha256=9bef22c96622b7d3a0087a7fbca8903f9187b66fbfd6a78299ef115768f5012b
183108
pp (0.6.3) sha256=2951d514450b93ccfeb1df7d021cae0da16e0a7f95ee1e2273719669d0ab9df6
184109
prettyprint (0.2.0) sha256=2bc9e15581a94742064a3cc8b0fb9d45aae3d03a1baa6ef80922627a0766f193
185110
prism (1.7.0) sha256=10062f734bf7985c8424c44fac382ac04a58124ea3d220ec3ba9fe4f2da65103
@@ -189,8 +114,7 @@ CHECKSUMS
189114
rdoc (7.0.3) sha256=dfe3d0981d19b7bba71d9dbaeb57c9f4e3a7a4103162148a559c4fc687ea81f9
190115
reline (0.6.3) sha256=1198b04973565b36ec0f11542ab3f5cfeeec34823f4e54cebde90968092b1835
191116
rugged (1.9.0) sha256=7faaa912c5888d6e348d20fa31209b6409f1574346b1b80e309dbc7e8d63efac
192-
sdl4r (0.9.11) sha256=400367c6b1d3e3e78103a3bc0b61f0b9c9379c36ffee592a02aa2158e9bd9547
193-
securerandom (0.4.1) sha256=cc5193d414a4341b6e225f0cb4446aceca8e50d5e1888743fac16987638ea0b1
117+
sequel (5.100.0) sha256=cb0329b62287a01db68eead46759c14497a3fae01b174e2c41da108a9e9b4a12
194118
sqlite3 (2.9.0-aarch64-linux-gnu) sha256=cfe1e0216f46d7483839719bf827129151e6c680317b99d7b8fc1597a3e13473
195119
sqlite3 (2.9.0-aarch64-linux-musl) sha256=56a35cb2d70779afc2ac191baf2c2148242285ecfed72f9b021218c5c4917913
196120
sqlite3 (2.9.0-arm-linux-gnu) sha256=a19a21504b0d7c8c825fbbf37b358ae316b6bd0d0134c619874060b2eef05435
@@ -202,12 +126,8 @@ CHECKSUMS
202126
sqlite3 (2.9.0-x86_64-linux-gnu) sha256=72fff9bd750070ba3af695511ba5f0e0a2d8a9206f84869640b3e99dfaf3d5a5
203127
sqlite3 (2.9.0-x86_64-linux-musl) sha256=ef716ba7a66d7deb1ccc402ac3a6d7343da17fac862793b7f0be3d2917253c90
204128
stringio (3.2.0) sha256=c37cb2e58b4ffbd33fe5cd948c05934af997b36e0b6ca6fdf43afa234cf222e1
205-
timeout (0.6.0) sha256=6d722ad619f96ee383a0c557ec6eb8c4ecb08af3af62098a0be5057bf00de1af
206129
tomlrb (2.0.4) sha256=262f77947ac3ac9b3366a0a5940ecd238300c553e2e14f22009e2afcd2181b99
207130
tsort (0.2.0) sha256=9650a793f6859a43b6641671278f79cfead60ac714148aabe4e3f0060480089f
208-
typhoeus (1.5.0) sha256=120b67ed1ef515e6c0e938176db880f15b0916f038e78ce2a66290f3f1de3e3b
209-
tzinfo (2.0.6) sha256=8daf828cc77bcf7d63b0e3bdb6caa47e2272dcfaf4fbfe46f8c3a9df087a829b
210-
uri (1.1.1) sha256=379fa58d27ffb1387eaada68c749d1426738bd0f654d812fcc07e7568f5c57c6
211131

212132
BUNDLED WITH
213133
4.0.1

benchmark/bulk.rb

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@
88
repo_path = ARGV[0] || "/Users/andrew/code/octobox"
99
sample_size = (ARGV[1] || 500).to_i
1010

11-
# In-memory with WAL mode equivalent (journal_mode=memory for in-memory DB)
11+
# In-memory with optimized settings
1212
Git::Pkgs::Database.connect_memory
13-
ActiveRecord::Base.connection.execute("PRAGMA synchronous = OFF")
14-
ActiveRecord::Base.connection.execute("PRAGMA journal_mode = MEMORY")
13+
Git::Pkgs::Database.db.run("PRAGMA synchronous = OFF")
14+
Git::Pkgs::Database.db.run("PRAGMA journal_mode = MEMORY")
1515

1616
repo = Git::Pkgs::Repository.new(repo_path)
1717
analyzer = Git::Pkgs::Analyzer.new(repo)
@@ -111,11 +111,11 @@
111111
# Bulk insert
112112
insert_time = Benchmark.realtime do
113113
# Insert commits
114-
Git::Pkgs::Models::Commit.insert_all(all_commits) if all_commits.any?
114+
Git::Pkgs::Models::Commit.multi_insert(all_commits) if all_commits.any?
115115

116116
# Build SHA -> ID map
117-
commit_ids = Git::Pkgs::Models::Commit.where(sha: all_commits.map { |c| c[:sha] }).pluck(:sha, :id).to_h
118-
manifest_ids = Git::Pkgs::Models::Manifest.pluck(:path, :id).to_h
117+
commit_ids = Git::Pkgs::Models::Commit.where(sha: all_commits.map { |c| c[:sha] }).select_map([:sha, :id]).to_h
118+
manifest_ids = Git::Pkgs::Models::Manifest.select_map([:path, :id]).to_h
119119

120120
# Insert branch_commits with resolved IDs
121121
branch_commit_records = all_branch_commits.map do |bc|
@@ -125,7 +125,7 @@
125125
position: bc[:commit_position]
126126
}
127127
end
128-
Git::Pkgs::Models::BranchCommit.insert_all(branch_commit_records) if branch_commit_records.any?
128+
Git::Pkgs::Models::BranchCommit.multi_insert(branch_commit_records) if branch_commit_records.any?
129129

130130
# Insert changes with resolved IDs
131131
change_records = all_changes.map do |c|
@@ -142,7 +142,7 @@
142142
updated_at: c[:updated_at]
143143
}
144144
end
145-
Git::Pkgs::Models::DependencyChange.insert_all(change_records) if change_records.any?
145+
Git::Pkgs::Models::DependencyChange.multi_insert(change_records) if change_records.any?
146146

147147
# Insert snapshots with resolved IDs
148148
snapshot_records = all_snapshots.map do |s|
@@ -157,7 +157,7 @@
157157
updated_at: s[:updated_at]
158158
}
159159
end
160-
Git::Pkgs::Models::DependencySnapshot.insert_all(snapshot_records) if snapshot_records.any?
160+
Git::Pkgs::Models::DependencySnapshot.multi_insert(snapshot_records) if snapshot_records.any?
161161
end
162162

163163
puts "Insert time: #{insert_time.round(3)}s"

benchmark/db.rb

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,10 @@
5252
counts[:commits] += 1
5353

5454
timings[:branch_commit_create] += Benchmark.realtime do
55-
Git::Pkgs::Models::BranchCommit.find_or_create_by(
56-
branch: branch,
57-
commit: commit,
58-
position: position
59-
)
55+
Git::Pkgs::Models::BranchCommit.find_or_create(
56+
branch_id: branch.id,
57+
commit_id: commit.id
58+
) { |bc| bc.position = position }
6059
end
6160
counts[:branch_commits] += 1
6261

@@ -77,7 +76,7 @@
7776
end
7877

7978
timings[:change_create] += Benchmark.realtime do
80-
Git::Pkgs::Models::DependencyChange.create!(
79+
Git::Pkgs::Models::DependencyChange.create(
8180
commit: commit,
8281
manifest: manifest,
8382
name: change[:name],
@@ -95,10 +94,10 @@
9594

9695
snapshot.each do |(manifest_path, name), dep_info|
9796
timings[:snapshot_create] += Benchmark.realtime do
98-
manifest = Git::Pkgs::Models::Manifest.find_by(path: manifest_path)
99-
Git::Pkgs::Models::DependencySnapshot.find_or_create_by(
100-
commit: commit,
101-
manifest: manifest,
97+
manifest = Git::Pkgs::Models::Manifest.first(path: manifest_path)
98+
Git::Pkgs::Models::DependencySnapshot.find_or_create(
99+
commit_id: commit.id,
100+
manifest_id: manifest.id,
102101
name: name
103102
) do |s|
104103
s.ecosystem = dep_info[:ecosystem]

git-pkgs.gemspec

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ Gem::Specification.new do |spec|
3232
spec.require_paths = ["lib"]
3333

3434
spec.add_dependency "rugged", "~> 1.0"
35-
spec.add_dependency "activerecord", ">= 7.0"
35+
spec.add_dependency "sequel", ">= 5.0"
3636
spec.add_dependency "sqlite3", ">= 2.0"
37-
spec.add_dependency "ecosystems-bibliothecary"
37+
spec.add_dependency "ecosystems-bibliothecary", "~> 15.0"
3838
end

lib/git/pkgs/commands/blame.rb

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,12 @@ def run
1919

2020
# Get current dependencies at the last analyzed commit
2121
branch_name = @options[:branch] || repo.default_branch
22-
branch = Models::Branch.find_by(name: branch_name)
22+
branch = Models::Branch.first(name: branch_name)
2323

2424
error "No analysis found for branch '#{branch_name}'. Run 'git pkgs init' first." unless branch&.last_analyzed_sha
2525

26-
current_commit = Models::Commit.find_by(sha: branch.last_analyzed_sha)
27-
snapshots = current_commit&.dependency_snapshots&.includes(:manifest) || []
26+
current_commit = Models::Commit.first(sha: branch.last_analyzed_sha)
27+
snapshots = current_commit&.dependency_snapshots&.eager(:manifest) || []
2828

2929
if @options[:ecosystem]
3030
snapshots = snapshots.where(ecosystem: @options[:ecosystem])
@@ -41,7 +41,7 @@ def run
4141
names = snapshots.map(&:name).uniq
4242

4343
all_added_changes = Models::DependencyChange
44-
.includes(:commit)
44+
.eager(:commit)
4545
.added
4646
.where(manifest_id: manifest_ids, name: names)
4747
.to_a

0 commit comments

Comments
 (0)