Class: FakeDynamo::Storage

Inherits:
Object
  • Object
show all
Defined in:
lib/fake_dynamo/storage.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#compactedObject

Returns the value of attribute compacted.



7
8
9
# File 'lib/fake_dynamo/storage.rb', line 7

def compacted
  @compacted
end

#db_pathObject

Returns the value of attribute db_path.



7
8
9
# File 'lib/fake_dynamo/storage.rb', line 7

def db_path
  @db_path
end

#loadedObject

Returns the value of attribute loaded.



7
8
9
# File 'lib/fake_dynamo/storage.rb', line 7

def loaded
  @loaded
end

Class Method Details

.instanceObject



10
11
12
# File 'lib/fake_dynamo/storage.rb', line 10

def instance
  @storage ||= Storage.new
end

Instance Method Details

#compact!Object



101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/fake_dynamo/storage.rb', line 101

def compact!
  return if @compacted
  @aof = Tempfile.new('compact')
  log.warn "Compacting db ..."
  db.tables.each do |_, table|
    persist('CreateTable', table.create_table_data)
    table.items.each do |_, item|
      persist('PutItem', table.put_item_data(item))
    end
  end
  @aof.close
  FileUtils.mv(@aof.path, db_path)
  @aof = nil
  @compacted = true
end

#compact_if_necessaryObject



94
95
96
97
98
99
# File 'lib/fake_dynamo/storage.rb', line 94

def compact_if_necessary
  return unless File.exists? db_path
  if File.stat(db_path).size > compact_threshold
    compact!
  end
end

#compact_thresholdObject



90
91
92
# File 'lib/fake_dynamo/storage.rb', line 90

def compact_threshold
  100 * 1024 * 1024 # 100mb
end

#dbObject



52
53
54
# File 'lib/fake_dynamo/storage.rb', line 52

def db
  DB.instance
end

#db_aofObject



56
57
58
# File 'lib/fake_dynamo/storage.rb', line 56

def db_aof
  @aof ||= File.new(db_path, 'a')
end

#delete_dbObject



40
41
42
43
# File 'lib/fake_dynamo/storage.rb', line 40

def delete_db
  return unless File.exists? db_path
  FileUtils.rm(db_path)
end

#init_db(path) ⇒ Object



27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/fake_dynamo/storage.rb', line 27

def init_db(path)
  @db_path = path

  return if File.exists?(db_path) && File.writable?(db_path)

  FileUtils.mkdir_p(File.dirname(db_path))
  FileUtils.touch(db_path)
rescue Errno::EACCES
  puts "Cannot create or access db file at #{db_path}"
  puts "Make sure you have write access to #{db_path}"
  exit(1)
end

#load_aofObject



74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/fake_dynamo/storage.rb', line 74

def load_aof
  return if @loaded
  file = File.new(db_path, 'r')
  log.warn "Loading fake_dynamo data ..."
  loop do
    operation = file.readline.chomp
    size = Integer(file.readline.chomp)
    data = file.read(size)
    db.process(operation, JSON.parse(data))
  end
rescue EOFError
  file.close
  compact_if_necessary
  @loaded = true
end

#logObject



15
16
17
# File 'lib/fake_dynamo/storage.rb', line 15

def log
  Logger.log
end

#persist(operation, data) ⇒ Object



65
66
67
68
69
70
71
72
# File 'lib/fake_dynamo/storage.rb', line 65

def persist(operation, data)
  return unless write_command?(operation)
  db_aof.puts(operation)
  data = data.to_json
  db_aof.puts(data.bytesize + "\n".bytesize)
  db_aof.puts(data)
  db_aof.flush
end

#resetObject



45
46
47
48
49
50
# File 'lib/fake_dynamo/storage.rb', line 45

def reset
  log.warn "resetting database ..."
  @aof.close if @aof
  @aof = nil
  delete_db
end

#shutdownObject



60
61
62
63
# File 'lib/fake_dynamo/storage.rb', line 60

def shutdown
  log.warn "shutting down fake_dynamo ..."
  @aof.close if @aof
end

#write_command?(command) ⇒ Boolean

Returns:

  • (Boolean)


23
24
25
# File 'lib/fake_dynamo/storage.rb', line 23

def write_command?(command)
  write_commands.include?(command)
end

#write_commandsObject



19
20
21
# File 'lib/fake_dynamo/storage.rb', line 19

def write_commands
  %w[CreateTable DeleteItem DeleteTable PutItem UpdateItem UpdateTable BatchWriteItem]
end