Class: Woods::Storage::MetadataStore::SQLite
- Inherits:
-
Object
- Object
- Woods::Storage::MetadataStore::SQLite
- Includes:
- Interface
- Defined in:
- lib/woods/storage/metadata_store.rb
Overview
SQLite-backed metadata store using the JSON1 extension.
Stores unit metadata as JSON in a single table with type indexing for efficient filtering. Uses upsert semantics for store operations.
Instance Method Summary collapse
- #count ⇒ Object
- #delete(id) ⇒ Object
- #find(id) ⇒ Object
- #find_batch(ids) ⇒ Object
- #find_by_type(type) ⇒ Object
-
#initialize(db_path = ':memory:') ⇒ SQLite
constructor
A new instance of SQLite.
- #search(query, fields: nil) ⇒ Object
- #store(id, metadata) ⇒ Object
Constructor Details
#initialize(db_path = ':memory:') ⇒ SQLite
Returns a new instance of SQLite.
223 224 225 226 227 228 229 230 231 232 233 234 235 |
# File 'lib/woods/storage/metadata_store.rb', line 223 def initialize(db_path = ':memory:') begin require 'sqlite3' rescue LoadError raise Woods::ConfigurationError, 'metadata_store: :sqlite requires the sqlite3 gem in your Gemfile. ' \ "Add `gem 'sqlite3'` and re-bundle, or set " \ "`config.metadata_store = :in_memory` if you don't need cross-process persistence." end @db = ::SQLite3::Database.new(db_path) @db.results_as_hash = true create_table end |
Instance Method Details
#count ⇒ Object
293 294 295 |
# File 'lib/woods/storage/metadata_store.rb', line 293 def count @db.get_first_value('SELECT COUNT(*) FROM units') end |
#delete(id) ⇒ Object
288 289 290 |
# File 'lib/woods/storage/metadata_store.rb', line 288 def delete(id) @db.execute('DELETE FROM units WHERE id = ?', [id]) end |
#find(id) ⇒ Object
250 251 252 253 254 255 |
# File 'lib/woods/storage/metadata_store.rb', line 250 def find(id) row = @db.get_first_row('SELECT data FROM units WHERE id = ?', [id]) return nil unless row JSON.parse(row['data']) end |
#find_batch(ids) ⇒ Object
258 259 260 261 262 263 264 265 266 |
# File 'lib/woods/storage/metadata_store.rb', line 258 def find_batch(ids) return {} if ids.empty? placeholders = Array.new(ids.size, '?').join(', ') rows = @db.execute("SELECT id, data FROM units WHERE id IN (#{placeholders})", ids) rows.to_h do |row| [row['id'], JSON.parse(row['data'])] end end |
#find_by_type(type) ⇒ Object
269 270 271 272 |
# File 'lib/woods/storage/metadata_store.rb', line 269 def find_by_type(type) rows = @db.execute('SELECT id, data FROM units WHERE type = ?', [type.to_s]) rows.map { |row| parse_row(row) } end |
#search(query, fields: nil) ⇒ Object
275 276 277 278 279 280 281 282 283 284 285 |
# File 'lib/woods/storage/metadata_store.rb', line 275 def search(query, fields: nil) if fields conditions = fields.map { "json_extract(data, '$.#{_1}') LIKE ?" }.join(' OR ') params = fields.map { "%#{query}%" } rows = @db.execute("SELECT id, data FROM units WHERE #{conditions}", params) else rows = @db.execute('SELECT id, data FROM units WHERE data LIKE ?', ["%#{query}%"]) end rows.map { |row| parse_row(row) } end |
#store(id, metadata) ⇒ Object
238 239 240 241 242 243 244 245 246 247 |
# File 'lib/woods/storage/metadata_store.rb', line 238 def store(id, ) type = [:type] || ['type'] data = JSON.generate() @db.execute(<<~SQL, [id, type.to_s, data, Time.now.iso8601]) INSERT INTO units (id, type, data, updated_at) VALUES (?, ?, ?, ?) ON CONFLICT(id) DO UPDATE SET type = excluded.type, data = excluded.data, updated_at = excluded.updated_at SQL end |