Class: BitClust::Database

Inherits:
Object show all
Includes:
NameUtils, DRb::DRbUndumped
Defined in:
lib/bitclust/server.rb,
lib/bitclust/database.rb

Overview

Abstract class for BitClust DB. Each entry is written in a file.

Has subclass MethodDatabase (Ruby stuff) and FunctionDatabase (C stuff).

Direct Known Subclasses

FunctionDatabase, MethodDatabase

Constant Summary

Constants included from NameUtils

NameUtils::CHAR_TO_MARK, NameUtils::CHAR_TO_NAME, NameUtils::CLASS_NAME_RE, NameUtils::CLASS_PATH_RE, NameUtils::CONST_PATH_RE, NameUtils::CONST_RE, NameUtils::GVAR_RE, NameUtils::LIBNAME_RE, NameUtils::MARK_TO_CHAR, NameUtils::MARK_TO_NAME, NameUtils::METHOD_NAME_RE, NameUtils::METHOD_SPEC_RE, NameUtils::MID, NameUtils::NAME_TO_CHAR, NameUtils::NAME_TO_MARK, NameUtils::TYPEMARK_RE

Class Method Summary collapse

Instance Method Summary collapse

Methods included from NameUtils

build_method_id, classid2name, classname2id, classname?, decodeid, decodename_fs, decodename_url, encodeid, encodename_fs, encodename_rdocurl, encodename_url, functionname?, gvarname?, html_filename, libid2name, libname2id, libname?, method_spec?, methodid2classid, methodid2libid, methodid2mname, methodid2specparts, methodid2specstring, methodid2typechar, methodid2typemark, methodid2typename, methodname?, split_method_id, split_method_spec, typechar2mark, typechar2name, typechar?, typemark2char, typemark2name, typemark?, typename2char, typename2mark, typename?

Constructor Details

#initialize(prefix) ⇒ Database

Returns a new instance of Database.


44
45
46
47
48
49
# File 'lib/bitclust/database.rb', line 44

def initialize(prefix)
  @prefix = prefix
  @properties = nil
  @in_transaction = false
  @properties_dirty = false
end

Class Method Details

.connect(uri) ⇒ Object


27
28
29
30
31
32
33
34
35
36
# File 'lib/bitclust/database.rb', line 27

def Database.connect(uri)
  case uri.scheme
  when 'file'
    new(uri.path)
  when 'druby'
    DRbObject.new_with_uri(uri.to_s)
  else
    raise InvalidScheme, "unknown database scheme: #{uri.scheme}"
  end
end

.datadir?(dir) ⇒ Boolean

Returns:

  • (Boolean)

23
24
25
# File 'lib/bitclust/database.rb', line 23

def Database.datadir?(dir)
  File.file?("#{dir}/properties")
end

.dummy(params = {}) ⇒ Object


38
39
40
41
42
# File 'lib/bitclust/database.rb', line 38

def Database.dummy(params = {})
  db = new(nil)
  db.properties['version'] = params['version']
  db
end

Instance Method Details

#atomic_write_open(rel, &block) ⇒ Object


170
171
172
173
174
175
176
# File 'lib/bitclust/database.rb', line 170

def atomic_write_open(rel, &block)
  tmppath = realpath(rel) + '.writing'
  fopen(tmppath, 'wb', &block)
  File.rename tmppath, realpath(rel)
ensure
  File.unlink tmppath  rescue nil
end

#dummy?Boolean

Returns:

  • (Boolean)

51
52
53
# File 'lib/bitclust/database.rb', line 51

def dummy?
  not @prefix
end

#encodingObject


111
112
113
# File 'lib/bitclust/database.rb', line 111

def encoding
  propget('encoding')
end

#entries(rel) ⇒ Object


124
125
126
127
128
129
130
# File 'lib/bitclust/database.rb', line 124

def entries(rel)
  Dir.entries(realpath(rel))\
      .reject {|ent| /\A[\.=]/ =~ ent }\
      .map {|ent| decodeid(ent) }
rescue Errno::ENOENT
  return []
end

#exist?(rel) ⇒ Boolean

Direct File Access Layer: BitClust internal use only

Returns:

  • (Boolean)

119
120
121
122
# File 'lib/bitclust/database.rb', line 119

def exist?(rel)
  return false unless @prefix
  File.exist?(realpath(rel))
end

#foreach_line(rel, &block) ⇒ Object


166
167
168
# File 'lib/bitclust/database.rb', line 166

def foreach_line(rel, &block)
  File.foreach(realpath(rel), &block)
end

#load_properties(rel) ⇒ Object


136
137
138
139
140
141
142
143
144
145
146
147
148
149
# File 'lib/bitclust/database.rb', line 136

def load_properties(rel)
  h = {}
  fopen(realpath(rel), 'r:UTF-8') {|f|
    while line = f.gets
      k, v = line.strip.split('=', 2)
      break unless k
      h[k] = v
    end
    h['source'] = f.read
  }
  h
rescue Errno::ENOENT
  return {}
end

#makepath(rel) ⇒ Object


132
133
134
# File 'lib/bitclust/database.rb', line 132

def makepath(rel)
  FileUtils.mkdir_p realpath(rel)
end

#propertiesObject

Properties


88
89
90
91
92
93
94
95
# File 'lib/bitclust/database.rb', line 88

def properties
  @properties ||=
      begin
        h = load_properties('properties')
        h.delete 'source' if h['source'] and h['source'].strip.empty?
        h
      end
end

#propget(key) ⇒ Object


101
102
103
# File 'lib/bitclust/database.rb', line 101

def propget(key)
  properties()[key]
end

#propkeysObject


97
98
99
# File 'lib/bitclust/database.rb', line 97

def propkeys
  properties().keys
end

#propset(key, value) ⇒ Object


105
106
107
108
109
# File 'lib/bitclust/database.rb', line 105

def propset(key, value)
  check_transaction
  properties()[key] = value
  @properties_dirty = true
end

#read(rel) ⇒ Object


162
163
164
# File 'lib/bitclust/database.rb', line 162

def read(rel)
  File.read(realpath(rel))
end

#save_properties(rel, h) ⇒ Object


151
152
153
154
155
156
157
158
159
160
# File 'lib/bitclust/database.rb', line 151

def save_properties(rel, h)
  source = h.delete('source')
  atomic_write_open(rel) {|f|
    h.each do |key, val|
      f.puts "#{key}=#{val}"
    end
    f.puts
    f.puts source
  }
end

#transactionObject

Transaction


59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/bitclust/database.rb', line 59

def transaction
  @in_transaction = true
  yield
  return if dummy?
  if @properties_dirty
    save_properties 'properties', @properties
    @properties_dirty = false
  end
  commit if dirty?
ensure
  @in_transaction = false
end