full_search 0.4.3 → 0.4.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 894bce4229c00412829f531fbb35c78a3b9a3b4ac869ddc23e67421d1abc773b
4
- data.tar.gz: 3a9504c246aced49dcef0b9991efddf53fdbff873c0ddf7e6781e6551550af71
3
+ metadata.gz: 99b631f72162065698bc187ad0b88cb7602cbead185b5c82209db713774e763d
4
+ data.tar.gz: 5e1dd5a0782e69cba81b0b2c8f32170046f4c0e3ad55debb063837117285a559
5
5
  SHA512:
6
- metadata.gz: aea83a66af28bf651dd022c63725d012dea6783e57125c5febbf7e48582fe4ac8990cd30af6d9c72bc9544ae3fbf925e84c03a060c549a1b79aaf65668bb2705
7
- data.tar.gz: 9d9d227f097f3c1b5629aa6ced3768e2cb99db6fdafa28ca15ce641afac2ed4af7f15892d6b7fc87316246eb1be7fd02cdd81db1d1f16407fcf2f8a574d20af6
6
+ metadata.gz: 146763f433fba78ed55b6a638b1d8a80bed0ea886daf294ff8e9389d09efef104b7ae6729d8897ee3ea267a4d38cf5d9956e691f4524da4a0861df6827c909ba
7
+ data.tar.gz: 65c5e59005e1730e12fadda9126b397a5fffdef462bcda088e7f14259b3635d1df7356d91dd23ebb312e6403489bf461b6088fc29a68b86b38fdbb80c4786ac2
@@ -71,8 +71,8 @@ module FullSearch
71
71
  with_rebuild_lock(model) do
72
72
  FullSearch::Instrumentation.instrument("rebuild", model: model.name) do
73
73
  drop_triggers!(model)
74
- conn.execute("DROP TABLE IF EXISTS #{qt(fts_table_name(model))};")
75
- conn.execute("DROP TABLE IF EXISTS #{qt(trigram_table_name(model))};")
74
+ drop_fts_table_safely!(fts_table_name(model))
75
+ drop_fts_table_safely!(trigram_table_name(model))
76
76
  conn.execute(create_virtual_table_sql(model))
77
77
  if trigram_table_needed?(model)
78
78
  FullSearch::Typo.warn_unsupported!(model) unless FullSearch::Typo.supported?(model)
@@ -181,8 +181,32 @@ module FullSearch
181
181
  verified_tables.delete(model.table_name)
182
182
  sqlite!(model)
183
183
  drop_triggers!(model)
184
- connection.execute("DROP TABLE IF EXISTS #{qt(fts_table_name(model))};")
185
- connection.execute("DROP TABLE IF EXISTS #{qt(trigram_table_name(model))};")
184
+ drop_fts_table_safely!(fts_table_name(model))
185
+ drop_fts_table_safely!(trigram_table_name(model))
186
+ end
187
+ # Drops an FTS5 virtual table, recovering from corruption where a bare
188
+ # DROP TABLE IF EXISTS raises "invalid fts5 file format" because the
189
+ # shadow tables were tampered with out-of-band. When that happens we
190
+ # drop the shadow tables directly, then drop the (now-empty) virtual
191
+ # table wrapper, so the caller can recreate a clean index.
192
+ def drop_fts_table_safely!(table_name)
193
+ connection.execute("DROP TABLE IF EXISTS #{qt(table_name)};")
194
+ rescue ActiveRecord::StatementInvalid => e
195
+ raise unless e.message.match?(/fts5: corruption|invalid fts5 file format|malformed database schema/i)
196
+
197
+ drop_shadow_tables!(table_name)
198
+ connection.execute("DROP TABLE IF EXISTS #{qt(table_name)};")
199
+ end
200
+
201
+ # FTS5 stores its index data in a fixed set of shadow tables named
202
+ # <table>_content, <table>_data, <table>_idx, <table>_docsize and
203
+ # <table>_config. Dropping these lets SQLite recover a virtual table
204
+ # that is otherwise undroppable due to internal corruption.
205
+ def drop_shadow_tables!(table_name)
206
+ %w[content data idx docsize config].each do |suffix|
207
+ shadow = "#{table_name}_#{suffix}"
208
+ connection.execute("DROP TABLE IF EXISTS #{qt(shadow)};")
209
+ end
186
210
  end
187
211
 
188
212
  def fts_table_name(model)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module FullSearch
4
- VERSION = "0.4.3"
4
+ VERSION = "0.4.4"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: full_search
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.3
4
+ version: 0.4.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ben D'Angelo