Class: Lingo::Database

Inherits:
Object
  • Object
show all
Defined in:
lib/lingo/database.rb,
lib/lingo/database/source.rb,
lib/lingo/database/crypter.rb,
lib/lingo/database/progress.rb,
lib/lingo/database/gdbm_store.rb,
lib/lingo/database/hash_store.rb,
lib/lingo/database/sdbm_store.rb,
lib/lingo/database/libcdb_store.rb,
lib/lingo/database/source/key_value.rb,
lib/lingo/database/source/multi_key.rb,
lib/lingo/database/source/word_class.rb,
lib/lingo/database/source/multi_value.rb,
lib/lingo/database/source/single_word.rb

Overview

– Die Klasse Database stellt eine einheitliche Schnittstelle auf Lingo-Datenbanken bereit. Die Identifizierung der Datenbank erfolgt über die ID der Datenbank, so wie sie in der Sprachkonfigurationsdatei de.lang unter language/dictionary/databases hinterlegt ist.

Das Lesen und Schreiben der Datenbank erfolgt über die Funktionen []() und []=(). ++

Defined Under Namespace

Modules: Crypter, GDBMStore, HashStore, LibCDBStore, SDBMStore Classes: Progress, Source

Constant Summary collapse

FLD_SEP =
'|'
KEY_REF =
'*'
SYS_KEY =
'~'
KEY_REF_RE =
%r{\A#{Regexp.escape(KEY_REF)}(\d+)\z}o
BACKENDS =
[]
BACKEND_BY_EXT =
{}

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(id, lingo) ⇒ Database

Returns a new instance of Database.



88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/lingo/database.rb', line 88

def initialize(id, lingo)
  @id, @lingo, @config, @db = id, lingo, lingo.database_config(id), nil

  @val, @crypt, @srcfile = Hash.array, config.key?('crypt'),
    Lingo.find(:dict, config['name'], relax: true)

  begin
    @stofile = Lingo.find(:store, @srcfile)
    FileUtils.mkdir_p(File.dirname(@stofile))
  rescue SourceFileNotFoundError => err
    @stofile = skip_ext = err.id
    backend = self.class.backend_by_ext(@stofile) unless err.name
  rescue NoWritableStoreError
    backend = HashStore
  end

  extend(@backend = backend || self.class.find_backend || HashStore)

  @stofile << store_ext unless skip_ext || !respond_to?(:store_ext)

  convert unless uptodate?
end

Instance Attribute Details

#backendObject (readonly)

Returns the value of attribute backend.



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

def backend
  @backend
end

#configObject (readonly)

Returns the value of attribute config.



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

def config
  @config
end

#lingoObject (readonly)

Returns the value of attribute lingo.



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

def lingo
  @lingo
end

Class Method Details

.backend_by_ext(file, ext = File.extname(file)) ⇒ Object



63
64
65
66
# File 'lib/lingo/database.rb', line 63

def backend_by_ext(file, ext = File.extname(file))
  get_backend(BACKEND_BY_EXT[ext], file) or
    raise BackendNotFoundError.new(file)
end

.find_backend(env = 'LINGO_BACKEND') ⇒ Object



68
69
70
71
# File 'lib/lingo/database.rb', line 68

def find_backend(env = 'LINGO_BACKEND')
  env && get_backend(ENV[env]) || BACKENDS.find { |name|
    backend = get_backend(name, nil, true) and return backend }
end

.get_backend(name, file = nil, relax = false) ⇒ Object



73
74
75
76
77
78
79
80
# File 'lib/lingo/database.rb', line 73

def get_backend(name, file = nil, relax = false)
  return unless name

  Object.const_get(name)
  const_get("#{name}Store")
rescue TypeError, NameError => err
  raise BackendNotAvailableError.new(name, file, err) unless relax
end

.open(*args, &block) ⇒ Object



82
83
84
# File 'lib/lingo/database.rb', line 82

def open(*args, &block)
  new(*args).open(&block)
end

.register(klass, ext, prio = -1,, meth = true) ⇒ Object



55
56
57
58
59
60
61
# File 'lib/lingo/database.rb', line 55

def register(klass, ext, prio = -1, meth = true)
  BACKENDS.insert(prio, name = klass.name[/::(\w+)Store\z/, 1])
  Array(ext).each { |i| BACKEND_BY_EXT[i.insert(0, '.')] = name }

  klass.const_set(:EXT, ext)
  klass.class_eval('def store_ext; EXT; end', __FILE__, __LINE__) if meth
end

Instance Method Details

#[](key) ⇒ Object



143
144
145
146
# File 'lib/lingo/database.rb', line 143

def [](key)
  val = _val(key) unless closed?
  val.split(FLD_SEP) if val
end

#[]=(key, val) ⇒ Object



148
149
150
151
152
153
154
155
156
# File 'lib/lingo/database.rb', line 148

def []=(key, val)
  return if closed?

  val = @val[key].concat(val)
  val.uniq!

  val = val.join(FLD_SEP)
  @crypt ? _set(*Crypter.encode(key, val)) : _set(key, val)
end

#closeObject



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

def close
  _close unless closed?
  @db = nil

  self
end

#closed?Boolean

Returns:

  • (Boolean)


113
114
115
# File 'lib/lingo/database.rb', line 113

def closed?
  !@db || _closed?
end

#eachObject



139
140
141
# File 'lib/lingo/database.rb', line 139

def each
  _each { |key, val| yield _encode!(key), _encode!(val) } unless closed?
end

#openObject



117
118
119
120
121
122
123
124
# File 'lib/lingo/database.rb', line 117

def open
  @db = _open if closed?
  block_given? ? yield(self) : self
rescue => err
  raise DatabaseError.new(:open, @stofile, err)
ensure
  close if @db && block_given?
end

#to_hObject



133
134
135
136
137
# File 'lib/lingo/database.rb', line 133

def to_h
  hash = {}
  each { |key, val| hash[key.freeze] = val }
  hash
end

#warn(*msg) ⇒ Object



158
159
160
# File 'lib/lingo/database.rb', line 158

def warn(*msg)
  lingo.warn(*msg)
end