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.



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

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

Class Method Details

.connect(uri) ⇒ Object



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

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)


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

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

.dummy(params = {}) ⇒ Object



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

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

Instance Method Details

#atomic_write_open(rel, &block) ⇒ Object



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

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)


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

def dummy?
  not @prefix
end

#encodingObject



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

def encoding
  propget('encoding')
end

#entries(rel) ⇒ Object



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

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)


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

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

#foreach_line(rel, &block) ⇒ Object



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

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

#load_properties(rel) ⇒ Object



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

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



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

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

#propertiesObject

Properties



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

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



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

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

#propkeysObject



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

def propkeys
  properties().keys
end

#propset(key, value) ⇒ Object



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

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

#read(rel) ⇒ Object



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

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

#save_properties(rel, h) ⇒ Object



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

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



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

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