Advertisement
Snusmumriken

Snus_redis

Feb 17th, 2018
321
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 57.49 KB | None | 0 0
  1. local socket = require'socket'
  2.  
  3. local concat = table.concat
  4. local floor  = math.floor
  5.  
  6. -- // Core
  7. local connection = {}
  8. connection.__index  = connection
  9. connection.default  = {
  10.     timeout = 5,
  11.     ip = '127.0.0.1',
  12.     port = 6379
  13. }
  14.  
  15. function connection:getIPSockType(ip)
  16.   if type(ip) ~= "string" then return false, 'ip is not string' end
  17.     local ip, err = socket.dns.toip(ip)
  18.     if not ip then return ip, err end
  19.    
  20.   -- check for format X.XX.XXX.XXX for ipv4
  21.   if ip:match'^%d+%.%d+%.%d+%.%d+$' then
  22.     return (socket.tcp4 or socket.tcp)()
  23.   end
  24.  
  25.     if not socket.tcp4 then return false, 'ipv6 not alowed, update luasocket library up to v3.x' end
  26.     return socket.tcp()
  27. end
  28.  
  29. function connection:new(ip, port, pass, timeout)
  30.     self         = setmetatable({}, self)
  31.     self.ip      = ip      or self.default.ip
  32.     self.port    = port    or self.default.port
  33.     self.timeout = timeout or self.default.timeout
  34.     self.pass    = pass
  35.    
  36.     return self
  37. end
  38.  
  39. -- settimeout(0) --> settimeout() = set to zero and restore back
  40. function connection:settimeout(t)
  41.     if not self.tcp then return end
  42.     if not t then self.tcp:settimeout(self.timeout) end
  43.     if t ~= 0 then
  44.         self.timeout = t
  45.     end
  46.     self.tcp:settimeout(t)
  47. end
  48.  
  49. setmetatable(connection, {__call = connection.new})
  50.  
  51. -- connect and auth (if needed)
  52. function connection:connect(ip, port, pass)
  53.     if self.tcp then return true end
  54.    
  55.     self.ip   = ip   or self.ip
  56.     self.port = port or self.port
  57.     self.pass = pass or self.pass
  58.    
  59.     local sock, err = self:getIPSockType(self.ip)
  60.     if not sock then return false, err end
  61.     self.tcp = sock
  62.     self.tcp:connect(self.ip, self.port)
  63.     self.tcp:settimeout(self.timeout)
  64.     if self.pass then
  65.         if self:auth(self.pass) then return true end
  66.     else
  67.         if self:ping() then return true end
  68.     end
  69.    
  70.     self:close()
  71.     return false, 'redis not responded'
  72. end
  73.  
  74. -- destroy connection
  75. function connection:close()
  76.     if not self.tcp then return end
  77.     self.tcp:close()
  78.     self.tcp = nil
  79. end
  80.  
  81. -- set of functions for receiving any data
  82. local receiver = {}
  83. connection.receiver = receiver
  84.  
  85. -- simple strings
  86. receiver['+'] = function(self, data) return data end
  87.  
  88. -- errors
  89. receiver['-'] = function(self, data) return false, data end
  90.  
  91. -- bulk strings
  92. receiver['$'] = function(self, data)
  93.     local bytes = tonumber(data)
  94.     if not bytes or bytes < 1 then return bytes end
  95.     local res, err = self.tcp:receive(bytes + 2) -- data + '\r\n'
  96.     return err and false or res:sub(1, -3), err  -- cut '\r\n'
  97. end
  98.  
  99. -- integers
  100. receiver[':'] = function(self, data)
  101.     return tonumber(data)
  102. end
  103.  
  104. -- arrays
  105. receiver['*'] = function(self, data)
  106.     local count = tonumber(data)
  107.     if not count then return false, 'unknown redis response' end
  108.     local list = {}
  109.     for i = 1, count do
  110.         list[i] = self:receive()
  111.     end
  112.     return list
  113. end
  114.  
  115. -- recursive auto-reconnect receiver
  116. function connection:receive(async)
  117.     local res,  err  = self.tcp:receive'*l'
  118.     if not res then
  119.         if async then return end
  120.         return self:close(), err
  121.     end
  122.    
  123.     local head, tail = res:sub(1, 1), res:sub(2)
  124.    
  125.     if not self.receiver[head] then
  126.         return false, 'unknown type: ['..head..']', res
  127.     end
  128.    
  129.     return self.receiver[head](self, tail)
  130. end
  131.  
  132. -- base string request
  133. function connection:request(command, close)
  134.     if not self:connect() then return end
  135.    
  136.     self.tcp:send(command..'\r\n')
  137.     return self:receive()
  138. end
  139.  
  140. -- base table request
  141. function connection:trequest(request_table)
  142.     if not self:connect() then return end
  143.     self.tcp:send(concat(request_table, ' ')..'\r\n')
  144.     return self:receive()
  145. end
  146.  
  147.  
  148. -- // Utility
  149.  
  150. -- Utily
  151. function connection:concat(...)
  152.     return concat({...}, ' ')
  153. end
  154.  
  155. -- Get string-serialized object and object
  156. function connection:inspect(key, fmt)
  157.     fmt = fmt or 0
  158.     local template = '%'..fmt..'s (%s)'
  159.     if not key then
  160.         local res = {}
  161.         local keys = self:keys('*')
  162.         for i, key in ipairs(keys) do
  163.             res[#res + 1] = template:format(key, self:type(key))
  164.         end
  165.         return table.concat(res, '\r\n')
  166.     end
  167.    
  168.     local type = self:type(key)
  169.    
  170.     local text = "%s (%s): "
  171.     text = text:format(type, key)
  172.    
  173.     if type == 'string' then
  174.         return text:format(key, t, self:get(key))
  175.     end
  176.    
  177.     if self[type] then
  178.         local obj = self[type](self, key)
  179.         return obj and obj:Inspect() or 'No object ['..tostring(key)..']', obj
  180.     end
  181.    
  182.     return 'nil'
  183. end
  184.  
  185. function connection:format(v)
  186.     local type = type(v)
  187.     if     type == 'number' then
  188.         return v
  189.     elseif type == 'string' then
  190.         return ('"%s"'):format(v:gsub('"', '\\"'))
  191.     elseif type == 'table' then
  192.         for i = 1, #v do
  193.             v[i] = ('"%s"'):format(tostring(v[i]):gsub('"', '\\"'))
  194.         end
  195.         return concat(v, ' ')
  196.     end
  197. end
  198.  
  199. -- Delete a keys by mask
  200. function connection:pdel(mask)
  201.     assert(mask, 'Name or delete mask required')
  202.     local keys = self:request('keys '..mask)
  203.     if #keys == 0 then return true end
  204.     return self:trequest{'DEL ', unpack(keys)}
  205. end
  206.  
  207. -- // Set of classic command-methods
  208.  
  209. -- APPEND key value
  210. -- Append a value to a key
  211. function connection:append(key, value)
  212.     return self:trequest{'APPEND', key, self:format(value)}
  213. end
  214.  
  215. -- AUTH password
  216. -- Authenticate to the server
  217. function connection:auth(password)
  218.     self.pass = assert(password or self.pass, 'Password required')
  219.     return self:request('AUTH '..self.pass)
  220. end
  221.  
  222. -- BGREWRITEAOF
  223. -- Asynchronously rewrite the append-only file
  224. function connection:bgrewriteaof()
  225.     return self:request('BGREWRITEAOF')
  226. end
  227.  
  228. -- BGSAVE
  229. -- Asynchronously save the dataset to disk
  230. function connection:bgsave()
  231.     return self:request('BGSAVE')
  232. end
  233.  
  234. -- BITCOUNT key [start end]
  235. -- Count set bits in a string
  236. function connection:bitcount(key, s, e)
  237.     return self:trequest{'BITCOUNT', key, s, e}
  238. end
  239.  
  240. -- BITFIELD key [GET type offset] [SET type offset value] [INCRBY type offset increment] [OVERFLOW WRAP|SAT|FAIL]
  241. -- Perform arbitrary bitfield integer operations on strings
  242. function connection:bitfield(key, ...)
  243.     return self:trequest{'BITFIELD', key, ...}
  244. end
  245.  
  246. -- BITOP operation destkey key [key ...]
  247. -- Perform bitwise operations between strings
  248. function connection:bitop(key, destkey, key, ...)
  249.     return self:trequest{'BITOP', destkey, key, ...}
  250. end
  251.  
  252. -- BITPOS key bit [start] [end]
  253. -- Find first bit set or clear in a string
  254. function connection:bitpos(key, bit, s, e)
  255.     return self:trequest{'BITPOS', bit, s, e}
  256. end
  257.  
  258. -- BLPOP key [key ...] timeout
  259. -- Remove and get the first element in a list, or block until one is available
  260. function connection:blpop(key, ...)
  261.     return self:trequest{'BLPOP', key, ...}
  262. end
  263.  
  264. -- BRPOP key [key ...] timeout
  265. -- Remove and get the last element in a list, or block until one is available
  266. function connection:brpop(key, ...)
  267.     return self:trequest{'BRPOP', key, ...}
  268. end
  269.  
  270. -- BRPOPLPUSH source destination timeout
  271. -- Pop a value from a list, push it to another list and return it; or block until one is available
  272. function connection:brpoplpush(source, destination, timeout)
  273.     return self:trequest{'BRPOPLPUSH', source, destination, timeout}
  274. end
  275.  
  276. -- CLIENT KILL [ip:port] [ID client-id] [TYPE normal|master|slave|pubsub] [ADDR ip:port] [SKIPME yes/no]
  277. -- Kill the connection of a client
  278. function connection:clientKill(...)
  279.     return self:trequest{'CLIENT KILL', ...}
  280. end
  281.  
  282. -- CLIENT LIST
  283. -- Get the list of client connections
  284. function connection:clientList()
  285.     return self:request('CLIENT LIST')
  286. end
  287.  
  288. -- CLIENT GETNAME
  289. -- Get the current connection name
  290. function connection:clientGetName()
  291.     return self:request('CLIENT GETNAME')
  292. end
  293.  
  294. -- CLIENT PAUSE timeout
  295. -- Stop processing commands from clients for some time
  296. function connection:clientPause(timeout)
  297.     return self:request('CLIENT PAUSE '..(timeout or 0))
  298. end
  299.  
  300. -- CLIENT REPLY ON|OFF|SKIP
  301. -- Instruct the server whether to reply to commands
  302. function connection:clientReply(mode)
  303.     return self:request('CLIENT REPLY '..(mode or 'ON'))
  304. end
  305.  
  306. -- CLIENT SETNAME connection-name
  307. -- Set the current connection name
  308. function connection:clientSetName(name)
  309.     return self:request('CLIENT SETNAME '..name)
  310. end
  311.  
  312. -- CLUSTER ADDSLOTS slot [slot ...]
  313. -- Assign new hash slots to receiving node
  314. function connection:clusterAddSlots(slot, ...)
  315.     return self:trequest{'CLUSTER ADDSLOTS', slot, ...}
  316. end
  317.  
  318. -- CLUSTER COUNT-FAILURE-REPORTS node-id
  319. -- Return the number of failure reports active for a given node
  320. function connection:clusterCountFailureReports(node)
  321.     return self:request('CLUSTER COUNT-FAILURE-REPORTS '..node)
  322. end
  323.  
  324. -- CLUSTER COUNTKEYSINSLOT slot
  325. -- Return the number of local keys in the specified hash slot
  326. function connection:clusterCountKeysInSlot(slot)
  327.     return self:request('CLUSTER COUNTKEYSINSLOT '..slot)
  328. end
  329.  
  330. -- CLUSTER DELSLOTS slot [slot ...]
  331. -- Set hash slots as unbound in receiving node
  332. function connection:clusterDelSlots(slot, ...)
  333.     return self:trequest{'CLUSTER DELSLOTS', slot, ...}
  334. end
  335.  
  336. -- CLUSTER FAILOVER [FORCE|TAKEOVER]
  337. -- Forces a slave to perform a manual failover of its master.
  338. function connection:clusterFailover(mode)
  339.     return self:request('CLUSTER FAILOVER '..(mode or 'FORCE'))
  340. end
  341.  
  342. -- CLUSTER FORGET node-id
  343. -- Remove a node from the nodes table
  344. function connection:clusterForget(node)
  345.     return self:request('CLUSTER FORGET '..node)
  346. end
  347.  
  348. -- CLUSTER GETKEYSINSLOT slot count
  349. -- Return local key names in the specified hash slot
  350. function connection:clusterGetKeysInSlot(slot, count)
  351.     return self:trequest{'CLUSTER GETKEYSINSLOT', slot, count}
  352. end
  353.  
  354. -- CLUSTER INFO
  355. -- Provides info about Redis Cluster node state
  356. function connection:clusterInfo()
  357.     return self:request('CLUSTER INFO')
  358. end
  359.  
  360. -- CLUSTER KEYSLOT key
  361. -- Returns the hash slot of the specified key
  362. function connection:clusterKeyslot(key)
  363.     return self:request('CLUSTER KEYSLOT '..key)
  364. end
  365.  
  366. -- CLUSTER MEET ip port
  367. -- Force a node cluster to handshake with another node
  368. function connection:clusterMeet(ip, port)
  369.     return self:trequest{'CLUSTER MEET', ip, port}
  370. end
  371.  
  372. -- CLUSTER NODES
  373. -- Get Cluster config for the node
  374. function connection:clusterNodes()
  375.     return self:request('CLUSTER NODES')
  376. end
  377.  
  378. -- CLUSTER REPLICATE node-id
  379. -- Reconfigure a node as a slave of the specified master node
  380. function connection:clusterReplicate(node)
  381.     return self:request('CLUSTER REPLICATE '..node)
  382. end
  383.  
  384. -- CLUSTER RESET [HARD|SOFT]
  385. -- Reset a Redis Cluster node
  386. function connection:clusterReset(mode)
  387.     return self:request('CLUSTER RESET '..(mode or 'HARD'))
  388. end
  389.  
  390. -- CLUSTER SAVECONFIG
  391. -- Forces the node to save cluster state on disk
  392. function connection:clusterSaveConfig()
  393.     return self:request('CLUSTER SAVECONFIG')
  394. end
  395.  
  396. -- CLUSTER SET-CONFIG-EPOCH config-epoch
  397. -- Set the configuration epoch in a new node
  398. function connection:clusterSetConfigEpoch(config_epoch)
  399.     return self:request('CLUSTER SET-CONFIG-EPOCH '..config_epoch)
  400. end
  401.  
  402. -- CLUSTER SETSLOT slot IMPORTING|MIGRATING|STABLE|NODE [node-id]
  403. -- Bind a hash slot to a specific node
  404. function connection:clusterSetSlot(slot, mode, node)
  405.     return self:trequest{'CLUSTER SETSLOT', slot, mode, node}
  406. end
  407.  
  408. -- CLUSTER SLAVES node-id
  409. -- List slave nodes of the specified master node
  410. function connection:clusterSlaves(node)
  411.     return self:request('CLUSTER SLAVES '..node)
  412. end
  413.  
  414. -- CLUSTER SLOTS
  415. -- Get array of Cluster slot to node mappings
  416. function connection:clusterSlots()
  417.     return self:request('CLUSTER SLOTS')
  418. end
  419.  
  420. -- COMMAND
  421. -- Get array of Redis command details
  422. function connection:command()
  423.     return self:request('COMMAND')
  424. end
  425.  
  426. -- COMMAND COUNT
  427. -- Get total number of Redis commands
  428. function connection:commandCount()
  429.     return self:request('COMMAND COUNT')
  430. end
  431.  
  432. -- COMMAND GETKEYS
  433. -- Extract keys given a full Redis command
  434. function connection:commandGetKeys()
  435.     return self:request('COMMAND GETKEYS')
  436. end
  437.  
  438. -- COMMAND INFO command-name [command-name ...]
  439. -- Get array of specific Redis command details
  440. function connection:commandInfo(command, ...)
  441.     return self:trequest{'COMMAND INFO', command, ...}
  442. end
  443.  
  444. -- CONFIG GET parameter
  445. -- Get the value of a configuration parameter
  446. function connection:configGet(param)
  447.     return self:request('CONFIG GET '..param)
  448. end
  449.  
  450. -- CONFIG REWRITE
  451. -- Rewrite the configuration file with the in memory configuration
  452. function connection:configRewrite()
  453.     return self:request('CONFIG REWRITE')
  454. end
  455.  
  456. -- CONFIG SET parameter value
  457. -- Set a configuration parameter to the given value
  458. function connection:configSet(...)
  459.     return self:trequest{'CONFIG SET ', ...}
  460. end
  461.  
  462. -- CONFIG RESETSTAT
  463. -- Reset the stats returned by INFO
  464. function connection:configResetStat()
  465.     return self:request('CONFIG RESETSTAT')
  466. end
  467.  
  468. -- DBSIZE
  469. -- Return the number of keys in the selected database
  470. function connection:dbsize()
  471.     return self:request('DBSIZE')
  472. end
  473.  
  474. -- DEBUG OBJECT key
  475. -- Get debugging information about a key
  476. function connection:debugObject(key)
  477.     return self:request('DEBUG OBJECT '..key)
  478. end
  479.  
  480. -- DEBUG SEGFAULT
  481. -- Make the server crash
  482. function connection:debugSegfault()
  483.     return self:request('DEBUG SEGFAULT')
  484. end
  485.  
  486. -- DECR key
  487. -- Decrement the integer value of a key by one
  488. function connection:decr(key)
  489.     return self:request('DECR '..key)
  490. end
  491.  
  492. -- DECRBY key decrement
  493. -- Decrement the integer value of a key by the given number
  494. function connection:decrby(key, inc)
  495.     return self:trequest{'DECRBY', key, inc}
  496. end
  497.  
  498. -- DEL key [key ...]
  499. -- Delete a key
  500. function connection:del(...)
  501.     self:trequest{'DEL', ...}
  502. end
  503.  
  504. -- DISCARD
  505. -- Discard all commands issued after MULTI
  506. function connection:discard()
  507.     return self:request('DISCARD')
  508. end
  509.  
  510. -- DUMP key
  511. -- Return a serialized version of the value stored at the specified key.
  512. function connection:dump(key)
  513.     return self:request('DUMP '..key)
  514. end
  515.  
  516. -- ECHO message
  517. -- Echo the given string
  518. function connection:echo(msg)
  519.     return self:request('ECHO '..self:format(msg))
  520. end
  521.  
  522. -- EVAL script numkeys key [key ...] arg [arg ...]
  523. -- Execute a Lua script server side
  524. function connection:eval(script, nargs, ...)
  525.     local args = self:format{...}
  526.     return self:trequest{'EVAL', self:format(script), nargs or 0, unpack(args)}
  527. end
  528.  
  529. -- EVALSHA sha1 numkeys key [key ...] arg [arg ...]
  530. -- Execute a Lua script server side
  531. function connection:evalsha(script, nargs, ...)
  532.     local args = self:format{...}
  533.     return self:trequest{'EVALSHA', script, nargs or 0, unpack(args)}
  534. end
  535.  
  536. -- EXEC
  537. -- Execute all commands issued after MULTI
  538. function connection:exec()
  539.     return self:request('EXEC')
  540. end
  541.  
  542. -- EXISTS key [key ...]
  543. -- Determine if a key exists
  544. function connection:exists(...)
  545.     return self:trequest{'EXISTS', ...}
  546. end
  547.  
  548. -- EXPIRE key seconds
  549. -- Set a key's time to live in seconds
  550. function connection:expire(key, seconds)
  551.     return self:trequest{'EXPIRE', key, seconds}
  552. end
  553.  
  554. -- EXPIREAT key timestamp
  555. -- Set the expiration for a key as a UNIX timestamp
  556. function connection:expireAt(key, timestamp)
  557.     return self:trequest{'EXPIREAT', key, timestamp}
  558. end
  559.  
  560. -- FLUSHALL [ASYNC]
  561. -- Remove all keys from all databases
  562. function connection:flushAll(async)
  563.     return self:trequest{'FLUSHALL', async and 'ASYNC' or nil}
  564. end
  565.  
  566. -- FLUSHDB [ASYNC]
  567. -- Remove all keys from the current database
  568. function connection:flushDB(async)
  569.     return self:trequest{'FLUSHDB', async and 'ASYNC' or nil}
  570. end
  571.  
  572. -- GEOADD key longitude latitude member [longitude latitude member ...]
  573. -- Add one or more geospatial items in the geospatial index represented using a sorted set
  574. function connection:geoAdd(key, ...)
  575.     return self:trequest{'GEOADD', key, ...}
  576. end
  577.  
  578. -- GEOHASH key member [member ...]
  579. -- Returns members of a geospatial index as standard geohash strings
  580. function connection:geoHash(key, ...)
  581.     return self:trequest{'GEOHASH', key, ...}
  582. end
  583.  
  584. -- GEOPOS key member [member ...]
  585. -- Returns longitude and latitude of members of a geospatial index
  586. function connection:geoPos(key, ...)
  587.     return self:trequest{'GEOPOS', key, ...}
  588. end
  589.  
  590. -- GEODIST key member1 member2 [unit]
  591. -- Returns the distance between two members of a geospatial index
  592. function connection:geoDist(key, ...)
  593.     return self:trequest{'GEODIST', key, ...}
  594. end
  595.  
  596. -- GEORADIUS key longitude latitude radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC] [STORE key] [STOREDIST key]
  597. -- Query a sorted set representing a geospatial index to fetch members matching a given maximum distance from a point
  598. function connection:geoRadius(key, long, lat, rad, ...)
  599.     return self:trequest{'GEORADIUS', key, long, lat, rad, ...}
  600. end
  601.  
  602. -- GEORADIUSBYMEMBER key member radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC] [STORE key] [STOREDIST key]
  603. -- Query a sorted set representing a geospatial index to fetch members matching a given maximum distance from a member
  604. function connection:geoRadiusByMember(key, member, rad, ...)
  605.     return self:trequest{'GEORADIUSBYMEMBER', key, member, rad, ...}
  606. end
  607.  
  608. -- GET key
  609. -- Get the value of a key
  610. function connection:get(key)
  611.     return self:request('GET '..key)
  612. end
  613.  
  614. -- GETBIT key offset
  615. -- Returns the bit value at offset in the string value stored at key
  616. function connection:getBit(key, offset)
  617.     return self:trequest{'GETBIT', key, offset}
  618. end
  619.  
  620. -- GETRANGE key start end
  621. -- Get a substring of the string stored at a key
  622. function connection:getRange(key, s, e)
  623.     return self:trequest{'GETRANGE', s, e}
  624. end
  625.  
  626. -- GETSET key value
  627. -- Set the string value of a key and return its old value
  628. function connection:getSet(key, value)
  629.     return self:trequest{'GETSET', key, self:format(value)}
  630. end
  631.  
  632. -- HDEL key field [field ...]
  633. -- Delete one or more hash fields
  634. function connection:hdel(key, ...)
  635.     return self:trequest{'HDEL', ...}
  636. end
  637.  
  638. -- HEXISTS key field
  639. -- Determine if a hash field exists
  640. function connection:hexists(key, field)
  641.     return self:trequest{'HEXISTS', key, field}
  642. end
  643.  
  644. -- HGET key field
  645. -- Get the value of a hash field
  646. function connection:hget(key, field)
  647.     return self:trequest{'HGET', key, field}
  648. end
  649.  
  650. -- HGETALL key
  651. -- Get all the fields and values in a hash
  652. function connection:hgetall(key)
  653.     return self:request('HGETALL '..key)
  654. end
  655.  
  656. -- HINCRBY key field increment
  657. -- Increment the integer value of a hash field by the given number
  658. function connection:hincrby(key, field, increment)
  659.     return self:trequest{'HINCRBY', key, field, increment}
  660. end
  661.  
  662. -- HINCRBYFLOAT key field increment
  663. -- Increment the float value of a hash field by the given amount
  664. function connection:hincrbyfloat(key, field, increment)
  665.     return self:trequest{'HINCRBYFLOAT', key, field, increment}
  666. end
  667.  
  668. -- HKEYS key
  669. -- Get all the fields in a hash
  670. function connection:hkeys(key)
  671.     return self:request('HKEYS '..key)
  672. end
  673.  
  674. -- HLEN key
  675. -- Get the number of fields in a hash
  676. function connection:hlen(key)
  677.     return self:request('HLEN '..key)
  678. end
  679.  
  680. -- HMGET key field [field ...]
  681. -- Get the values of all the given hash fields
  682. function connection:hmget(key, ...)
  683.     return self:trequest{'HMGET', key, ...}
  684. end
  685.  
  686. -- HMSET key field value [field value ...]
  687. -- Set multiple hash fields to multiple values
  688. function connection:hmset(key, ...)
  689.     local args = {...}
  690.     for i = 2, #args, 2 do args[i] = self:format(args[i]) end
  691.     return self:trequest{'HMSET', key, unpack(args)}
  692. end
  693.  
  694. -- HSET key field value
  695. -- Set the string value of a hash field
  696. function connection:hset(key, field, value)
  697.     return self:trequest{'HSET', key, field, value and self:format(value) or 'nil'}
  698. end
  699.  
  700. -- HSETNX key field value
  701. -- Set the value of a hash field, only if the field does not exist
  702. function connection:hsetnx(key, field, value)
  703.     return self:trequest{'HSETNX', key, field, self:format(value)}
  704. end
  705.  
  706. -- HSTRLEN key field
  707. -- Get the length of the value of a hash field
  708. function connection:hstrlen(key, field)
  709.     return self:trequest{'HSTRLEN', key, field}
  710. end
  711.  
  712. -- HVALS key
  713. -- Get all the values in a hash
  714. function connection:hvals(key)
  715.     return self:request('HVALS '..key)
  716. end
  717.  
  718. -- INCR key
  719. -- Increment the integer value of a key by one
  720. function connection:incr(key)
  721.     return self:request('INCR '..key)
  722. end
  723.  
  724. -- INCRBY key increment
  725. -- Increment the integer value of a key by the given amount
  726. function connection:incrby(key, increment)
  727.     return self:trequest{'INCRBY', key, increment}
  728. end
  729.  
  730. -- INCRBYFLOAT key increment
  731. -- Increment the float value of a key by the given amount
  732. function connection:incrbyfloat(key, increment)
  733.     return self:trequest{'INCRBYFLOAT', key, increment}
  734. end
  735.  
  736. -- INFO [section]
  737. -- Get information and statistics about the server
  738. function connection:info(section)
  739.     return self:trequest{'INFO', section}
  740. end
  741.  
  742. -- KEYS pattern
  743. -- Find all keys matching the given pattern
  744. function connection:keys(mask)
  745.     return self:request('KEYS '..(mask or '*'))
  746. end
  747.  
  748. -- LASTSAVE
  749. -- Get the UNIX time stamp of the last successful save to disk
  750. function connection:lastsave()
  751.     return self:request('LASTSAVE')
  752. end
  753.  
  754. -- LINDEX key index
  755. -- Get an element from a list by its index
  756. function connection:lindex(key, index)
  757.     return self:trequest{'LINDEX', key, index}
  758. end
  759.  
  760. -- LINSERT key BEFORE|AFTER pivot value
  761. -- Insert an element before or after another element in a list
  762. function connection:linsert(key, pivot, value, shift)
  763.     shift = shift and 'BEFORE' or 'AFTER'
  764.     return self:trequest{'LINSERT', key, shift, self:format(pivot), self:format(value)}
  765. end
  766.  
  767. -- LLEN key
  768. -- Get the length of a list
  769. function connection:llen(key)
  770.     return self:request('LLEN '..key)
  771. end
  772.  
  773. -- LPOP key
  774. -- Remove and get the first element in a list
  775. function connection:lpop(key)
  776.     return self:request('LPOP '..key)
  777. end
  778.  
  779. -- LPUSH key value [value ...]
  780. -- Prepend one or multiple values to a list
  781. function connection:lpush(key, value)
  782.     return self:trequest{'LPUSH', key, self:format(value)}
  783. end
  784.  
  785. -- LPUSHX key value
  786. -- Prepend a value to a list, only if the list exists
  787. function connection:lpushx(key, value)
  788.     return self:trequest{'LPUSHX', key, self:format(value)}
  789. end
  790.  
  791. -- LRANGE key start stop
  792. -- Get a range of elements from a list
  793. function connection:lrange(key, s, e)
  794.     return self:trequest{'LRANGE', key, s, e}
  795. end
  796.  
  797. -- LREM key count value
  798. -- Remove elements from a list
  799. function connection:lrem(key, count, value)
  800.     return self:trequest{'LREM', key, count, self:format(value)}
  801. end
  802.  
  803. -- LSET key index value
  804. -- Set the value of an element in a list by its index
  805. function connection:lset(key, index, value)
  806.     return self:trequest{'LSET', key, index, self:format(value)}
  807. end
  808.  
  809. -- LTRIM key start stop
  810. -- Trim a list to the specified range
  811. function connection:ltrim(key, s, e)
  812.     return self:trequest{'LTRIM', key, s, e}
  813. end
  814.  
  815. -- MEMORY DOCTOR
  816. -- Outputs memory problems report
  817. function connection:memoryDoctor()
  818.     return self:request('MEMORY DOCTOR')
  819. end
  820.  
  821. -- MEMORY HELP
  822. -- Show helpful text about the different subcommands
  823. function connection:memoryHelp()
  824.     return self:request('MEMORY HELP')
  825. end
  826.  
  827. -- MEMORY MALLOC-STATS
  828. -- Show allocator internal stats
  829. function connection:memoryMallocStats()
  830.     return self:request('MEMORY MALLOC-STATS')
  831. end
  832.  
  833. -- MEMORY PURGE
  834. -- Ask the allocator to release memory
  835. function connection:memoryPurge()
  836.     return self:request('MEMORY PURGE')
  837. end
  838.  
  839. -- MEMORY STATS
  840. -- Show memory usage details
  841. function connection:memoryStats()
  842.     return self:request('MEMORY STATS')
  843. end
  844.  
  845. -- MEMORY USAGE key [SAMPLES count]
  846. -- Estimate the memory usage of a key
  847. function connection:memoryUsage(key, count)
  848.     return self:trequest{'MEMORY USAGE', key, 'SAMPLES', count or 5}
  849. end
  850.  
  851. -- MGET key [key ...]
  852. -- Get the values of all the given keys
  853. function connection:mget(key, ...)
  854.     return self:trequest{'MGET', key, ...}
  855. end
  856.  
  857. -- MIGRATE host port key|"" destination-db timeout [COPY] [REPLACE] [KEYS key [key ...]]
  858. -- Atomically transfer a key from a Redis instance to another one.
  859. function connection:migrate(host, port, key, destination, timeout, ...)
  860.     return self:trequest{'MIGRATE', host, port, key, destination, timeout, ...}
  861. end
  862.  
  863. -- MONITOR
  864. -- Listen for all requests received by the server in real time
  865. -- Returns monitoring object, string log is path to logging file
  866. function connection:monitor(log)
  867.     local conn = self
  868.     local self = {}
  869.     self.__file = log and assert(io.open(log, 'wb'), 'Cannot open '..tostring(log)..' path')
  870.     self.__type = 'monitor'
  871.     self.__conn = connection:new(conn.ip, conn.port, conn.pass)
  872.     self.__conn:settimeout(.25)
  873.     self.__conn:connect()
  874.     print('MON', self.__conn:request('MONITOR'))
  875.  
  876.     function self:receive()
  877.         local data, err = self.__conn:receive(true)
  878.         if self.__file then
  879.             while data do
  880.                 self.__file:write(tostring(data)..'\r\n')
  881.                 data, err = self.__conn:receive(true)
  882.             end
  883.         else
  884.             return data, err
  885.         end
  886.     end
  887.    
  888.     function self:close()
  889.         self.receive = function() error('Monitoring disconnected') end
  890.         return self.__conn:close()
  891.     end
  892.    
  893.     return self
  894. end
  895.  
  896. -- MOVE key db
  897. -- Move a key to another database
  898. function connection:move(key, db)
  899.     return self:trequest{'MOVE', key, db}
  900. end
  901.  
  902. -- MSET key value [key value ...]
  903. -- Set multiple keys to multiple values
  904. function connection:mset(...)
  905.     local args = {...}
  906.     for i = 2, #args, 2 do args[i] = self:format(args[i]) end
  907.     return self:trequest{'MSET', unpack(args)}
  908. end
  909.  
  910. -- MSETNX key value [key value ...]
  911. -- Set multiple keys to multiple values, only if none of the keys exist
  912. function connection:msetnx(...)
  913.     local args = {...}
  914.     for i = 2, #args, 2 do args[i] = self:format(args[i]) end
  915.     return self:trequest{'MSETNX', unpack(args)}
  916. end
  917.  
  918. -- MULTI
  919. -- Mark the start of a transaction block
  920. function connection:multi()
  921.     return self:request('MULTI')
  922. end
  923.  
  924. -- OBJECT subcommand [arguments [arguments ...]]
  925. -- Inspect the internals of Redis objects
  926. function connection:object(subcommand, ...)
  927.     return self:trequest{'OBJECT', subcommand, ...}
  928. end
  929.  
  930. -- PERSIST key
  931. -- Remove the expiration from a key
  932. function connection:persist(key)
  933.     return self:request('PERSIST '..key)
  934. end
  935.  
  936. -- PEXPIRE key milliseconds
  937. -- Set a key's time to live in milliseconds
  938. function connection:pexpire(key, milliseconds)
  939.     return self:trequest{'PEXPIRE', key, milliseconds}
  940. end
  941.  
  942. -- PEXPIREAT key milliseconds-timestamp
  943. -- Set the expiration for a key as a UNIX timestamp specified in milliseconds
  944. function connection:pexpireat(key, milliseconds_ts)
  945.     return self:trequest{'PEXPIREAT', key, milliseconds_ts}
  946. end
  947.  
  948. -- PFADD key element [element ...]
  949. -- Adds the specified elements to the specified HyperLogLog.
  950. function connection:pfadd(key, element, ...)
  951.     return self:trequest{'PFADD', element, ...}
  952. end
  953.  
  954. -- PFCOUNT key [key ...]
  955. -- Return the approximated cardinality of the set(s) observed by the HyperLogLog at key(s).
  956. function connection:pfcount(key, ...)
  957.     return self:trequest{'PFCOUNT', key, ...}
  958. end
  959.  
  960. -- PFMERGE destkey sourcekey [sourcekey ...]
  961. -- Merge N different HyperLogLogs into a single one.
  962. function connection:pfmerge(destkey, sourcekey, ...)
  963.     return self:trequest{'PFMERGE', destkey, sourcekey, ...}
  964. end
  965.  
  966. -- PING [message]
  967. -- Ping the server
  968. function connection:ping(msg)
  969.     return self:trequest{'PING', msg} and true
  970. end
  971.  
  972. -- PSETEX key milliseconds value
  973. -- Set the value and expiration in milliseconds of a key
  974. function connection:psetex(key, ms, value)
  975.     return self:trequest{'PSETEX', ms, self:format(value)}
  976. end
  977.  
  978. -- PUBSUB subcommand [argument [argument ...]]
  979. -- Inspect the state of the Pub/Sub subsystem
  980. function connection:pubsub(subcommand, ...)
  981.     return self:trequest{'PUBSUB', subcommand, ...}
  982. end
  983.  
  984. -- PTTL key
  985. -- Get the time to live for a key in milliseconds
  986. function connection:pttl(key)
  987.     return self:request('PTTL '..key)
  988. end
  989.  
  990. -- QUIT
  991. -- Close the connection
  992. function connection:quit()
  993.     return self:request('QUIT')
  994. end
  995.  
  996. -- RANDOMKEY
  997. -- Return a random key from the keyspace
  998. function connection:randomkey()
  999.     return self:request('RANDOMKEY')
  1000. end
  1001.  
  1002. -- READONLY
  1003. -- Enables read queries for a connection to a cluster slave node
  1004. function connection:readonly()
  1005.     return self:request('READONLY')
  1006. end
  1007.  
  1008. -- READWRITE
  1009. -- Disables read queries for a connection to a cluster slave node
  1010. function connection:readwrite()
  1011.     return self:request('READWRITE')
  1012. end
  1013.  
  1014. -- RENAME key newkey
  1015. -- Rename a key
  1016. function connection:rename(key, newkey)
  1017.     return self:trequest{'RENAME', key, newkey}
  1018. end
  1019.  
  1020. -- RENAMENX key newkey
  1021. -- Rename a key, only if the new key does not exist
  1022. function connection:renamenx(key, newkey)
  1023.     return self:trequest{'RENAMENX', key, newkey}
  1024. end
  1025.  
  1026. -- RESTORE key ttl serialized-value [REPLACE]
  1027. -- Create a key using the provided serialized value, previously obtained using DUMP.
  1028. function connection:restore(key, ttl, serialized_value, replace)
  1029.     return self:trequest{'RENAMENX', key, ttl, serialized_value, replace and 'REPLACE'}
  1030. end
  1031.  
  1032. -- ROLE
  1033. -- Return the role of the instance in the context of replication
  1034. function connection:role()
  1035.     return self:request('ROLE')
  1036. end
  1037.  
  1038. -- RPOP key
  1039. -- Remove and get the last element in a list
  1040. function connection:rpop(key)
  1041.     return self:request('RPOP '..key)
  1042. end
  1043.  
  1044. -- RPOPLPUSH source destination
  1045. -- Remove the last element in a list, prepend it to another list and return it
  1046. function connection:rpoplpush(source, destination)
  1047.     return self:trequest{'RPOPLPUSH', source, destination}
  1048. end
  1049.  
  1050. -- RPUSH key value [value ...]
  1051. -- Append one or multiple values to a list
  1052. function connection:rpush(key, ...)
  1053.     return self:trequest{'RPUSH', key, unpack(self:format{...})}
  1054. end
  1055.  
  1056. -- RPUSHX key value
  1057. -- Append a value to a list, only if the list exists
  1058. function connection:rpushx(key, ...)
  1059.     return self:trequest{'RPUSHX', key, unpack(self:format{...})}
  1060. end
  1061.  
  1062. -- SADD key member [member ...]
  1063. -- Add one or more members to a set
  1064. function connection:sadd(key, ...)
  1065.     return self:trequest{'SADD', key, unpack(self:format{...})}
  1066. end
  1067.  
  1068. -- SAVE
  1069. -- Synchronously save the dataset to disk
  1070. function connection:save()
  1071.     return self:request('SAVE')
  1072. end
  1073.  
  1074. -- SCARD key
  1075. -- Get the number of members in a set
  1076. function connection:scard(key)
  1077.     return self:request('SCARD '..key)
  1078. end
  1079.  
  1080. -- SCRIPT DEBUG YES|SYNC|NO
  1081. -- Set the debug mode for executed scripts.
  1082. function connection:scriptDebug(mode)
  1083.     return self:request('SCRIPT DEBUG '..(mode or 'YES'))
  1084. end
  1085.  
  1086. -- SCRIPT EXISTS sha1 [sha1 ...]
  1087. -- Check existence of scripts in the script cache.
  1088. function connection:scriptExists(...)
  1089.     return self:trequest{'SCRIPT EXISTS', ...}
  1090. end
  1091.  
  1092. -- SCRIPT FLUSH
  1093. -- Remove all the scripts from the script cache.
  1094. function connection:scriptFlush()
  1095.     return self:request('SCRIPT FLUSH')
  1096. end
  1097.  
  1098. -- SCRIPT KILL
  1099. -- Kill the script currently in execution.
  1100. function connection:scriptKill()
  1101.     return self:request('SCRIPT KILL')
  1102. end
  1103.  
  1104. -- SCRIPT LOAD script
  1105. -- Load the specified Lua script into the script cache.
  1106. function connection:scriptLoad(script)
  1107.     return self:request('SCRIPT LOAD '..self:format(script:gsub('[\r\n]', [[\r\n]])))
  1108. end
  1109.  
  1110. -- SDIFF key [key ...]
  1111. -- Subtract multiple sets
  1112. function connection:sdiff(key, ...)
  1113.     return self:trequest{'SDIFF', key, ...}
  1114. end
  1115.  
  1116. -- SDIFFSTORE destination key [key ...]
  1117. -- Subtract multiple sets and store the resulting set in a key
  1118. function connection:sdiffstore(destination, key, ...)
  1119.     return self:trequest{'SDIFFSTORE', destination, key, ...}
  1120. end
  1121.  
  1122. -- SELECT index
  1123. -- Change the selected database for the current connection
  1124. function connection:select(index)
  1125.     return self:request('SELECT '..index)
  1126. end
  1127.  
  1128. -- SET key value [EX seconds] [PX milliseconds] [NX|XX]
  1129. -- Set the string value of a key
  1130. function connection:set(key, value, ex, ex_mode)
  1131.     local req = {}
  1132.     req[1] = 'SET'
  1133.     req[2] = tostring(key)
  1134.     req[3] = self:format(value)
  1135.     if type(ex) == 'number' then
  1136.         local sec = floor(ex)
  1137.         local msc = floor(ex % 1 * 1000)
  1138.         req[#req + 1] = ('EX %d PX %d'):format(sec, msc)
  1139.     end
  1140.     if type(ex_mode) == 'boolean' then
  1141.         req[#req + 1] = ex_mode and 'NX' or 'XX'
  1142.     end
  1143.  
  1144.     return self:trequest(req)
  1145. end
  1146.  
  1147. -- SETBIT key offset value
  1148. -- Sets or clears the bit at offset in the string value stored at key
  1149. function connection:setbit(key, offset, value)
  1150.     return self:trequest{'SETBIT', key, offset, self:format(value)}
  1151. end
  1152.  
  1153. -- SETEX key seconds value
  1154. -- Set the value and expiration of a key
  1155. function connection:setex(key, seconds, value)
  1156.     return self:trequest{'SETEX', key, seconds, self:format(value)}
  1157. end
  1158.  
  1159. -- SETNX key value
  1160. -- Set the value of a key, only if the key does not exist
  1161. function connection:setnx(key, value)
  1162.     return self:trequest{'SETNX', key, self:format(value)}
  1163. end
  1164.  
  1165. -- SETRANGE key offset value
  1166. -- Overwrite part of a string at key starting at the specified offset
  1167. function connection:setrange(key, offset, value)
  1168.     return self:trequest{'SETRANGE', key, offset, self:format(value)}
  1169. end
  1170.  
  1171. -- SHUTDOWN [NOSAVE|SAVE]
  1172. -- Synchronously save the dataset to disk and then shut down the server
  1173. function connection:shutdown(noSave)
  1174.     return self:request('SHUTDOWN '..(noSave and 'NOSAVE' or 'SAVE'))
  1175. end
  1176.  
  1177. -- SINTER key [key ...]
  1178. -- Intersect multiple sets
  1179. function connection:sinter(key, ...)
  1180.     return self:trequest{'SINTER', key, ...}
  1181. end
  1182.  
  1183. -- SINTERSTORE destination key [key ...]
  1184. -- Intersect multiple sets and store the resulting set in a key
  1185. function connection:sinterstore(destination, key, ...)
  1186.     return self:trequest{'SINTERSTORE', destination, key, ...}
  1187. end
  1188.  
  1189. -- SISMEMBER key member
  1190. -- Determine if a given value is a member of a set
  1191. function connection:sismember(key, member)
  1192.     return self:trequest{'SISMEMBER', key, self:format(member)}
  1193. end
  1194.  
  1195. -- SLAVEOF host port
  1196. -- Make the server a slave of another instance, or promote it as master
  1197. function connection:slaveof(host, port)
  1198.     return self:trequest{'SLAVEOF', host, port}
  1199. end
  1200.  
  1201. -- SLOWLOG subcommand [argument]
  1202. -- Manages the Redis slow queries log
  1203. function connection:slowlog(subcommand, argument)
  1204.     return self:trequest{'SLOWLOG', subcommand, argument}
  1205. end
  1206.  
  1207. -- SMEMBERS key
  1208. -- Get all the members in a set
  1209. function connection:smembers(key)
  1210.     return self:request('SMEMBERS '..key)
  1211. end
  1212.  
  1213. -- SMOVE source destination member
  1214. -- Move a member from one set to another
  1215. function connection:smove(source, destination, member)
  1216.     return self:trequest{'SMOVE', source, destination, self:format(member)}
  1217. end
  1218.  
  1219. -- SORT key [BY pattern] [LIMIT offset count] [GET pattern [GET pattern ...]] [ASC|DESC] [ALPHA] [STORE destination]
  1220. -- Sort the elements in a list, set or sorted set
  1221. function connection:sort(key, ...)
  1222.     return self:trequest{'SORT', key, ...}
  1223. end
  1224.  
  1225. -- SPOP key [count]
  1226. -- Remove and return one or multiple random members from a set
  1227. function connection:spop(key, count)
  1228.     return self:trequest{'SPOP', key, count}
  1229. end
  1230.  
  1231. -- SRANDMEMBER key [count]
  1232. -- Get one or multiple random members from a set
  1233. function connection:srandmember(key, count)
  1234.     return self:trequest{'SRANDMEMBER', key, count}
  1235. end
  1236.  
  1237. -- SREM key member [member ...]
  1238. -- Remove one or more members from a set
  1239. function connection:srem(key, ...)
  1240.     return self:trequest{'SREM', key, unpack(self:format{...})}
  1241. end
  1242.  
  1243. -- STRLEN key
  1244. -- Get the length of the value stored in a key
  1245. function connection:strlen(key)
  1246.     return self:request('STRLEN '..key)
  1247. end
  1248.  
  1249. -- SUNION key [key ...]
  1250. -- Add multiple sets
  1251. function connection:sunion(key, ...)
  1252.     return self:trequest{'SUNION', key, ...}
  1253. end
  1254.  
  1255. -- SUNIONSTORE destination key [key ...]
  1256. -- Add multiple sets and store the resulting set in a key
  1257. function connection:sunionstore(destination, key, ...)
  1258.     return self:trequest{'SUNIONSTORE', destination, key, ...}
  1259. end
  1260.  
  1261. -- SWAPDB index index
  1262. -- Swaps two Redis databases
  1263. function connection:swapdb(indexA, indexB)
  1264.     return self:trequest{'SWAPDB', indexA, indexB}
  1265. end
  1266.  
  1267. -- SYNC
  1268. -- Internal command used for replication
  1269. function connection:sync()
  1270.     return self:request('SYNC')
  1271. end
  1272.  
  1273. -- TIME
  1274. -- Return the current server time
  1275. function connection:time()
  1276.     return self:request('TIME')
  1277. end
  1278.  
  1279. -- TOUCH key [key ...]
  1280. -- Alters the last access time of a key(s). Returns the number of existing keys specified.
  1281. function connection:touch(key, ...)
  1282.     return self:trequest{'TOUCH', key, ...}
  1283. end
  1284.  
  1285. -- TTL key
  1286. -- Get the time to live for a key
  1287. function connection:ttl(key)
  1288.     return self:request('TTL '..key)
  1289. end
  1290.  
  1291. -- TYPE key
  1292. -- Determine the type stored at key
  1293. function connection:type(obj)
  1294.     local res = self:request('TYPE '..obj)
  1295.     return res
  1296. end
  1297.  
  1298. -- UNLINK key [key ...]
  1299. -- Delete a key asynchronously in another thread. Otherwise it is just as DEL, but non blocking.
  1300. function connection:unlink(key, ...)
  1301.     return self:trequest{'UNLINK', key, ...}
  1302. end
  1303.  
  1304. -- UNWATCH
  1305. -- Forget about all watched keys
  1306. function connection:unwatch()
  1307.     return self:request('UNWATCH')
  1308. end
  1309.  
  1310. -- WAIT numslaves timeout
  1311. -- Wait for the synchronous replication of all the write commands sent in the context of the current connection
  1312. function connection:wait(numslaves, timeout)
  1313.     return self:trequest{'WAIT', numslaves, timeout}
  1314. end
  1315.  
  1316. -- WATCH key [key ...]
  1317. -- Watch the given keys to determine execution of the MULTI/EXEC block
  1318. function connection:watch(key, ...)
  1319.     return self:trequest{'WATCH', key, ...}
  1320. end
  1321.  
  1322. -- ZADD key [NX|XX] [CH] [INCR] score member [score member ...]
  1323. -- Add one or more members to a sorted set, or update its score if it already exists
  1324. function connection:zadd(key, ...)
  1325.     return self:trequest{'ZADD', key, ...}
  1326. end
  1327.  
  1328. -- ZCARD key
  1329. -- Get the number of members in a sorted set
  1330. function connection:zcard(key)
  1331.     return self:request('ZCARD '..key)
  1332. end
  1333.  
  1334. -- ZCOUNT key min max
  1335. -- Count the members in a sorted set with scores within the given values
  1336. function connection:zcount(key, min, max)
  1337.     return self:trequest{'ZCOUNT', key, min, max}
  1338. end
  1339.  
  1340. -- ZINCRBY key increment member
  1341. -- Increment the score of a member in a sorted set
  1342. function connection:zincrby(key, increment, member)
  1343.     return self:trequest{'ZINCRBY', key, increment, self:format(member)}
  1344. end
  1345.  
  1346. -- ZINTERSTORE destination numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX]
  1347. -- Intersect multiple sorted sets and store the resulting sorted set in a new key
  1348. function connection:zinterstore(destination, numkeys, key, ...)
  1349.     return self:trequest{'ZINTERSTORE', destination, numkeys, key, ...}
  1350. end
  1351.  
  1352. -- ZLEXCOUNT key min max
  1353. -- Count the number of members in a sorted set between a given lexicographical range
  1354. function connection:zlexcount(key, min, max)
  1355.     return self:trequest{'ZLEXCOUNT', key, min, max}
  1356. end
  1357.  
  1358. -- ZRANGE key start stop [WITHSCORES]
  1359. -- Return a range of members in a sorted set, by index
  1360. function connection:zrange(key, start, stop, withscores)
  1361.     return self:trequest{'ZRANGE', key, start, stop, (withscores and 'WITHSCORES' or nil)}
  1362. end
  1363.  
  1364. -- ZRANGEBYLEX key min max [LIMIT offset count]
  1365. -- Return a range of members in a sorted set, by lexicographical range
  1366. function connection:zrangebylex(key, min, max, ...)
  1367.     return self:trequest{'ZRANGEBYLEX', key, min, max, ...}
  1368. end
  1369.  
  1370. -- ZREVRANGEBYLEX key max min [LIMIT offset count]
  1371. -- Return a range of members in a sorted set, by lexicographical range, ordered from higher to lower strings.
  1372. function connection:zrevrangebylex(key, max, min, ...)
  1373.     return self:trequest{'ZREVRANGEBYLEX', key, max, min, ...}
  1374. end
  1375.  
  1376. -- ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]
  1377. -- Return a range of members in a sorted set, by score
  1378. function connection:zrangebyscore(key, min, max, withscores, ...)
  1379.     return self:trequest{'ZRANGEBYSCORE', key, min, max, (withscores and 'WITHSCORES' or nil), ...}
  1380. end
  1381.  
  1382. -- ZRANK key member
  1383. -- Determine the index of a member in a sorted set
  1384. function connection:zrank(key, member)
  1385.     return self:trequest{'ZRANK', key, self:format(member)}
  1386. end
  1387.  
  1388. -- ZREM key member [member ...]
  1389. -- Remove one or more members from a sorted set
  1390. function connection:zrem(key, ...)
  1391.     return self:trequest{'ZREM', key, self:format{...}}
  1392. end
  1393.  
  1394. -- ZREMRANGEBYLEX key min max
  1395. -- Remove all members in a sorted set between the given lexicographical range
  1396. function connection:zremrangebylex(key, min, max)
  1397.     return self:trequest{'ZREMRANGEBYLEX', key, min, max}
  1398. end
  1399.  
  1400. -- ZREMRANGEBYRANK key start stop
  1401. -- Remove all members in a sorted set within the given indexes
  1402. function connection:zremrangebyrank(key, start, stop)
  1403.     return self:trequest{'ZREMRANGEBYRANK', key, start, stop}
  1404. end
  1405.  
  1406. -- ZREMRANGEBYSCORE key min max
  1407. -- Remove all members in a sorted set within the given scores
  1408. function connection:zremrangebyscore(key, min, max)
  1409.     return self:trequest{'ZREMRANGEBYSCORE', key, min, max}
  1410. end
  1411.  
  1412. -- ZREVRANGE key start stop [WITHSCORES]
  1413. -- Return a range of members in a sorted set, by index, with scores ordered from high to low
  1414. function connection:zrevrange(key, start, stop, withscores)
  1415.     return self:trequest{'ZREVRANGE', key, start, stop, (withscores and 'WITHSCORES' or nil)}
  1416. end
  1417.  
  1418. -- ZREVRANGEBYSCORE key max min [WITHSCORES] [LIMIT offset count]
  1419. -- Return a range of members in a sorted set, by score, with scores ordered from high to low
  1420. function connection:zrevrangebyscore(key, max, min, withscores, ...)
  1421.     return self:trequest{'ZREVRANGEBYSCORE', key, max, min, (withscores and 'WITHSCORES' or nil), ...}
  1422. end
  1423.  
  1424. -- ZREVRANK key member
  1425. -- Determine the index of a member in a sorted set, with scores ordered from high to low
  1426. function connection:zrevrank(key, member)
  1427.     return self:trequest{'ZREVRANK', key, self:format(member)}
  1428. end
  1429.  
  1430. -- ZSCORE key member
  1431. -- Get the score associated with the given member in a sorted set
  1432. function connection:zscore(key, member)
  1433.     return self:trequest{'ZSCORE', key, self:format(member)}
  1434. end
  1435.  
  1436. -- ZUNIONSTORE destination numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX]
  1437. -- Add multiple sorted sets and store the resulting sorted set in a new key
  1438. function connection:zunionstore(destination, numkeys, ...)
  1439.     return self:trequest{'ZUNIONSTORE', destination, numkeys, ...}
  1440. end
  1441.  
  1442. -- SCAN cursor [MATCH pattern] [COUNT count]
  1443. -- Incrementally iterate the keys space
  1444. function connection:scan(cursor, ...)
  1445.     return self:trequest{'SCAN', cursor, ...}
  1446. end
  1447.  
  1448. -- SSCAN key cursor [MATCH pattern] [COUNT count]
  1449. -- Incrementally iterate Set elements
  1450. function connection:sscan(key, cursor, ...)
  1451.     return self:trequest{'SSCAN', key, cursor, ...}
  1452. end
  1453.  
  1454. -- HSCAN key cursor [MATCH pattern] [COUNT count]
  1455. -- Incrementally iterate hash fields and associated values
  1456. function connection:hscan(key, cursor, ...)
  1457.     return self:trequest{'HSCAN', key, cursor, ...}
  1458. end
  1459.  
  1460. -- ZSCAN key cursor [MATCH pattern] [COUNT count]
  1461. -- Incrementally iterate sorted sets elements and associated scores
  1462. function connection:zscan(key, cursor, ...)
  1463.     return self:trequest{'ZSCAN', key, cursor, ...}
  1464. end
  1465.  
  1466. -- PUBLISH channel message
  1467. -- Post a message to a channel
  1468. function connection:publish(channel, message)
  1469.     return self:trequest{'PUBLISH', channel, self:format(message)}
  1470. end
  1471.  
  1472. -- // base structure
  1473. local structure = {}
  1474. structure.__index = structure
  1475.  
  1476. function structure:new(name, connection)
  1477.     local o  = {}
  1478.     o.__name = name
  1479.     o.__conn = connection
  1480.     return setmetatable(o, self)
  1481. end
  1482.  
  1483. function structure:Inspect()
  1484.     return 'Structure ['..self.__name..']'
  1485. end
  1486.  
  1487. -- // structures
  1488. local hash   = setmetatable({}, structure)
  1489. hash.__type  = 'hash'
  1490.  
  1491. function hash:__index(key)
  1492.     key = key and tostring(key) or nil
  1493.     if hash[key] then return hash[key] end
  1494.     return self:Get(key)
  1495. end
  1496.  
  1497. function hash:__tostring()
  1498.     return 'Hash ['..self.__name..']'
  1499. end
  1500.  
  1501. function hash:new(name, connection)
  1502.     local o     = structure:new(name, connection)
  1503.     o.__updated = false
  1504.     o.__cache   = {}
  1505.     return setmetatable(o, self)
  1506. end
  1507.  
  1508. -- HSET key field value
  1509. -- Set the string value of a hash field
  1510. function hash:Set(key, value, mode)
  1511.     key = key and tostring(key) or nil
  1512.  
  1513.     local req = {}
  1514.     req[1] = 'hset'
  1515.     req[2] = self.__name
  1516.     req[3] = key
  1517.    
  1518.     if type(value) == 'nil' then
  1519.         req[1] = 'hdel'
  1520.         self.__cache[key] = nil
  1521.         return self.__conn:trequest(req)
  1522.     end
  1523.    
  1524.     if mode then
  1525.         req[1] = 'hsetnx'
  1526.     end
  1527.    
  1528.     req[4] = self.__conn:format(value)
  1529.     local res = self.__conn:trequest(req)
  1530.     if res then self.__cache[key] = value end
  1531.     return res
  1532. end
  1533.  
  1534. -- HSETNX key field value
  1535. -- Set the value of a hash field, only if the field does not exist
  1536. function hash:SetNx(key, value)
  1537.     return self:Set(key, value, true)
  1538. end
  1539.  
  1540. -- HMSET key field value [field value ...]
  1541. -- Set multiple hash fields to multiple values
  1542. function hash:Mset(tbl)
  1543.     local req = {}
  1544.     req[1] = 'hmset'
  1545.     req[2] = self.__name
  1546.     for key, value in pairs(tbl) do
  1547.         req[#req + 1] = tostring(key)
  1548.         req[#req + 1] = self.__conn:format(value)
  1549.     end
  1550.    
  1551.     return self.__conn:trequest(req)
  1552. end
  1553.  
  1554. -- HGET key field
  1555. -- Get the value of a hash field
  1556. function hash:Get(key)
  1557.     local cache = self.__cache[key]
  1558.     if cache then return cache end
  1559.    
  1560.     local req = {}
  1561.     req[1] = 'HGET'
  1562.     req[2] = self.__name
  1563.     req[3] = self.__conn:format(key)
  1564.    
  1565.     local value = self.__conn:trequest(req)
  1566.     -- cache
  1567.    
  1568.     if value ~= -1 then
  1569.         self.__cache[key] = value
  1570.     end
  1571.     return self.__cache[key]
  1572. end
  1573.  
  1574. function hash:Mget(...)
  1575.     local req = {}
  1576.     req[1] = 'HMGET'
  1577.     req[2] = self.__name
  1578.     req[3] = type(...) == 'tab'
  1579.     local t = type(...)
  1580.     if t == 'table' then
  1581.         req[3] = self.__conn:format(...)
  1582.     else
  1583.         req[3] = self.__conn:format{...}
  1584.     end
  1585.    
  1586.     local res = self.__conn:trequest(req)
  1587.    
  1588.     local value
  1589.     for i, key in ipairs(tbl) do
  1590.         value = res[i]
  1591.         self.__cache[key] = value ~= -1 and value or nil
  1592.     end
  1593.    
  1594.     return res
  1595. end
  1596.  
  1597. function hash:Mset(tbl)
  1598.     local req = {}
  1599.     req[1] = 'HMSET'
  1600.     req[2] = self.__name
  1601.    
  1602.     for key, value in pairs(tbl) do
  1603.         req[#req + 1] = tostring(key)
  1604.         req[#req + 1] = self.__conn:format(value)
  1605.         self.__cache[key] = value
  1606.     end
  1607.    
  1608.     return self.__conn:trequest(req)
  1609. end
  1610.  
  1611. hash.__newindex = hash.Set
  1612.  
  1613. function hash:Len()
  1614.     return self.__conn:request('HLEN '..self.__name)
  1615. end
  1616.  
  1617. function hash:Del(key)
  1618.     return self.__conn:trequest{'HDEL', self.__name, key}
  1619. end
  1620.  
  1621. function hash:StrLen(key)
  1622.     return self.__conn:trequest{'HSTRLEN', self.__name, key}
  1623. end
  1624.  
  1625. function hash:IncrBy(key, inc)
  1626.     return self.__conn:trequest{'HINCRBY', self.__name, key, inc or 1}
  1627. end
  1628.  
  1629. function hash:IncrByFloat(key, inc)
  1630.     return self.__conn:trequest{'HINCRBYFLOAT', self.__name, key, inc or 1}
  1631. end
  1632.  
  1633. function hash:Keys()
  1634.     return self.__conn:request('HKEYS '..self.__name)
  1635. end
  1636.  
  1637. function hash:Vals()
  1638.     return self.__conn:request('HVALS '..self.__name)
  1639. end
  1640.  
  1641. function hash:Pairs()
  1642.     self:GetAll()
  1643.     local key, value
  1644.     return function()
  1645.         key, value = next(self.__cache, key)
  1646.         return key, value
  1647.     end
  1648. end
  1649.  
  1650. function hash:Inspect(fmt)
  1651.     fmt = fmt or 0
  1652.     self:GetAll()
  1653.     local res = {}
  1654.     res[1] = ('%s (%s) {'):format(self.__name, self.__conn:type(self.__name))
  1655.    
  1656.     local template = '%'..fmt..'s: [%s]'
  1657.     for k, v in pairs(self.__cache) do
  1658.         res[#res + 1] = template:format(k, v)
  1659.     end
  1660.    
  1661.     res[#res + 1] = '}'
  1662.     return concat(res, '\n')
  1663. end
  1664.  
  1665. function hash:Scan(key, match, count)
  1666.     local req = {}
  1667.     req[1] = 'HSCAN'
  1668.     req[2] = self.__name
  1669.     req[3] = type(key) == 'number' and key or 0
  1670.     req[4] = 'MATCH'
  1671.     req[5] = match or '*'
  1672.     req[6] = 'COUNT'
  1673.     req[7] = count or 1000
  1674.    
  1675.     local res = self.__conn:trequest(req)
  1676.    
  1677.     key = res[1]
  1678.     res = res[2]
  1679.    
  1680.     local result = {}
  1681.     local key, value
  1682.     for i = 1, #res, 2 do
  1683.         key, value = res[i], res[i + 1]
  1684.         result[key]       = value
  1685.         self.__cache[key] = value
  1686.     end
  1687.    
  1688.     return result, key
  1689. end
  1690.  
  1691. function hash:Find(match, count)
  1692.     return self:Scan(0, match, count)
  1693. end
  1694.  
  1695. function hash:Exists(field)
  1696.     return self.__conn:trequest{'HEXISTS', self.__name, field}
  1697. end
  1698.  
  1699. -- HGETALL key
  1700. -- Get all the fields and values in a hash
  1701. function hash:GetAll()
  1702.     if self.__updated then return end
  1703.     self.__updated = true
  1704.     local res    = self.__conn:request('hgetall '..self.__name)
  1705.     local result = {}
  1706.     local key, value
  1707.    
  1708.     for i = 1, #res, 2 do
  1709.         key, value = res[i], res[i + 1]
  1710.         self.__cache[key] = value
  1711.         result[key]       = value
  1712.     end
  1713.    
  1714.     return result
  1715. end
  1716.  
  1717. -- DEL
  1718. function hash:Delete()
  1719.     return self.__conn:request('DEL '..self.__name)
  1720. end
  1721.  
  1722.  
  1723. local list = setmetatable({}, structure)
  1724. list.__type  = 'list'
  1725.  
  1726. function list:new(name, connection)
  1727.     local o     = structure:new(name, connection)
  1728.     o.__updated = false
  1729.     o.__cache   = {}
  1730.     return setmetatable(o, self)
  1731. end
  1732.  
  1733. function list:__index(key)
  1734.     if type(key) ~= 'number' then
  1735.         return rawget(self, key) or list[key]
  1736.     end
  1737.    
  1738.     return self:Index(key)
  1739. end
  1740.  
  1741. function list:__newindex(key, value)
  1742.     error('List: cannot direct assign values', 2)
  1743. end
  1744.  
  1745. function list:__tostring()
  1746.     return 'List ['..self.__name..']'
  1747. end
  1748.  
  1749. function list:Index(key)
  1750.   key = key > 0 and key or self:Len() + (key + 1)
  1751.    
  1752.     local cache = self.__cache[key]
  1753.     if cache then return cache end
  1754.    
  1755.     local value = self.__conn:trequest{'LINDEX', self.__name, key}
  1756.     -- cache
  1757.    
  1758.     if value ~= -1 then
  1759.         self.__cache[key] = value
  1760.     end
  1761.     return self.__cache[key]
  1762. end
  1763.  
  1764. function list:Push(...)
  1765.     local req = {}
  1766.     req[1] = 'LPUSH'
  1767.     req[2] = self.__name
  1768.     req[3] = self.__conn:format{...}
  1769.    
  1770.     local res = self.__conn:trequest(req)
  1771.     if res then
  1772.         self.__cache[res] = value
  1773.     end
  1774.     return res
  1775. end
  1776.  
  1777. function list:Lpush(...)
  1778.     local req = {}
  1779.     req[1] = 'LPUSH'
  1780.     req[2] = self.__name
  1781.     req[3] = self.__conn:format{...}
  1782.    
  1783.     local res = self.__conn:trequest(req)
  1784.     if res then
  1785.         self.__cache[res] = value
  1786.     end
  1787.     return res
  1788. end
  1789.  
  1790. function list:Len()
  1791.     return self.__conn:request('LLEN '..self.__name)
  1792. end
  1793.  
  1794. function list:GetAll()
  1795.     if self.__updated then return self.__cache end
  1796.    
  1797.     self.__updated = true
  1798.     return self:Range()
  1799. end
  1800.  
  1801. function list:Inspect(fmt)
  1802.     fmt = fmt or 0
  1803.     self:GetAll()
  1804.    
  1805.     local res = {}
  1806.     res[1] = ('%s (%s) {'):format(self.__name, self.__conn:type(self.__name))
  1807.  
  1808.     local template = '%'..fmt..'d: [%s]'
  1809.     for i, v in ipairs(self.__cache) do
  1810.         res[#res + 1] = template:format(i, v)
  1811.     end
  1812.    
  1813.     res[#res + 1] = '}'
  1814.     return concat(res, '\n')
  1815. end
  1816.  
  1817. function list:Range(min, max)
  1818.     -- lua key-index normalisation (starts from 1)
  1819.     min = min or 1
  1820.     max = max or -1
  1821.    
  1822.     min = min > 0 and min - 1 or min
  1823.     max = max > 0 and max - 1 or max
  1824.    
  1825.    
  1826.     local req = {}
  1827.     req[1] = 'LRANGE'
  1828.     req[2] = self.__name
  1829.     req[3] = min
  1830.     req[4] = max
  1831.    
  1832.     local result = self.__conn:trequest(req)
  1833.     for i, v in ipairs(result) do
  1834.         i = i + min
  1835.         self.__cache[i] = v
  1836.     end
  1837.     return result
  1838. end
  1839.  
  1840. function list:Ipairs()
  1841.     self:GetAll()
  1842.     local i = 0
  1843.     return function()
  1844.         i = i + 1
  1845.         if self[i] then
  1846.             return i, self[i]
  1847.         end
  1848.     end
  1849. end
  1850.  
  1851.  
  1852. local set   = setmetatable({}, structure)
  1853. set.__type  = 'set'
  1854. set.__index = set
  1855.  
  1856. function set:new(name, connection)
  1857.     local o     = structure:new(name, connection)
  1858.     o.__updated = false
  1859.     o.__cache   = {}
  1860.    
  1861.     return setmetatable(o, self)
  1862. end
  1863.  
  1864. function set:__index(key)
  1865.     key = key and tostring(key) or nil
  1866.    
  1867.     local v = rawget(self, key) or set[key]
  1868.     if v then return v end
  1869.     if self.__cache[key] then return true end
  1870.    
  1871.     return self:IsMember(key)
  1872. end
  1873.  
  1874. function set:__newindex(key, value)
  1875.     key = key and tostring(key) or nil
  1876.    
  1877.     return value and self:Add(key) or self:Rem(key)
  1878. end
  1879.  
  1880. function set:__tostring()
  1881.     return 'Set ['..self.__name..']'
  1882. end
  1883.  
  1884. function set:Add(...)
  1885.     if not ... then return end
  1886.     local req = {}
  1887.     req[1] = 'sadd'
  1888.     req[2] = self.__name
  1889.    
  1890.     for i, value in ipairs{...} do
  1891.         if not self.__cache[value] then
  1892.             req[#req + 1] = self.__conn:format(value)
  1893.         end
  1894.         self.__cache[value] = true
  1895.     end
  1896.    
  1897.     return self.__conn:trequest(req)
  1898. end
  1899.  
  1900. function set:Rem(...)
  1901.     if not ... then return end
  1902.     local req = {}
  1903.     req[1] = 'SREM'
  1904.     req[2] = self.__name
  1905.    
  1906.     for i, value in ipairs{...} do
  1907.         if self.__cache[value] then
  1908.             req[#req + 1] = self.__conn:format(value)
  1909.         end
  1910.         self.__cache[value] = nil
  1911.     end
  1912.    
  1913.     return self.__conn:trequest(req)
  1914. end
  1915.  
  1916. function set:Diff(...)
  1917.     if not ... then return end
  1918.     local req = {}
  1919.     req[1] = 'SDIFF'
  1920.     req[2] = self.__name
  1921.    
  1922.     for i, value in ipairs{...} do
  1923.         if type(value) == 'table' then
  1924.             value = value.__name
  1925.         end
  1926.         req[#req + 1] = value
  1927.     end
  1928.    
  1929.     return self.__conn:trequest(req)
  1930. end
  1931.  
  1932. function set:DiffStore(...)
  1933.     if not ... then return end
  1934.     local req = {}
  1935.     req[1] = 'SDIFFSTORE'
  1936.     req[2] = self.__name
  1937.    
  1938.     for i, value in ipairs{...} do
  1939.         if type(value) == 'table' then
  1940.             value = value.__name
  1941.         end
  1942.         req[#req + 1] = value
  1943.     end
  1944.        
  1945.     local res = self.__conn:trequest(req)
  1946.     self:Members()
  1947.    
  1948.     return res
  1949. end
  1950.  
  1951. function set:Inter(...)
  1952.     if not ... then return end
  1953.     local req = {}
  1954.     req[1] = 'SINTER'
  1955.     req[2] = self.__name
  1956.    
  1957.     for i, value in ipairs{...} do
  1958.         if type(value) == 'table' and value.__type == 'list' then
  1959.             value = value.__name
  1960.         end
  1961.         req[#req + 1] = value
  1962.     end
  1963.    
  1964.     return self.__conn:trequest(req)
  1965. end
  1966.  
  1967. function set:InterStore(...)
  1968.     if not ... then return end
  1969.     local req = {}
  1970.     req[1] = 'SINTERSTORE'
  1971.     req[2] = self.__name
  1972.    
  1973.     for i, value in ipairs{...} do
  1974.         if type(value) == 'table' and value.__type == 'list' then
  1975.             value = value.__name
  1976.         end
  1977.         req[#req + 1] = value
  1978.     end
  1979.        
  1980.     local res = self.__conn:trequest(req)
  1981.     self:Members()
  1982.     return res
  1983. end
  1984.  
  1985. function set:Union(...)
  1986.     if not ... then return end
  1987.     local req = {}
  1988.     req[1] = 'SUNIONS'
  1989.     req[2] = self.__name
  1990.    
  1991.     for i, value in ipairs{...} do
  1992.         if type(value) == 'table' then
  1993.             value = value.__name
  1994.         end
  1995.         req[#req + 1] = value
  1996.     end
  1997.    
  1998.     return self.__conn:trequest(req)
  1999. end
  2000.  
  2001. function set:UnionStore(...)
  2002.     if not ... then return end
  2003.     local req = {}
  2004.     req[1] = 'SUNIONSTORE'
  2005.     req[2] = self.__name
  2006.    
  2007.     for i, value in ipairs{...} do
  2008.         if type(value) == 'table' and value.__type == 'list' then
  2009.             value = value.__name
  2010.         end
  2011.         req[#req + 1] = value
  2012.     end
  2013.        
  2014.     local res = self.__conn:trequest(req)
  2015.     self:Members()
  2016.     return res
  2017. end
  2018.  
  2019. function set:IsMember(value)
  2020.     if self.__cache[value] then
  2021.         return 1
  2022.     end
  2023.  
  2024.     local res = self.__conn:trequest{'SISMEMBER', self.__name, self:format(value)}
  2025.     self.__cache[value] = res == 1 or nil
  2026.    
  2027.     return res
  2028. end
  2029.  
  2030. function set:Members()
  2031.     local res = self.__conn:trequest{'SMEMBER', self.__name}
  2032.    
  2033.     self.__cache = {}
  2034.    
  2035.     for i, value in ipairs(res or {}) do
  2036.         self.__cache[value] = true
  2037.     end
  2038.    
  2039.     return res
  2040. end
  2041.  
  2042. function set:Move(destination, value)
  2043.     local dstable = type(destination) == 'table'
  2044.     if dstable then
  2045.         destination = destination.__name
  2046.     end
  2047.    
  2048.     local res = self.__conn:trequest{'SMOVE', self.__name}
  2049.     if res == 1 then
  2050.         self.__cache[value] = nil
  2051.         if dstable then
  2052.             dstable.__cache[value] = true
  2053.         end
  2054.     end
  2055.    
  2056.     return res
  2057. end
  2058.  
  2059. function set:RandMember(count)
  2060.     return self.__conn:trequest{'SRANDMEMBER', self.__name, count}
  2061. end
  2062.  
  2063. function set:GetAll()
  2064.     if self.__updated then return self.__cache end
  2065.    
  2066.     self.__updated = true
  2067.     return self:Members()
  2068. end
  2069.  
  2070. function set:Len()
  2071.     return self.__conn:trequest{'SCARD', self.__name}
  2072. end
  2073.  
  2074. set.Card = set.Len
  2075.  
  2076. function set:Pop(n)
  2077.     local res = self.__conn:trequest{'SPOP', self.__name, n or 1}
  2078.    
  2079.     if type(res) == 'string' then
  2080.         self.__cache[res] = nil
  2081.         return res
  2082.     end
  2083.    
  2084.     for i, value in ipairs(res) do
  2085.         self.__cache[value] = nil
  2086.     end
  2087.    
  2088.     return res
  2089. end
  2090.  
  2091. function set:Inspect(fmt)
  2092.     fmt = fmt or 0
  2093.    
  2094.     local res = {}
  2095.     res[1] = ('%s (%s) {'):format(self.__name, self.__conn:type(self.__name))
  2096.  
  2097.     local template = '  %'..fmt..'s'
  2098.     for k, v in pairs(self.__cache) do
  2099.         res[#res + 1] = template:format(k)
  2100.     end
  2101.    
  2102.     res[#res + 1] = '}'
  2103.     return concat(res, '\n')
  2104. end
  2105.  
  2106. local subscriber   = {}
  2107. subscriber.__type  = 'subscriber'
  2108. subscriber.__index = subscriber
  2109.  
  2110. function subscriber:new(connect, ...)
  2111.     self = setmetatable({}, self)
  2112.     self.__subs  = {}
  2113.     self.__psubs = {}
  2114.     self.__conn  = connection:new(connect.ip, connect.port, connection.pass)
  2115.     self.__conn:connect()
  2116.     if ... then
  2117.         self:subscribe(...)
  2118.         for i = 1, select('#', ...) - 1 do
  2119.             self.__conn:receive(true)
  2120.         end
  2121.     end
  2122.     self.__conn:settimeout(0) -- set to zero
  2123.     return self
  2124. end
  2125.  
  2126. local function key_conc(t, sep)
  2127.     local res = {}
  2128.     for k, v in pairs(t) do res[#res + 1] = tostring(k) end
  2129.     return table.concat(res, sep or ' ')
  2130. end
  2131.  
  2132. function subscriber:__tostring()
  2133.     return 'Subscriber: subs: {'..key_conc(self.__subs)..'}, psubs: {'..key_conc(self.__psubs)..'}'
  2134. end
  2135.  
  2136. -- user redefined
  2137. function subscriber:onMessage(channel, message)
  2138.     -- print('Published message:', channel, message)
  2139. end
  2140.  
  2141. -- receive new messages, call onMessage callback
  2142. function subscriber:update()
  2143.     local data = self.__conn:receive(true)
  2144.     while data do
  2145.         self:onMessage(data[2], data[3])
  2146.         data = self.__conn:receive(true)
  2147.     end
  2148. end
  2149.  
  2150. -- SUBSCRIBE channel [channel ...]
  2151. -- Listen for messages published to the given channels
  2152. function subscriber:subscribe(...)
  2153.     for i, v in ipairs{...} do self.__subs[v] = true end
  2154.     return self.__conn:trequest{'SUBSCRIBE', ...}
  2155. end
  2156.  
  2157. -- UNSUBSCRIBE [channel [channel ...]]
  2158. -- Stop listening for messages posted to the given channels
  2159. function subscriber:unsubscribe(...)
  2160.     for i, v in ipairs{...} do self.__subs[v] = nil end
  2161.     return self.__conn:trequest{'UNSUBSCRIBE', ...}
  2162. end
  2163.  
  2164. -- PSUBSCRIBE pattern [pattern ...]
  2165. -- Listen for messages published to channels matching the given patterns
  2166. function subscriber:psubscribe(...)
  2167.     for i, v in ipairs{...} do self.__psubs[v] = true end
  2168.    
  2169.     return self.__conn:trequest{'PSUBSCRIBE', ...}
  2170. end
  2171.  
  2172. -- PUNSUBSCRIBE [pattern [pattern ...]]
  2173. -- Stop listening for messages posted to channels matching the given patterns
  2174. function subscriber:punsubscribe(...)
  2175.     for i, v in ipairs{...} do self.__psubs[v] = nil end
  2176.  
  2177.     return self.__conn:trequest{'PUNSUBSCRIBE', ...}
  2178. end
  2179.  
  2180. -- close connection
  2181. function subscriber:close()
  2182.     local subs, psubs = {}, {}
  2183.     for sub in pairs(self.__subs)  do  subs[#subs + 1]  = sub end
  2184.     for pub in pairs(self.__psubs) do psubs[#psubs + 1] = pub end
  2185.     if #subs  > 0 then  self:unsubscribe(unpack(subs))  end
  2186.     if #psubs > 0 then self:punsubscribe(unpack(psubs)) end
  2187.    
  2188.     return self.__conn:close()
  2189. end
  2190.  
  2191. -- // structure instancing
  2192. function connection:newHash(name)
  2193.     assert(type('name' == 'string'), 'String name of hash expected, got '..type(name))
  2194.     return hash:new(name, self)
  2195. end
  2196.  
  2197. function connection:newList(name)
  2198.     assert(type('name' == 'string'), 'String name of list expected, got '..type(name))
  2199.     return list:new(name, self)
  2200. end
  2201.  
  2202. function connection:newSet(name)
  2203.     assert(type('name' == 'string'), 'String name of set expected, got '..type(name))
  2204.     local set = set:new(name, self)
  2205.     set:GetAll()
  2206.     return set
  2207. end
  2208.  
  2209. function connection:newSubscriber(...)
  2210.     return subscriber:new(self, ...)
  2211. end
  2212.  
  2213. return connection
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement