Class: S3arch::Store

Inherits:
Object
  • Object
show all
Defined in:
lib/s3arch/store.rb

Overview

Thin adapter layer encapsulating all DynamoDB/S3 operations for index lifecycle. Indexer and Searcher delegate here instead of calling AWS SDKs directly.

Constant Summary collapse

RESERVED_WORDS =
Set.new(%w[status name comment count size type]).freeze

Instance Method Summary collapse

Constructor Details

#initialize(config: S3arch.configuration) ⇒ Store

Returns a new instance of Store.



10
11
12
13
14
# File 'lib/s3arch/store.rb', line 10

def initialize(config: S3arch.configuration)
  @config = config
  @dynamodb = Aws::DynamoDB::Client.new
  @s3 = Aws::S3::Client.new
end

Instance Method Details

#download_index(owner_id, db_path) ⇒ Object



46
47
48
49
50
51
# File 'lib/s3arch/store.rb', line 46

def download_index(owner_id, db_path)
  @s3.get_object(bucket: @config.index_bucket, key: index_key(owner_id), response_target: db_path)
  true
rescue Aws::S3::Errors::NoSuchKey
  false
end

#fetch_records(owner_id) ⇒ Object

— Source data (read tokens from host app’s DynamoDB table) —



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/s3arch/store.rb', line 18

def fetch_records(owner_id)
  records = []
  params = build_query_params(owner_id)

  loop do
    result = @dynamodb.query(params)
    result.items.each do |item|
      next unless @config.record_filter.call(item)

      tokens = extract_tokens_from_item(item)
      next unless tokens.is_a?(Hash) && tokens.any?

      records << { 'id' => item['id'], 'tokens' => tokens, 'meta' => extract_meta(item) }
    end
    break unless result.last_evaluated_key

    params[:exclusive_start_key] = result.last_evaluated_key
  end

  records
end

#fetch_version(owner_id) ⇒ Object

— Version tracking —



55
56
57
58
59
60
# File 'lib/s3arch/store.rb', line 55

def fetch_version(owner_id)
  result = @dynamodb.get_item(table_name: @config.version_table,
                              key: { @config.owner_key => owner_id },
                              projection_expression: 'version')
  result.item&.dig('version')&.to_i
end

#increment_version(owner_id, record_count) ⇒ Object



62
63
64
65
66
67
68
69
70
# File 'lib/s3arch/store.rb', line 62

def increment_version(owner_id, record_count)
  @dynamodb.update_item(
    table_name: @config.version_table,
    key: { @config.owner_key => owner_id },
    update_expression: 'SET version = if_not_exists(version, :zero) + :one, ' \
                       'updated_at = :now, record_count = :count',
    expression_attribute_values: { ':zero' => 0, ':one' => 1, ':now' => Time.now.iso8601, ':count' => record_count }
  )
end

#upload_index(owner_id, db_path) ⇒ Object

— Index files (SQLite databases on S3) —



42
43
44
# File 'lib/s3arch/store.rb', line 42

def upload_index(owner_id, db_path)
  @s3.put_object(bucket: @config.index_bucket, key: index_key(owner_id), body: File.open(db_path, 'rb'))
end