#-- # Copyright (c) 2009, John Mettraux, jmettraux@gmail.com # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. # # Made in Japan. #++ require 'tokyotyrant' # gem install careo-tokyotyrant require 'rufus/edo/error' require 'rufus/edo/cabcore' require 'rufus/tokyo/ttcommons' module Rufus::Edo # # Connecting to a 'classic' Tokyo Tyrant server remotely # # require 'rufus/edo/ntyrant' # t = Rufus::Edo::NetTyrant.new('127.0.0.1', 44001) # t['toto'] = 'blah blah' # t['toto'] # => 'blah blah' # class NetTyrant include Rufus::Edo::CabinetCore include Rufus::Tokyo::TyrantCommons include Rufus::Tokyo::NoTransactions attr_reader :host, :port # Connects to a given Tokyo Tyrant server. # # Note that if the port is not specified, the host parameter is expected # to hold the path to a unix socket (not a TCP socket). # # (You can start a unix socket listening Tyrant with : # # ttserver -host /tmp/tyrant_socket -port 0 data.tch # # and then connect to it with rufus-tokyo via : # # require 'rufus/edo/ntyrant' # db = Rufus::Edo::NetTyrant.new('/tmp/tyrant_socket') # db['a'] = 'alpha' # db.close # ) # # To connect to a classic TCP bound Tyrant (port 44001) : # # t = Rufus::Edo::NetTyrant.new('127.0.0.1', 44001) # # # == :default and :default_proc # # Much like a Ruby Hash, a Tyrant accepts a default value or a default_proc # # db = Rufus::Edo::NetTyrant.new('127.0.0.1', 1978, :default => 'xxx') # db['fred'] = 'Astaire' # p db['fred'] # => 'Astaire' # p db['ginger'] # => 'xxx' # # db = Rufus::Edo::NetTyrant.new( # '127.0.0.1', # 1978, # :default_proc => lambda { |cab, key| "not found : '#{k}'" } # p db['ginger'] # => "not found : 'ginger'" # # The first arg passed to the default_proc is the tyrant itself, so this # opens up interesting possibilities. # def initialize (host, port=0, params={}) @host = host @port = port @db = TokyoTyrant::RDB.new @db.open(host, port) || raise_error if self.stat['type'] == 'table' @db.close raise ArgumentError.new( "tyrant at #{host}:#{port} is a table, " + "use Rufus::Edo::NetTyrantTable instead to access it.") end # # default value|proc self.default = params[:default] @default_proc ||= params[:default_proc] end # Returns the 'weight' of the db (in bytes) # def weight self.stat['size'] end # Tells the Tyrant server to create a copy of itself at the given (remote) # target_path. # # Returns true when successful. # # Note : if you started your ttserver with a path like "tyrants/data.tch" # you have to provide a target path in the same subdir, like # "tyrants/data_prime.tch". # def copy (target_path) @db.copy(target_path) || raise_error end # Copies the current cabinet to a new file. # # Does it by copying each entry afresh to the target file. Spares some # space, hence the 'compact' label... # def compact_copy (target_path) raise NotImplementedError.new('not creating files locally') end # Calls a lua embedded function # (http://tokyocabinet.sourceforge.net/tyrantdoc/#luaext) # # Options are :global_locking and :record_locking # # Returns the return value of the called function. # # Nil is returned in case of failure. # def ext (func_name, key='', value='', opts={}) @db.ext(func_name.to_s, key.to_s, value.to_s, compute_ext_opts(opts)) end protected def do_stat #:nodoc# @db.stat end end end