GNUmakefile: no news yet...
[metropolis.git] / lib / metropolis / tdb.rb
blobdac613d12b430f55e50f9a20785ce89e51d76a6c
1 # -*- encoding: binary -*-
3 require 'tdb'
5 module Metropolis::TDB
6   include Metropolis::Common
7   autoload :Single, 'metropolis/tdb/single'
8   autoload :Multi, 'metropolis/tdb/multi'
10   def setup(opts)
11     super
12     @tdb_opts = { :tdb_flags => 0 }
13     if @readonly
14       @tdb_opts[:open_flags] = IO::RDONLY
15       extend Metropolis::Common::RO
16     end
17     if @query
18       size = @query['hash_size'] and @tdb_opts[:hash_size] = size.to_i
19       hash = @query['hash'] and @tdb_opts[:hash] = hash.to_sym
21       case @query['threadsafe']
22       when 'true'; @tdb_opts[:threadsafe] = true
23       when 'false', nil
24       else
25         raise ArgumentError, "'threadsafe' must be 'true' or 'false'"
26       end
28       case @query['volatile']
29       when 'true'; @tdb_opts[:tdb_flags] |= TDB::VOLATILE
30       when 'false', nil
31       else
32         raise ArgumentError, "'volatile' must be 'true' or 'false'"
33       end
35       case @query['sync']
36       when 'true', nil
37       when 'false'; @tdb_opts[:tdb_flags] |= TDB::NOSYNC
38       else
39         raise ArgumentError, "'sync' must be 'true' or 'false'"
40       end
41     end
42     extend(@path_pattern ? Metropolis::TDB::Multi : Metropolis::TDB::Single)
43   end
45   def put(key, env)
46     value = env["rack.input"].read
47     db(key) do |tdb|
48       case env['HTTP_X_TT_PDMODE']
49       when '1'
50         # TODO: make this atomic
51         return r(409) if tdb.include?(key)
52       when '2'
53         value = (tdb.get(key) || "") << value
54       end
55       tdb.store(key, value)
56     end
57     r(201)
58   end
60   def delete(key)
61     r(db(key) { |tdb| tdb.nuke!(key) } ? 200 : 404)
62   end
64   def get(key, env)
65     value = db(key) { |tdb| tdb.fetch(key) } or return r(404)
66     [ 200, { 'Content-Length' => value.size.to_s }.merge!(@headers), [ value ] ]
67   end
68 end