Class: Qwe::DB::Record

Inherits:
Object
  • Object
show all
Includes:
DRb::DRbUndumped
Defined in:
lib/qwe/db/record.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(id, server_dir, create: nil, **args) ⇒ Record

Returns a new instance of Record.



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/qwe/db/record.rb', line 82

def initialize(id, server_dir, create: nil, **args)
  @dir = File.join(server_dir, "records", id.to_s)
  self.id = id

  if create
    Qwe::DB::Server.mkdir(dir)
    @meta = args
    @meta["commits_length"] = 0
    File.write(meta_file, JSON.generate(args))
    if create.is_a?(Class)
      create_object(create)
    elsif create.is_a?(Symbol)
      create_object(Object.module_eval(create.to_s))
    elsif create.is_a?(String)
      self.object = Marshal.load(create)
      File.binwrite(File.join(dir, "0"), create)
    else
      self.object = create
      dump_object
    end
  else
    @meta = JSON.parse(File.read(meta_file))
    self.object = Marshal.load(File.binread(File.join(dir, "dump")))
  end

  if object.respond_to?(:record=)
    object.record = self
  end
end

Instance Attribute Details

#dirObject (readonly)

Returns the value of attribute dir.



62
63
64
# File 'lib/qwe/db/record.rb', line 62

def dir
  @dir
end

#idObject

Returns the value of attribute id.



62
63
64
# File 'lib/qwe/db/record.rb', line 62

def id
  @id
end

#metaObject (readonly)

Returns the value of attribute meta.



62
63
64
# File 'lib/qwe/db/record.rb', line 62

def meta
  @meta
end

#objectObject

Returns the value of attribute object.



62
63
64
# File 'lib/qwe/db/record.rb', line 62

def object
  @object
end

Class Method Details

._loadObject



11
12
13
# File 'lib/qwe/db/record.rb', line 11

def self._load(...)
  nil
end

Instance Method Details

#_dumpObject



7
8
9
# File 'lib/qwe/db/record.rb', line 7

def _dump(...)
  ""
end

#archiveObject



168
169
170
171
172
# File 'lib/qwe/db/record.rb', line 168

def archive
  archive!
rescue => e
  log "Error archiving #{id}: #{e.full_message}"
end

#archive!Object



174
175
176
177
# File 'lib/qwe/db/record.rb', line 174

def archive!
  log "Archive record #{id}"
  commits_file.archive!
end

#commit(str) ⇒ Object



37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/qwe/db/record.rb', line 37

def commit(str)
  @meta["commits_length"] += str.count("\n")
  commits_file.write(str)
  unless str[-1] == "\n"
    commits_file.write("\n")
    @meta["commits_length"] += 1
  end
  self
rescue => e
  log "Can't write commit #{str}: #{e.full_message}"
  self
end

#commits(commit_id = nil) ⇒ Object



124
125
126
# File 'lib/qwe/db/record.rb', line 124

def commits(commit_id = nil)
  commits_file.read(commit_id)
end

#commits_fileObject



64
65
66
# File 'lib/qwe/db/record.rb', line 64

def commits_file
  @commits_file ||= CommitsFile.new(@dir)
end

#commits_lengthObject



54
55
56
# File 'lib/qwe/db/record.rb', line 54

def commits_length
  @meta["commits_length"]
end

#commits_length=(v) ⇒ Object



50
51
52
# File 'lib/qwe/db/record.rb', line 50

def commits_length=(v)
  @meta["commits_length"] = v
end

#create_object(klass) ⇒ Object



76
77
78
79
80
# File 'lib/qwe/db/record.rb', line 76

def create_object(klass)
  self.object = klass.new
  object.init if klass.include?(Qwe::Mixins::Root)
  dump_object
end

#detachObject



134
135
136
# File 'lib/qwe/db/record.rb', line 134

def detach
  Worker.instance.detach(id, self)
end

#detach_atObject



15
16
17
# File 'lib/qwe/db/record.rb', line 15

def detach_at
  @detach_at || keep
end

#dumpObject



68
69
70
# File 'lib/qwe/db/record.rb', line 68

def dump
  Marshal.dump(object)
end

#dump_objectObject



72
73
74
# File 'lib/qwe/db/record.rb', line 72

def dump_object
  File.binwrite(File.join(dir, commits_length.to_s), dump)
end

#evaluate(rb) ⇒ Object



164
165
166
# File 'lib/qwe/db/record.rb', line 164

def evaluate(rb)
  object.instance_eval(rb)
end

#fork(commit_id = nil) ⇒ Object



138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
# File 'lib/qwe/db/record.rb', line 138

def fork(commit_id = nil)
  log "Fork at commit id #{commit_id}"
  commit_id ||= commits_length

  zero = File.binread(File.join(dir, "0"))
  rec = Worker.instance.allocate_record(zero)

  commits = commits(commit_id)
  rec.commits_length = commit_id + 1

  begin
    rec.object.instance_eval(commits)
  rescue ScriptError, StandardError => e
    log e.full_message
    log "Commits are:\n\n#{commits}\n\n"
  end

  if rec.commits.length > 0
    log "Commits should not produce another commits:", "\n" + rec.commits
    raise "Commits loop detected"
  end

  rec.commits_file.write(commits)
  rec
end

#keepObject



19
20
21
# File 'lib/qwe/db/record.rb', line 19

def keep
  @detach_at = Time.now + Worker.instance.detach_timeout
end

#meta_fileObject



58
59
60
# File 'lib/qwe/db/record.rb', line 58

def meta_file
  File.join(@dir, "meta")
end

#object_at(commit_id) ⇒ Object



128
129
130
131
132
# File 'lib/qwe/db/record.rb', line 128

def object_at(commit_id)
  o = Marshal.load File.read(File.join(dir, "0"))
  o.instance_eval commits(commit_id)
  o
end

#saveObject



112
113
114
115
116
# File 'lib/qwe/db/record.rb', line 112

def save
  save!
rescue => e
  log "Can't save record #{id}: #{e.full_message} #{e.backtrace}"
end

#save!Object



118
119
120
121
122
# File 'lib/qwe/db/record.rb', line 118

def save!
  commits_file.close
  File.binwrite(File.join(dir, "dump"), dump)
  File.write(meta_file, JSON.generate(@meta))
end

#should_detach?Boolean

Returns:

  • (Boolean)


23
24
25
# File 'lib/qwe/db/record.rb', line 23

def should_detach?
  detach_at < Time.now
end