rufus-tokyo 0.1.14 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -27,17 +27,20 @@ require 'rufus/tokyo'
27
27
 
28
28
 
29
29
  module Rufus::Tokyo
30
-
31
- #
32
- # An error for Dystopia
33
- #
34
- class DystopianError < RuntimeError
35
- def new (error_code)
36
- super("tokyo dystopia error #{error_code}")
30
+ module Dystopia
31
+ #
32
+ # An error for Dystopia
33
+ #
34
+ class Error < RuntimeError
35
+ def new (error_code)
36
+ super("tokyo dystopia error #{error_code}")
37
+ end
37
38
  end
38
39
  end
39
40
  end
40
41
 
41
42
  require 'rufus/tokyo/dystopia/lib'
43
+
44
+ require 'rufus/tokyo/dystopia/core'
42
45
  require 'rufus/tokyo/dystopia/words'
43
46
 
@@ -0,0 +1,198 @@
1
+ #--
2
+ # Copyright (c) 2009, Jeremy Hinegardner, jeremy@copiousfreetime.org
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ # of this software and associated documentation files (the "Software"), to deal
6
+ # in the Software without restriction, including without limitation the rights
7
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ # copies of the Software, and to permit persons to whom the Software is
9
+ # furnished to do so, subject to the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be included in
12
+ # all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+ # THE SOFTWARE.
21
+ #
22
+ # Developed with and sponsored by Seven Scale <http://sevenscale.com/>,
23
+ # creators of Open Syslog.
24
+ #
25
+ #++
26
+
27
+ module Rufus::Tokyo::Dystopia
28
+ #
29
+ # Tokyo Dystopia Indexed Database
30
+ #
31
+ # http://tokyocabinet.sourceforge.net/dystopiadoc/#dystopiaapi
32
+ #
33
+ class Core
34
+ class Error < Rufus::Tokyo::Dystopia::Error; end
35
+
36
+ def self.lib
37
+ ::Rufus::Tokyo::DystopiaLib
38
+ end
39
+
40
+ def self.mode_to_bits( mode )
41
+ @modes_to_bits ||= {
42
+ "r" => lib::READER,
43
+ "r+" => lib::READER | lib::WRITER,
44
+ "w" => lib::WRITER | lib::CREAT | lib::TRUNC,
45
+ "w+" => lib::READER | lib::WRITER | lib::CREAT | lib::TRUNC,
46
+ "a" => lib::WRITER | lib::CREAT,
47
+ "a+" => lib::READER | lib::WRITER | lib::CREAT ,
48
+ }
49
+
50
+ return @modes_to_bits[mode]
51
+ end
52
+
53
+ def self.locking_to_bits( locking )
54
+ @locking_to_bits ||= {
55
+ true => 0,
56
+ false => lib::NOLCK,
57
+ :nonblocking => lib::LCKNB
58
+ }
59
+ return @locking_to_bits[locking]
60
+ end
61
+
62
+ def lib
63
+ Core.lib
64
+ end
65
+
66
+ #
67
+ # Opens/creates a new Tokyo dystopia database
68
+ #
69
+ # The modes are equivelent to those when opening a file:
70
+ #
71
+ # 'r' : readonly
72
+ # 'r+' : read/write does not create or truncate
73
+ # 'w' : write only, create and truncate
74
+ # 'w+' : read/write, create and truncate
75
+ # 'a' : write only, create if db does not exist
76
+ # 'a+' : read/write, create if db does not exist
77
+ #
78
+ # The third parameter 'locking' can be one of 'true', 'false' or
79
+ # :nonblocking
80
+ #
81
+ def initialize( path, mode = "a+", locking = true )
82
+ mode_bits = Core.mode_to_bits( mode )
83
+ raise Error.new( "Invalid mode '#{mode}'" ) unless mode_bits
84
+ lock_bits = Core.locking_to_bits( locking )
85
+ raise Error.new( "Invalid Locking mode #{locking}" ) unless lock_bits
86
+
87
+ @db = lib.tcidbnew()
88
+
89
+ rc = lib.tcidbopen( @db, path, mode_bits | lock_bits )
90
+ raise_error unless rc == 1
91
+ end
92
+
93
+ #
94
+ # Close and detach from the database. This instance can not be used anymore
95
+ #
96
+ def close
97
+ rc = lib.tcidbclose( @db )
98
+ raise_error unless rc == 1
99
+
100
+ lib.tcidbdel( @db )
101
+ raise_error unless rc == 1
102
+
103
+ @db = nil
104
+ end
105
+
106
+ #
107
+ # Add a new document to the database
108
+ #
109
+ def store( id, text )
110
+ rc = lib.tcidbput( @db, id, text )
111
+ raise_error unless rc == 1
112
+ end
113
+
114
+ #
115
+ # Remove the given document from the index
116
+ #
117
+ def delete( id )
118
+ rc = lib.tcidbout( @db, id )
119
+ raise_error unless rc == 1
120
+ end
121
+
122
+ #
123
+ # Return the document at the specified index
124
+ #
125
+ def fetch( id )
126
+ r = nil
127
+ begin
128
+ r = lib.tcidbget( @db, id )
129
+ rescue => e
130
+ # if we have 'no record found' then return nil
131
+ if lib.tcidbecode( @db ) == 22 then
132
+ return nil
133
+ else
134
+ raise_error
135
+ end
136
+ end
137
+ return r
138
+ end
139
+
140
+ #
141
+ # Return the document ids of the documents that matche the search expression
142
+ #
143
+ # http://tokyocabinet.sourceforge.net/dystopiadoc/#dystopiaapi and scroll
144
+ # down to 'Compound Expression of Search'
145
+ #
146
+ def search( expression )
147
+ out_count = ::FFI::MemoryPointer.new :pointer
148
+ out_list = ::FFI::MemoryPointer.new :pointer
149
+ out_list = lib.tcidbsearch2( @db, expression, out_count )
150
+
151
+ count = out_count.read_int
152
+ results = out_list.get_array_of_uint64(0, count )
153
+ return results
154
+ end
155
+
156
+ #
157
+ # Remove all records from the db
158
+ #
159
+ def clear
160
+ lib.tcidbvanish( @db )
161
+ end
162
+
163
+ #
164
+ # Report the path of the database
165
+ #
166
+ def path
167
+ s = lib.tcidbpath( @db )
168
+ return File.expand_path( s ) if s
169
+ end
170
+
171
+ #
172
+ # Return the number of records in the database
173
+ #
174
+ def count
175
+ lib.tcidbrnum( @db )
176
+ end
177
+ alias :rnum :count
178
+
179
+ #
180
+ # return the disk space used by the index
181
+ #
182
+ def fsize
183
+ lib.tcidbfsiz( @db )
184
+ end
185
+
186
+ protected
187
+
188
+ #
189
+ # Raises a dystopian error (asks the db which one)
190
+ #
191
+ def raise_error
192
+ code = lib.tcidbecode( @db )
193
+ msg = lib.tcidberrmsg( code )
194
+ raise Error.new("[ERROR #{code}] : #{msg}")
195
+ end
196
+
197
+ end
198
+ end
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2009, John Mettraux, jmettraux@gmail.com
2
+ # Copyright (c) 2009, Jeremy Hinegardner, John Mettraux
3
3
  #
4
4
  # Permission is hereby granted, free of charge, to any person obtaining a copy
5
5
  # of this software and associated documentation files (the "Software"), to deal
@@ -36,19 +36,81 @@ module Rufus::Tokyo
36
36
  # find Tokyo Dystopia lib
37
37
 
38
38
  paths = Array(ENV['TOKYO_DYSTOPIA_LIB'] || %w{
39
+ /usr/lib/libtokyodystopia.so
40
+ /usr/lib64/libtokyodystopia.so
39
41
  /opt/local/lib/libtokyodystopia.dylib
42
+ /opt/local/lib/libtokyodystopia.so
40
43
  /usr/local/lib/libtokyodystopia.dylib
41
44
  /usr/local/lib/libtokyodystopia.so
42
45
  })
43
46
 
44
- if path = paths.find { |path| File.exist?(path) }
47
+ path = paths.find { |path| File.exist?(path) }
45
48
 
46
49
  raise "did not find Tokyo Dystopia libs on your system" unless path
47
50
 
48
51
  ffi_lib(path)
49
52
 
50
53
  #
51
- # tcwdb functions
54
+ # tcidb functions - The Core API
55
+ #
56
+ # http://tokyocabinet.sourceforge.net/dystopiadoc/#dystopiaapi
57
+
58
+ # tuning options <dystopia.h>
59
+ LARGE = 1 << 0
60
+ DEFLATE = 1 << 1
61
+ BZIP = 1 << 2
62
+ TCBS = 1 << 3
63
+
64
+ # open modes <dystopia.h>
65
+ READER = 1 << 0
66
+ WRITER = 1 << 1
67
+ CREAT = 1 << 2
68
+ TRUNC = 1 << 3
69
+ NOLCK = 1 << 4
70
+ LCKNB = 1 << 5
71
+
72
+ # for get modes
73
+ SUBSTR = 0
74
+ PREFIX = 1
75
+ SUFFIX = 2
76
+ FULL = 3
77
+ TOKEN = 4
78
+ TOKPRE = 5
79
+ TOKSUF = 6
80
+
81
+
82
+ attach_function :tcidberrmsg, [ :int ], :string
83
+ attach_function :tcidbecode, [ :pointer ], :int
84
+
85
+ attach_function :tcidbnew, [], :pointer
86
+ attach_function :tcidbopen, [ :pointer, :pointer, :int ], :int
87
+ attach_function :tcidbclose, [ :pointer ], :int
88
+ attach_function :tcidbdel, [ :pointer ], :void
89
+ attach_function :tcidbvanish, [ :pointer ], :int
90
+
91
+ # TODO
92
+ #attach_function :tcidbtune, [ :pointer, :int64, :int64, :int64, :int8 ], :int
93
+ #attach_function :tcidbsetcache, [ :pointer, :int64, :int32 ], :int
94
+ #attach_function :tcidbsetfwmmax, [ :pointer, :uint32 ], :int
95
+ #attach_function :tcidbsync, [ :pointer ], :int
96
+ #attach_function :tcidboptimize, [ :pointer ], :int
97
+ #attach_function :tcidbcopy, [ :pointer, :pointer ], :int
98
+
99
+ attach_function :tcidbpath, [ :pointer ], :string
100
+ attach_function :tcidbrnum, [ :pointer ], :uint64
101
+ attach_function :tcidbfsiz, [ :pointer ], :uint64
102
+
103
+ attach_function :tcidbput, [ :pointer, :int64, :string ], :int
104
+ attach_function :tcidbout, [ :pointer, :int64 ], :int
105
+ attach_function :tcidbget, [ :pointer, :int64 ], :string
106
+ #attach_function :tcidbsearch, [ :pointer, :pointer, :int, :pointer ], :pointer
107
+ attach_function :tcidbsearch2, [ :pointer, :string, :pointer], :pointer
108
+ #attach_function :tcidbiterinit, [ :pointer ], :int
109
+ #attach_function :tcidbiternext, [ :pointer ], :uint64
110
+
111
+
112
+ #
113
+ # tcwdb functions - The Word Database API
52
114
  #
53
115
  # http://tokyocabinet.sourceforge.net/dystopiadoc/#tcwdbapi
54
116
 
@@ -23,7 +23,7 @@
23
23
  #++
24
24
 
25
25
 
26
- module Rufus::Tokyo
26
+ module Rufus::Tokyo::Dystopia
27
27
 
28
28
  #
29
29
  # Tokyo Dystopia words database.
@@ -0,0 +1,46 @@
1
+ #--
2
+ # Copyright (c) 2009, Adam Keys, John Mettraux, jmettraux@gmail.com
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ # of this software and associated documentation files (the "Software"), to deal
6
+ # in the Software without restriction, including without limitation the rights
7
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ # copies of the Software, and to permit persons to whom the Software is
9
+ # furnished to do so, subject to the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be included in
12
+ # all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+ # THE SOFTWARE.
21
+ #
22
+ # Made in Japan.
23
+ #++
24
+
25
+ module Rufus::Tokyo
26
+ module Outlen
27
+
28
+ # A wrapper for library returning a string (binary data potentially)
29
+ #
30
+ def outlen_op (method, *args)
31
+
32
+ args.unshift(@db)
33
+
34
+ outlen = FFI::MemoryPointer.new(:int)
35
+ args << outlen
36
+
37
+ out = lib.send(method, *args)
38
+
39
+ return nil if out.address == 0
40
+ return out.get_bytes(0, outlen.get_int(0))
41
+ ensure
42
+ outlen.free
43
+ end
44
+ end
45
+ end
46
+
@@ -81,7 +81,15 @@ module Tokyo
81
81
  :bt => 13,
82
82
  :between => 13,
83
83
 
84
- :numoreq => 14 # number which is equal to at least one token
84
+ :numoreq => 14, # number which is equal to at least one token
85
+
86
+ # full-text search
87
+ :ftsph => 15,
88
+ :ftsphrase => 15,
89
+ :phrase => 15,
90
+ :ftsand => 16,
91
+ :ftsor => 17,
92
+ :ftsex => 18
85
93
  }
86
94
 
87
95
  TDBQCNEGATE = 1 << 24
@@ -22,9 +22,8 @@
22
22
  # Made in Japan.
23
23
  #++
24
24
 
25
-
26
25
  require 'rufus/tokyo/ttcommons'
27
-
26
+ require 'rufus/tokyo/tyrant/ext'
28
27
 
29
28
  module Rufus::Tokyo
30
29
 
@@ -39,6 +38,7 @@ module Rufus::Tokyo
39
38
  class Tyrant < Cabinet
40
39
 
41
40
  include TyrantCommons
41
+ include Ext
42
42
 
43
43
  attr_reader :host, :port
44
44
 
@@ -70,8 +70,8 @@ module Rufus::Tokyo
70
70
  @host = host
71
71
  @port = port
72
72
 
73
- (lib.tcrdbopen(@db, host, port) == 1) ||
74
- raise("couldn't connect to tyrant at #{host}:#{port}")
73
+ (lib.tcrdbopen(@db, host, port) == 1) || raise(
74
+ TokyoError.new("couldn't connect to tyrant at #{host}:#{port}"))
75
75
 
76
76
  if self.stat['type'] == 'table'
77
77
 
@@ -100,28 +100,6 @@ module Rufus::Tokyo
100
100
  raise 'not allowed to create files on the server'
101
101
  end
102
102
 
103
- # Calls a lua embedded function
104
- # (http://tokyocabinet.sourceforge.net/tyrantdoc/#luaext)
105
- #
106
- # Options are :global_locking and :record_locking
107
- #
108
- # Returns the return value of the called function.
109
- #
110
- # Nil is returned in case of failure.
111
- #
112
- def ext (func_name, key, value, opts={})
113
-
114
- k = key.to_s
115
- v = value.to_s
116
-
117
- outlen_op(
118
- :tcrdbext,
119
- func_name.to_s,
120
- compute_ext_opts(opts),
121
- k, Rufus::Tokyo.blen(k),
122
- v, Rufus::Tokyo.blen(v))
123
- end
124
-
125
103
  # Tyrant databases DO NOT support the 'defrag' call. Calling this method
126
104
  # will raise an exception.
127
105
  #