fixes for scanning generator
This commit is contained in:
0
lib/clients/mycelium/.heroscript
Normal file
0
lib/clients/mycelium/.heroscript
Normal file
0
lib/clients/openai/.heroscript
Normal file
0
lib/clients/openai/.heroscript
Normal file
0
lib/clients/postgres/.heroscript
Normal file
0
lib/clients/postgres/.heroscript
Normal file
@@ -1,58 +0,0 @@
|
||||
module redisclient
|
||||
|
||||
// original code see https://github.com/patrickpissurno/vredis/blob/master/vredis_test.v
|
||||
// credits see there as well (-:
|
||||
import net
|
||||
// import sync
|
||||
// import strconv
|
||||
|
||||
__global (
|
||||
redis_connections []Redis
|
||||
)
|
||||
|
||||
const default_read_timeout = net.infinite_timeout
|
||||
|
||||
@[heap]
|
||||
pub struct Redis {
|
||||
pub:
|
||||
addr string
|
||||
mut:
|
||||
socket net.TcpConn
|
||||
}
|
||||
|
||||
// https://redis.io/topics/protocol
|
||||
// examples:
|
||||
// localhost:6379
|
||||
// /tmp/redis-default.sock
|
||||
pub fn new(addr string) !Redis {
|
||||
// lock redis_connections {
|
||||
for mut conn in redis_connections {
|
||||
if conn.addr == addr {
|
||||
return conn
|
||||
}
|
||||
}
|
||||
// means there is no connection yet
|
||||
mut r := Redis{
|
||||
addr: addr
|
||||
}
|
||||
r.socket_connect()!
|
||||
redis_connections << r
|
||||
return r
|
||||
//}
|
||||
// panic("bug")
|
||||
}
|
||||
|
||||
pub fn reset() ! {
|
||||
// lock redis_connections {
|
||||
for mut conn in redis_connections {
|
||||
conn.disconnect()
|
||||
}
|
||||
redis_connections = []Redis{}
|
||||
//}
|
||||
}
|
||||
|
||||
pub fn checkempty() {
|
||||
// lock redis_connections {
|
||||
assert redis_connections.len == 0
|
||||
//}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
# Redisclient
|
||||
|
||||
## basic example to connect to local redis on 127.0.0.1:6379
|
||||
|
||||
```v
|
||||
|
||||
import freeflowuniverse.herolib.clients.redisclient
|
||||
|
||||
mut redis := redisclient.core_get()!
|
||||
redis.set('test', 'some data') or { panic('set' + err.str() + '\n' + c.str()) }
|
||||
r := redis.get('test')?
|
||||
if r != 'some data' {
|
||||
panic('get error different result.' + '\n' + c.str())
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
> redis commands can be found on https://redis.io/commands/
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
module redisclient
|
||||
|
||||
import freeflowuniverse.herolib.ui.console
|
||||
|
||||
pub struct RedisCache {
|
||||
mut:
|
||||
redis &Redis @[str: skip]
|
||||
namespace string
|
||||
enabled bool = true
|
||||
}
|
||||
|
||||
// return a cache object starting from a redis connection
|
||||
pub fn (mut r Redis) cache(namespace string) RedisCache {
|
||||
return RedisCache{
|
||||
redis: &r
|
||||
namespace: namespace
|
||||
}
|
||||
}
|
||||
|
||||
pub fn (mut h RedisCache) get(key string) ?string {
|
||||
if !h.enabled {
|
||||
return none
|
||||
}
|
||||
key2 := h.namespace + ':' + key
|
||||
hit := h.redis.get('cache:${key2}') or {
|
||||
console.print_debug('[-] cache: cache miss, ${key2}')
|
||||
return none
|
||||
}
|
||||
|
||||
console.print_debug('[+] cache: cache hit: ${key2}')
|
||||
return hit
|
||||
}
|
||||
|
||||
pub fn (mut h RedisCache) set(key string, val string, expire int) ! {
|
||||
if !h.enabled {
|
||||
return
|
||||
}
|
||||
|
||||
key2 := h.namespace + ':' + key
|
||||
h.redis.set_ex('cache:${key2}', val, expire.str())!
|
||||
}
|
||||
|
||||
pub fn (mut h RedisCache) exists(key string) bool {
|
||||
h.get(key) or { return false }
|
||||
return true
|
||||
}
|
||||
|
||||
pub fn (mut h RedisCache) reset() ! {
|
||||
key_check := 'cache:' + h.namespace
|
||||
// console.print_debug(key_check)
|
||||
keys := h.redis.keys(key_check)!
|
||||
// console.print_debug(keys)
|
||||
for key in keys {
|
||||
// console.print_debug(key)
|
||||
h.redis.del(key)!
|
||||
}
|
||||
}
|
||||
@@ -1,305 +0,0 @@
|
||||
module redisclient
|
||||
|
||||
import freeflowuniverse.herolib.data.resp
|
||||
import time
|
||||
|
||||
pub fn (mut r Redis) ping() !string {
|
||||
return r.send_expect_strnil(['PING'])
|
||||
}
|
||||
|
||||
pub fn (mut r Redis) set(key string, value string) ! {
|
||||
return r.send_expect_ok(['SET', key, value])
|
||||
}
|
||||
|
||||
pub fn (mut r Redis) set_ex(key string, value string, ex string) ! {
|
||||
return r.send_expect_ok(['SET', key, value, 'EX', ex])
|
||||
}
|
||||
|
||||
pub fn (mut r Redis) set_opts(key string, value string, opts SetOpts) !bool {
|
||||
ex := if opts.ex == -4 && opts.px == -4 {
|
||||
''
|
||||
} else if opts.ex != -4 {
|
||||
' EX ${opts.ex}'
|
||||
} else {
|
||||
' PX ${opts.px}'
|
||||
}
|
||||
nx := if opts.nx == false && opts.xx == false {
|
||||
''
|
||||
} else if opts.nx == true {
|
||||
' NX'
|
||||
} else {
|
||||
' XX'
|
||||
}
|
||||
keep_ttl := if opts.keep_ttl == false { '' } else { ' KEEPTTL' }
|
||||
message := 'SET "${key}" "${value}"${ex}${nx}${keep_ttl}\r\n'
|
||||
r.write(message.bytes()) or { return false }
|
||||
time.sleep(1 * time.millisecond)
|
||||
res := r.read_line()!
|
||||
match res {
|
||||
'+OK\r\n' {
|
||||
return true
|
||||
}
|
||||
else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn (mut r Redis) get(key string) !string {
|
||||
// mut key2 := key.trim("\"'")
|
||||
return r.send_expect_strnil(['GET', key])
|
||||
}
|
||||
|
||||
pub fn (mut r Redis) exists(key string) !bool {
|
||||
r2 := r.send_expect_int(['EXISTS', key])!
|
||||
return r2 == 1
|
||||
}
|
||||
|
||||
pub fn (mut r Redis) del(key string) !int {
|
||||
return r.send_expect_int(['DEL', key])
|
||||
}
|
||||
|
||||
pub fn (mut r Redis) hset(key string, skey string, value string) ! {
|
||||
r.send_expect_int(['HSET', key, skey, value])!
|
||||
}
|
||||
|
||||
pub fn (mut r Redis) hget(key string, skey string) !string {
|
||||
// mut key2 := key.trim("\"'")
|
||||
return r.send_expect_strnil(['HGET', key, skey])
|
||||
}
|
||||
|
||||
pub fn (mut r Redis) hgetall(key string) !map[string]string {
|
||||
// mut key2 := key.trim("\"'")
|
||||
res := r.send_expect_list_str(['HGETALL', key])!
|
||||
mut mapped := map[string]string{}
|
||||
mut i := 0
|
||||
for i < res.len && i + 1 < res.len {
|
||||
mapped[res[i]] = res[i + 1]
|
||||
i += 2
|
||||
}
|
||||
return mapped
|
||||
}
|
||||
|
||||
pub fn (mut r Redis) hexists(key string, skey string) !bool {
|
||||
return r.send_expect_bool(['HEXISTS', key, skey])
|
||||
}
|
||||
|
||||
pub fn (mut r Redis) hdel(key string, skey string) !int {
|
||||
return r.send_expect_int(['HDEL', key, skey])
|
||||
}
|
||||
|
||||
pub fn (mut r Redis) incrby(key string, increment int) !int {
|
||||
return r.send_expect_int(['INCRBY', key, increment.str()])
|
||||
}
|
||||
|
||||
pub fn (mut r Redis) incr(key string) !int {
|
||||
return r.incrby(key, 1)
|
||||
}
|
||||
|
||||
pub fn (mut r Redis) decr(key string) !int {
|
||||
return r.incrby(key, -1)
|
||||
}
|
||||
|
||||
pub fn (mut r Redis) decrby(key string, decrement int) !int {
|
||||
return r.incrby(key, -decrement)
|
||||
}
|
||||
|
||||
pub fn (mut r Redis) incrbyfloat(key string, increment f64) !f64 {
|
||||
res := r.send_expect_str(['INCRBYFLOAT', key, increment.str()])!
|
||||
count := res.f64()
|
||||
return count
|
||||
}
|
||||
|
||||
pub fn (mut r Redis) append(key string, value string) !int {
|
||||
return r.send_expect_int(['APPEND', key, value])
|
||||
}
|
||||
|
||||
pub fn (mut r Redis) setrange(key string, offset int, value string) !int {
|
||||
return r.send_expect_int(['SETRANGE', key, offset.str(), value.str()])
|
||||
}
|
||||
|
||||
pub fn (mut r Redis) lpush(key string, element string) !int {
|
||||
return r.send_expect_int(['LPUSH', key, element])
|
||||
}
|
||||
|
||||
pub fn (mut r Redis) rpush(key string, element string) !int {
|
||||
return r.send_expect_int(['RPUSH', key, element])
|
||||
}
|
||||
|
||||
pub fn (mut r Redis) lrange(key string, start int, end int) ![]resp.RValue {
|
||||
return r.send_expect_list(['LRANGE', key, start.str(), end.str()])
|
||||
}
|
||||
|
||||
pub fn (mut r Redis) expire(key string, seconds int) !int {
|
||||
return r.send_expect_int(['EXPIRE', key, seconds.str()])
|
||||
}
|
||||
|
||||
pub fn (mut r Redis) pexpire(key string, millis int) !int {
|
||||
return r.send_expect_int(['PEXPIRE', key, millis.str()])
|
||||
}
|
||||
|
||||
pub fn (mut r Redis) expireat(key string, timestamp int) !int {
|
||||
return r.send_expect_int(['EXPIREAT', key, timestamp.str()])
|
||||
}
|
||||
|
||||
pub fn (mut r Redis) pexpireat(key string, millistimestamp i64) !int {
|
||||
return r.send_expect_int(['PEXPIREAT', key, millistimestamp.str()])
|
||||
}
|
||||
|
||||
pub fn (mut r Redis) persist(key string) !int {
|
||||
return r.send_expect_int(['PERSIST', key])
|
||||
}
|
||||
|
||||
pub fn (mut r Redis) getset(key string, value string) !string {
|
||||
return r.send_expect_strnil(['GETSET', key, value])
|
||||
}
|
||||
|
||||
pub fn (mut r Redis) getrange(key string, start int, end int) !string {
|
||||
return r.send_expect_str(['GETRANGE', key, start.str(), end.str()])
|
||||
}
|
||||
|
||||
pub fn (mut r Redis) keys(pattern string) ![]string {
|
||||
response := r.send_expect_list(['KEYS', pattern])!
|
||||
mut result := []string{}
|
||||
for item in response {
|
||||
result << resp.get_redis_value(item)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
pub fn (mut r Redis) hkeys(key string) ![]string {
|
||||
response := r.send_expect_list(['HKEYS', key])!
|
||||
mut result := []string{}
|
||||
for item in response {
|
||||
result << resp.get_redis_value(item)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
pub fn (mut r Redis) randomkey() !string {
|
||||
return r.send_expect_strnil(['RANDOMKEY'])
|
||||
}
|
||||
|
||||
pub fn (mut r Redis) strlen(key string) !int {
|
||||
return r.send_expect_int(['STRLEN', key])
|
||||
}
|
||||
|
||||
pub fn (mut r Redis) lpop(key string) !string {
|
||||
return r.send_expect_strnil(['LPOP', key])
|
||||
}
|
||||
|
||||
pub fn (mut r Redis) blpop(keys []string, timeout f64) ![]string {
|
||||
mut request := ['BLPOP']
|
||||
request << keys
|
||||
request << '${timeout}'
|
||||
res := r.send_expect_list_str(request)!
|
||||
if res.len != 2 || res[1] == '' {
|
||||
return error('timeout on blpop')
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
pub fn (mut r Redis) brpop(keys []string, timeout f64) ![]string {
|
||||
mut request := ['BRPOP']
|
||||
request << keys
|
||||
request << '${timeout}'
|
||||
res := r.send_expect_list_str(request)!
|
||||
if res.len != 2 {
|
||||
return error('timeout on brpop')
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
pub fn (mut r Redis) rpop(key string) !string {
|
||||
return r.send_expect_strnil(['RPOP', key])
|
||||
}
|
||||
|
||||
pub fn (mut r Redis) llen(key string) !int {
|
||||
return r.send_expect_int(['LLEN', key])
|
||||
}
|
||||
|
||||
pub fn (mut r Redis) ttl(key string) !int {
|
||||
return r.send_expect_int(['TTL', key])
|
||||
}
|
||||
|
||||
pub fn (mut r Redis) pttl(key string) !int {
|
||||
return r.send_expect_int(['PTTL', key])
|
||||
}
|
||||
|
||||
pub fn (mut r Redis) rename(key string, newkey string) ! {
|
||||
return r.send_expect_ok(['RENAME', key, newkey])
|
||||
}
|
||||
|
||||
pub fn (mut r Redis) renamenx(key string, newkey string) !int {
|
||||
return r.send_expect_int(['RENAMENX', key, newkey])
|
||||
}
|
||||
|
||||
pub fn (mut r Redis) setex(key string, second i64, value string) ! {
|
||||
return r.send_expect_ok(['SETEX', key, second.str(), value])
|
||||
}
|
||||
|
||||
pub fn (mut r Redis) psetex(key string, millisecond i64, value string) ! {
|
||||
return r.send_expect_ok(['PSETEX', key, millisecond.str(), value])
|
||||
}
|
||||
|
||||
pub fn (mut r Redis) setnx(key string, value string) !int {
|
||||
return r.send_expect_int(['SETNX', key, value])
|
||||
}
|
||||
|
||||
pub fn (mut r Redis) type_of(key string) !string {
|
||||
return r.send_expect_strnil(['TYPE', key])
|
||||
}
|
||||
|
||||
pub fn (mut r Redis) flushall() ! {
|
||||
return r.send_expect_ok(['FLUSHALL'])
|
||||
}
|
||||
|
||||
pub fn (mut r Redis) flushdb() ! {
|
||||
return r.send_expect_ok(['FLUSHDB'])
|
||||
}
|
||||
|
||||
// select is reserved
|
||||
pub fn (mut r Redis) selectdb(database int) ! {
|
||||
return r.send_expect_ok(['SELECT', database.str()])
|
||||
}
|
||||
|
||||
pub fn (mut r Redis) scan(cursor int) !(string, []string) {
|
||||
res := r.send_expect_list(['SCAN', cursor.str()])!
|
||||
if res[0] !is resp.RBString {
|
||||
return error('Redis SCAN wrong response type (cursor)')
|
||||
}
|
||||
|
||||
if res[1] !is resp.RArray {
|
||||
return error('Redis SCAN wrong response type (list content)')
|
||||
}
|
||||
|
||||
mut values := []string{}
|
||||
|
||||
for i in 0 .. resp.get_redis_array_len(res[1]) {
|
||||
values << resp.get_redis_value_by_index(res[1], i)
|
||||
}
|
||||
|
||||
return resp.get_redis_value(res[0]), values
|
||||
}
|
||||
|
||||
// Add the specified members to the set stored at key. Specified members that are already a member
|
||||
// of this set are ignored. If key does not exist, a new set is created before adding the specified members.
|
||||
// An error is returned when the value stored at key is not a set.
|
||||
pub fn (mut r Redis) sadd(key string, members []string) !int {
|
||||
mut tosend := ['SADD', key]
|
||||
for k in members {
|
||||
tosend << k
|
||||
}
|
||||
return r.send_expect_int(tosend)
|
||||
}
|
||||
|
||||
// Returns if member is a member of the set stored at key.
|
||||
pub fn (mut r Redis) smismember(key string, members []string) ![]int {
|
||||
// mut key2 := key.trim("\"'")
|
||||
mut tosend := ['SMISMEMBER', key]
|
||||
for k in members {
|
||||
tosend << k
|
||||
}
|
||||
res := r.send_expect_list_int(tosend)!
|
||||
return res
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
module redisclient
|
||||
|
||||
@[params]
|
||||
pub struct RedisURL {
|
||||
address string = '127.0.0.1'
|
||||
port int = 6379
|
||||
// db int
|
||||
}
|
||||
|
||||
pub fn get_redis_url(url string) !RedisURL {
|
||||
if !url.contains(':') {
|
||||
return error('url doesnt contain port')
|
||||
} else {
|
||||
return RedisURL{
|
||||
address: url.all_before_last(':')
|
||||
port: url.all_after_last(':').u16()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn core_get(url RedisURL) !Redis {
|
||||
mut r := new('${url.address}:${url.port}')!
|
||||
return r
|
||||
}
|
||||
@@ -1,173 +0,0 @@
|
||||
module redisclient
|
||||
|
||||
import freeflowuniverse.herolib.data.resp
|
||||
|
||||
pub fn (mut r Redis) get_response() !resp.RValue {
|
||||
line := r.read_line()!
|
||||
|
||||
if line.starts_with('-') {
|
||||
return resp.RError{
|
||||
value: line[1..]
|
||||
}
|
||||
}
|
||||
if line.starts_with(':') {
|
||||
return resp.RInt{
|
||||
value: line[1..].int()
|
||||
}
|
||||
}
|
||||
if line.starts_with('+') {
|
||||
return resp.RString{
|
||||
value: line[1..]
|
||||
}
|
||||
}
|
||||
if line.starts_with('$') {
|
||||
mut bulkstring_size := line[1..].int()
|
||||
if bulkstring_size == -1 {
|
||||
return resp.RNil{}
|
||||
}
|
||||
if bulkstring_size == 0 {
|
||||
// extract final \r\n and not reading
|
||||
// any payload
|
||||
r.read_line()!
|
||||
return resp.RString{
|
||||
value: ''
|
||||
}
|
||||
}
|
||||
// read payload
|
||||
buffer := r.read(bulkstring_size) or { panic(err) }
|
||||
// extract final \r\n
|
||||
r.read_line()!
|
||||
// console.print_debug("readline result:'$buffer.bytestr()'")
|
||||
return resp.RBString{
|
||||
value: buffer
|
||||
} // TODO: won't support binary (afaik), need to fix? WHY not (despiegk)?
|
||||
}
|
||||
|
||||
if line.starts_with('*') {
|
||||
mut arr := resp.RArray{
|
||||
values: []resp.RValue{}
|
||||
}
|
||||
items := line[1..].int()
|
||||
|
||||
// proceed each entries, they can be of any types
|
||||
for _ in 0 .. items {
|
||||
value := r.get_response()!
|
||||
arr.values << value
|
||||
}
|
||||
|
||||
return arr
|
||||
}
|
||||
|
||||
return error('unsupported response type')
|
||||
}
|
||||
|
||||
// TODO: needs to use the resp library
|
||||
|
||||
pub fn (mut r Redis) get_int() !int {
|
||||
line := r.read_line()!
|
||||
if line.starts_with(':') {
|
||||
return line[1..].int()
|
||||
} else {
|
||||
return error("Did not find int, did find:'${line}'")
|
||||
}
|
||||
}
|
||||
|
||||
pub fn (mut r Redis) get_list_int() ![]int {
|
||||
line := r.read_line()!
|
||||
mut res := []int{}
|
||||
|
||||
if line.starts_with('*') {
|
||||
items := line[1..].int()
|
||||
// proceed each entries, they can be of any types
|
||||
for _ in 0 .. items {
|
||||
value := r.get_int()!
|
||||
res << value
|
||||
}
|
||||
return res
|
||||
} else {
|
||||
return error("Did not find int, did find:'${line}'")
|
||||
}
|
||||
}
|
||||
|
||||
pub fn (mut r Redis) get_list_str() ![]string {
|
||||
line := r.read_line()!
|
||||
mut res := []string{}
|
||||
|
||||
if line.starts_with('*') {
|
||||
items := line[1..].int()
|
||||
// proceed each entries, they can be of any types
|
||||
for _ in 0 .. items {
|
||||
value := r.get_string()!
|
||||
res << value
|
||||
}
|
||||
return res
|
||||
} else {
|
||||
return error("Did not find int, did find:'${line}'")
|
||||
}
|
||||
}
|
||||
|
||||
pub fn (mut r Redis) get_string() !string {
|
||||
line := r.read_line()!
|
||||
if line.starts_with('+') {
|
||||
// console.print_debug("getstring:'${line[1..]}'")
|
||||
return line[1..]
|
||||
}
|
||||
if line.starts_with('$') {
|
||||
r2 := r.get_bytes_from_line(line)!
|
||||
return r2.bytestr()
|
||||
} else {
|
||||
return error("Did not find string, did find:'${line}'")
|
||||
}
|
||||
}
|
||||
|
||||
pub fn (mut r Redis) get_string_nil() !string {
|
||||
r2 := r.get_bytes_nil()!
|
||||
return r2.bytestr()
|
||||
}
|
||||
|
||||
pub fn (mut r Redis) get_bytes_nil() ![]u8 {
|
||||
line := r.read_line()!
|
||||
if line.starts_with('+') {
|
||||
return line[1..].bytes()
|
||||
}
|
||||
if line.starts_with('$-1') {
|
||||
return []u8{}
|
||||
}
|
||||
if line.starts_with('$') {
|
||||
return r.get_bytes_from_line(line)
|
||||
} else {
|
||||
return error("Did not find string or nil, did find:'${line}'")
|
||||
}
|
||||
}
|
||||
|
||||
pub fn (mut r Redis) get_bool() !bool {
|
||||
i := r.get_int()!
|
||||
return i == 1
|
||||
}
|
||||
|
||||
pub fn (mut r Redis) get_bytes() ![]u8 {
|
||||
line := r.read_line()!
|
||||
if line.starts_with('$') {
|
||||
return r.get_bytes_from_line(line)
|
||||
} else {
|
||||
return error("Did not find bulkstring, did find:'${line}'")
|
||||
}
|
||||
}
|
||||
|
||||
fn (mut r Redis) get_bytes_from_line(line string) ![]u8 {
|
||||
mut bulkstring_size := line[1..].int()
|
||||
if bulkstring_size == -1 {
|
||||
// return none
|
||||
return error('bulkstring_size is -1')
|
||||
}
|
||||
if bulkstring_size == 0 {
|
||||
// extract final \r\n, there is no payload
|
||||
r.read_line()!
|
||||
return []
|
||||
}
|
||||
// read payload
|
||||
buffer := r.read(bulkstring_size) or { panic('Could not read payload: ${err}') }
|
||||
// extract final \r\n
|
||||
r.read_line()!
|
||||
return buffer
|
||||
}
|
||||
@@ -1,121 +0,0 @@
|
||||
module redisclient
|
||||
|
||||
import os
|
||||
import net
|
||||
import freeflowuniverse.herolib.data.resp
|
||||
import time
|
||||
import net.unix
|
||||
|
||||
pub struct SetOpts {
|
||||
ex int = -4
|
||||
px int = -4
|
||||
nx bool
|
||||
xx bool
|
||||
keep_ttl bool
|
||||
}
|
||||
|
||||
pub enum KeyType {
|
||||
t_none
|
||||
t_string
|
||||
t_list
|
||||
t_set
|
||||
t_zset
|
||||
t_hash
|
||||
t_stream
|
||||
t_unknown
|
||||
}
|
||||
|
||||
fn (mut r Redis) socket_connect() ! {
|
||||
// print_backtrace()
|
||||
addr := os.expand_tilde_to_home(r.addr)
|
||||
// console.print_debug(' - REDIS CONNECT: ${addr}')
|
||||
if !addr.contains(':') {
|
||||
unix_socket := unix.connect_stream(addr)!
|
||||
tcp_socket := net.tcp_socket_from_handle_raw(unix_socket.sock.Socket.handle)
|
||||
tcp_conn := net.TcpConn{
|
||||
sock: tcp_socket
|
||||
handle: unix_socket.sock.Socket.handle
|
||||
}
|
||||
r.socket = tcp_conn
|
||||
} else {
|
||||
r.socket = net.dial_tcp(addr)!
|
||||
}
|
||||
|
||||
r.socket.set_blocking(true)!
|
||||
r.socket.set_read_timeout(1 * time.second)
|
||||
// console.print_debug("---OK")
|
||||
}
|
||||
|
||||
fn (mut r Redis) socket_check() ! {
|
||||
r.socket.peer_addr() or {
|
||||
// console.print_debug(' - re-connect socket for redis')
|
||||
r.socket_connect()!
|
||||
}
|
||||
}
|
||||
|
||||
pub fn (mut r Redis) read_line() !string {
|
||||
return r.socket.read_line().trim_right('\r\n')
|
||||
}
|
||||
|
||||
// write *all the data* into the socket
|
||||
// This function loops, till *everything is written*
|
||||
// (some of the socket write ops could be partial)
|
||||
fn (mut r Redis) write(data []u8) ! {
|
||||
r.socket_check()!
|
||||
mut remaining := data.len
|
||||
for remaining > 0 {
|
||||
// zdbdata[data.len - remaining..].bytestr())
|
||||
written_bytes := r.socket.write(data[data.len - remaining..])!
|
||||
remaining -= written_bytes
|
||||
}
|
||||
}
|
||||
|
||||
fn (mut r Redis) read(size int) ![]u8 {
|
||||
r.socket_check() or {}
|
||||
mut buf := []u8{len: size}
|
||||
mut remaining := size
|
||||
for remaining > 0 {
|
||||
read_bytes := r.socket.read(mut buf[buf.len - remaining..])!
|
||||
remaining -= read_bytes
|
||||
}
|
||||
return buf
|
||||
}
|
||||
|
||||
pub fn (mut r Redis) disconnect() {
|
||||
r.socket.close() or {}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// TODO: need to implement a way how to use multiple connections at once
|
||||
|
||||
const cr_lf_bytes = [u8(`\r`), `\n`]
|
||||
|
||||
fn (mut r Redis) write_line(data []u8) ! {
|
||||
r.write(data)!
|
||||
r.write(cr_lf_bytes)!
|
||||
}
|
||||
|
||||
// write resp value to the redis channel
|
||||
pub fn (mut r Redis) write_rval(val resp.RValue) ! {
|
||||
r.write(val.encode())!
|
||||
}
|
||||
|
||||
// write list of strings to redis challen
|
||||
fn (mut r Redis) write_cmd(item string) ! {
|
||||
a := resp.r_bytestring(item.bytes())
|
||||
r.write_rval(a)!
|
||||
}
|
||||
|
||||
// write list of strings to redis challen
|
||||
fn (mut r Redis) write_cmds(items []string) ! {
|
||||
// if items.len==1{
|
||||
// a := resp.r_bytestring(items[0].bytes())
|
||||
// r.write_rval(a)!
|
||||
// }{
|
||||
a := resp.r_list_bstring(items)
|
||||
r.write_rval(a)!
|
||||
// }
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
module redisclient
|
||||
|
||||
import time
|
||||
|
||||
pub struct RedisQueue {
|
||||
pub mut:
|
||||
key string
|
||||
redis &Redis
|
||||
}
|
||||
|
||||
pub fn (mut r Redis) queue_get(key string) RedisQueue {
|
||||
return RedisQueue{
|
||||
key: key
|
||||
redis: r
|
||||
}
|
||||
}
|
||||
|
||||
pub fn (mut q RedisQueue) add(val string) ! {
|
||||
q.redis.lpush(q.key, val)!
|
||||
}
|
||||
|
||||
// timeout in msec
|
||||
pub fn (mut q RedisQueue) get(timeout u64) !string {
|
||||
start := u64(time.now().unix_milli())
|
||||
for {
|
||||
r := q.redis.rpop(q.key) or { '' }
|
||||
if r != '' {
|
||||
return r
|
||||
}
|
||||
if u64(time.now().unix_milli()) > (start + timeout) {
|
||||
break
|
||||
}
|
||||
time.sleep(time.microsecond)
|
||||
}
|
||||
return error('timeout on ${q.key}')
|
||||
}
|
||||
|
||||
// get without timeout, returns none if nil
|
||||
pub fn (mut q RedisQueue) pop() !string {
|
||||
return q.redis.rpop(q.key)!
|
||||
}
|
||||
@@ -1,136 +0,0 @@
|
||||
module redisclient
|
||||
|
||||
import rand
|
||||
import time
|
||||
import json
|
||||
|
||||
pub struct RedisRpc {
|
||||
pub mut:
|
||||
key string // queue name as used by this rpc
|
||||
redis &Redis
|
||||
}
|
||||
|
||||
// return a rpc mechanism
|
||||
pub fn (mut r Redis) rpc_get(key string) RedisRpc {
|
||||
return RedisRpc{
|
||||
key: key
|
||||
redis: r
|
||||
}
|
||||
}
|
||||
|
||||
pub struct RPCArgs {
|
||||
pub:
|
||||
cmd string @[required]
|
||||
data string @[required]
|
||||
timeout u64 = 60000 // 60 sec
|
||||
wait bool = true
|
||||
}
|
||||
|
||||
pub struct Message {
|
||||
pub:
|
||||
ret_queue string
|
||||
now i64
|
||||
cmd string
|
||||
data string
|
||||
}
|
||||
|
||||
pub struct Response {
|
||||
pub:
|
||||
result string
|
||||
error string
|
||||
}
|
||||
|
||||
// send data to a queue and wait till return comes back
|
||||
// timeout in milliseconds
|
||||
// params
|
||||
// cmd string @[required]
|
||||
// data string @[required]
|
||||
// timeout u64=60000 //60 sec
|
||||
// wait bool=true
|
||||
pub fn (mut q RedisRpc) call(args RPCArgs) !string {
|
||||
retqueue := rand.uuid_v4()
|
||||
now := time.now().unix()
|
||||
message := Message{
|
||||
ret_queue: retqueue
|
||||
now: now
|
||||
cmd: args.cmd
|
||||
data: args.data
|
||||
}
|
||||
encoded := json.encode(message)
|
||||
q.redis.lpush(q.key, encoded)!
|
||||
|
||||
if args.wait {
|
||||
return q.result(args.timeout, retqueue)!
|
||||
}
|
||||
return ''
|
||||
}
|
||||
|
||||
// get return once result processed
|
||||
pub fn (mut q RedisRpc) result(timeout u64, retqueue string) !string {
|
||||
start := u64(time.now().unix_milli())
|
||||
for {
|
||||
r := q.redis.rpop(retqueue) or { '' }
|
||||
if r != '' {
|
||||
res := json.decode(Response, r)!
|
||||
if res.error != '' {
|
||||
return res.error
|
||||
}
|
||||
return res.result
|
||||
}
|
||||
if u64(time.now().unix_milli()) > (start + timeout) {
|
||||
break
|
||||
}
|
||||
time.sleep(time.millisecond)
|
||||
}
|
||||
return error('timeout on returnqueue: ${retqueue}')
|
||||
}
|
||||
|
||||
@[params]
|
||||
pub struct ProcessParams {
|
||||
pub:
|
||||
timeout u64
|
||||
}
|
||||
|
||||
// to be used by processor, to get request and execute, this is the server side of a RPC mechanism
|
||||
// 2nd argument is a function which needs to execute the job: fn (string,string) !string
|
||||
pub fn (mut q RedisRpc) process(op fn (string, string) !string, params ProcessParams) !string {
|
||||
start := u64(time.now().unix_milli())
|
||||
for {
|
||||
r := q.redis.rpop(q.key) or { '' }
|
||||
if r != '' {
|
||||
msg := json.decode(Message, r)!
|
||||
|
||||
returnqueue := msg.ret_queue
|
||||
// epochtime:=parts[1].u64() //we don't do anything with it now
|
||||
cmd := msg.cmd
|
||||
data := msg.data
|
||||
// if true{panic("sd")}
|
||||
datareturn := op(cmd, data) or {
|
||||
response := Response{
|
||||
result: ''
|
||||
error: err.str()
|
||||
}
|
||||
encoded := json.encode(response)
|
||||
q.redis.lpush(returnqueue, encoded)!
|
||||
return ''
|
||||
}
|
||||
response := Response{
|
||||
result: datareturn
|
||||
error: ''
|
||||
}
|
||||
encoded := json.encode(response)
|
||||
q.redis.lpush(returnqueue, encoded)!
|
||||
return returnqueue
|
||||
}
|
||||
if params.timeout != 0 && u64(time.now().unix_milli()) > (start + params.timeout) {
|
||||
break
|
||||
}
|
||||
time.sleep(time.millisecond)
|
||||
}
|
||||
return error('timeout for waiting for cmd on ${q.key}')
|
||||
}
|
||||
|
||||
// get without timeout, returns none if nil
|
||||
pub fn (mut q RedisRpc) delete() ! {
|
||||
q.redis.del(q.key)!
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
import freeflowuniverse.herolib.clients.redisclient
|
||||
|
||||
fn setup() !&redisclient.Redis {
|
||||
mut redis := redisclient.core_get()!
|
||||
redis.selectdb(10) or { panic(err) }
|
||||
return &redis
|
||||
}
|
||||
|
||||
fn cleanup(mut redis redisclient.Redis) ! {
|
||||
redis.flushall()!
|
||||
// redis.disconnect()
|
||||
}
|
||||
|
||||
fn test_sadd() {
|
||||
mut redis := setup()!
|
||||
defer {
|
||||
cleanup(mut redis) or { panic(err) }
|
||||
}
|
||||
|
||||
redis.sadd('mysadd', ['a', 'b', 'c']) or { panic(err) }
|
||||
r := redis.smismember('mysadd', ['a', 'b', 'c']) or { panic(err) }
|
||||
assert r == [1, 1, 1]
|
||||
r2 := redis.smismember('mysadd', ['a', 'd', 'c']) or { panic(err) }
|
||||
assert r2 == [1, 0, 1]
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
module redisclient
|
||||
|
||||
// load a script and return the hash
|
||||
pub fn (mut r Redis) script_load(script string) !string {
|
||||
return r.send_expect_str(['SCRIPT LOAD', script])!
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
module redisclient
|
||||
|
||||
import freeflowuniverse.herolib.data.resp
|
||||
import freeflowuniverse.herolib.ui.console
|
||||
|
||||
// send list of strings, expect OK back
|
||||
pub fn (mut r Redis) send_expect_ok(items []string) ! {
|
||||
r.write_cmds(items)!
|
||||
res := r.get_string()!
|
||||
if res != 'OK' {
|
||||
console.print_debug("'${res}'")
|
||||
return error('did not get ok back')
|
||||
}
|
||||
}
|
||||
|
||||
// send list of strings, expect int back
|
||||
pub fn (mut r Redis) send_expect_int(items []string) !int {
|
||||
r.write_cmds(items)!
|
||||
return r.get_int()
|
||||
}
|
||||
|
||||
pub fn (mut r Redis) send_expect_bool(items []string) !bool {
|
||||
r.write_cmds(items)!
|
||||
return r.get_bool()
|
||||
}
|
||||
|
||||
// send list of strings, expect string back
|
||||
pub fn (mut r Redis) send_expect_str(items []string) !string {
|
||||
r.write_cmds(items)!
|
||||
return r.get_string()
|
||||
}
|
||||
|
||||
// send list of strings, expect string or nil back
|
||||
pub fn (mut r Redis) send_expect_strnil(items []string) !string {
|
||||
r.write_cmds(items)!
|
||||
d := r.get_string_nil()!
|
||||
return d
|
||||
}
|
||||
|
||||
// send list of strings, expect list of strings back
|
||||
pub fn (mut r Redis) send_expect_list_str(items []string) ![]string {
|
||||
r.write_cmds(items)!
|
||||
return r.get_list_str()
|
||||
}
|
||||
|
||||
pub fn (mut r Redis) send_expect_list_int(items []string) ![]int {
|
||||
r.write_cmds(items)!
|
||||
return r.get_list_int()
|
||||
}
|
||||
|
||||
pub fn (mut r Redis) send_expect_list(items []string) ![]resp.RValue {
|
||||
r.write_cmds(items)!
|
||||
res := r.get_response()!
|
||||
return resp.get_redis_array(res)
|
||||
}
|
||||
@@ -1,864 +0,0 @@
|
||||
import freeflowuniverse.herolib.clients.redisclient
|
||||
import time
|
||||
import freeflowuniverse.herolib.ui.console
|
||||
// original code see https://github.com/patrickpissurno/vredis/blob/master/vredis_test.v
|
||||
// credits see there as well (-:
|
||||
|
||||
fn setup() !&redisclient.Redis {
|
||||
mut redis := redisclient.core_get()!
|
||||
// Select db 10 to be away from default one '0'
|
||||
redis.selectdb(10) or { panic(err) }
|
||||
return &redis
|
||||
}
|
||||
|
||||
fn cleanup(mut redis redisclient.Redis) ! {
|
||||
redis.flushall()!
|
||||
// redis.disconnect()
|
||||
}
|
||||
|
||||
fn test_set() {
|
||||
mut redis := setup()!
|
||||
defer {
|
||||
cleanup(mut redis) or { panic(err) }
|
||||
}
|
||||
// console.print_debug('start')
|
||||
// for _ in 0 .. 10000 {
|
||||
// redis.set('test0', '123')!
|
||||
// }
|
||||
console.print_debug('stop')
|
||||
redis.set('test0', '456')!
|
||||
res := redis.get('test0')!
|
||||
assert res == '456'
|
||||
|
||||
redis.hset('x', 'a', '222')!
|
||||
redis.hset('x', 'b', '333')!
|
||||
mut res3 := redis.hget('x', 'b')!
|
||||
assert res3 == '333'
|
||||
redis.hdel('x', 'b')!
|
||||
res3 = redis.hget('x', 'b')!
|
||||
assert res3 == ''
|
||||
e := redis.hexists('x', 'a')!
|
||||
assert e
|
||||
}
|
||||
|
||||
fn test_large_value() {
|
||||
mut redis := setup()!
|
||||
defer {
|
||||
cleanup(mut redis) or { panic(err) }
|
||||
}
|
||||
rr := 'SSS' + 'a'.repeat(40000) + 'EEE'
|
||||
mut rr2 := ''
|
||||
for i in 0 .. 50 {
|
||||
redis.set('test_large_value0', rr)!
|
||||
rr2 = redis.get('test_large_value0')!
|
||||
assert rr.len == rr2.len
|
||||
assert rr == rr2
|
||||
}
|
||||
for i3 in 0 .. 100 {
|
||||
redis.set('test_large_value${i3}', rr)!
|
||||
}
|
||||
for i4 in 0 .. 100 {
|
||||
rr4 := redis.get('test_large_value${i4}')!
|
||||
assert rr.len == rr4.len
|
||||
redis.del('test_large_value${i4}')!
|
||||
}
|
||||
}
|
||||
|
||||
fn test_queue() {
|
||||
mut redis := setup()!
|
||||
defer {
|
||||
cleanup(mut redis) or { panic(err) }
|
||||
}
|
||||
mut q := redis.queue_get('kds:q')
|
||||
q.add('test1')!
|
||||
q.add('test2')!
|
||||
mut res := q.get(1)!
|
||||
assert res == 'test1'
|
||||
res = q.get(1)!
|
||||
assert res == 'test2'
|
||||
console.print_debug('start')
|
||||
res = q.get(100) or { '' }
|
||||
console.print_debug('stop')
|
||||
assert res == ''
|
||||
console.print_debug(res)
|
||||
}
|
||||
|
||||
fn test_scan() {
|
||||
mut redis := setup()!
|
||||
defer {
|
||||
cleanup(mut redis) or { panic(err) }
|
||||
}
|
||||
console.print_debug('stop')
|
||||
redis.set('test3', '12')!
|
||||
redis.set('test4', '34')!
|
||||
redis.set('test5', '56')!
|
||||
redis.set('test6', '78')!
|
||||
redis.set('test7', '9')!
|
||||
cursor, data := redis.scan(0)!
|
||||
console.print_debug(data)
|
||||
assert cursor == '0'
|
||||
}
|
||||
|
||||
// fn test_set_opts() {
|
||||
// mut redis := setup()!
|
||||
// defer {
|
||||
// cleanup(mut redis) or { panic(err) }
|
||||
// }
|
||||
// assert redis.set_opts('test8', '123', redisclient.SetOpts{
|
||||
// ex: 2
|
||||
// }) or {false}== true
|
||||
// assert redis.set_opts('test8', '456', redisclient.SetOpts{
|
||||
// px: 2000
|
||||
// xx: true
|
||||
// }) or {false} == true
|
||||
// assert redis.set_opts('test8', '789', redisclient.SetOpts{
|
||||
// px: 1000
|
||||
// nx: true
|
||||
// }) or {false}== false
|
||||
// // Works with redis version > 6
|
||||
// assert redis.set_opts('test8', '012', redisclient.SetOpts{ keep_ttl: true }) or {false}== true
|
||||
// }
|
||||
|
||||
fn test_setex() {
|
||||
mut redis := setup()!
|
||||
defer {
|
||||
cleanup(mut redis) or { panic(err) }
|
||||
}
|
||||
redis.setex('test9', 2, '123')!
|
||||
mut r := redis.get('test9')!
|
||||
assert r == '123'
|
||||
|
||||
time.sleep(2100 * time.millisecond)
|
||||
r = redis.get('test9')!
|
||||
|
||||
assert r == ''
|
||||
}
|
||||
|
||||
fn test_psetex() {
|
||||
mut redis := setup()!
|
||||
defer {
|
||||
cleanup(mut redis) or { panic(err) }
|
||||
}
|
||||
redis.psetex('test10', 200, '123')!
|
||||
mut r := redis.get('test10') or {
|
||||
assert false
|
||||
return
|
||||
}
|
||||
assert r == '123'
|
||||
|
||||
time.sleep(220 * time.millisecond)
|
||||
r = redis.get('test10')!
|
||||
assert r == ''
|
||||
}
|
||||
|
||||
fn test_setnx() {
|
||||
mut redis := setup()!
|
||||
defer {
|
||||
cleanup(mut redis) or { panic(err) }
|
||||
}
|
||||
mut r1 := redis.setnx('test11', '123')!
|
||||
assert r1 == 1
|
||||
r1 = redis.setnx('test11', '456')!
|
||||
assert r1 == 0
|
||||
|
||||
val := redis.get('test11') or {
|
||||
assert false
|
||||
return
|
||||
}
|
||||
assert val == '123'
|
||||
}
|
||||
|
||||
fn test_incrby() {
|
||||
mut redis := setup()!
|
||||
defer {
|
||||
cleanup(mut redis) or { panic(err) }
|
||||
}
|
||||
|
||||
redis.set('test12', '100')!
|
||||
r1 := redis.incrby('test12', 4) or {
|
||||
assert false
|
||||
return
|
||||
}
|
||||
assert r1 == 104
|
||||
|
||||
r2 := redis.incrby('test13', 2) or {
|
||||
assert false
|
||||
return
|
||||
}
|
||||
assert r2 == 2
|
||||
|
||||
redis.set('test14', 'nan')!
|
||||
redis.incrby('test14', 1) or {
|
||||
assert true
|
||||
return
|
||||
}
|
||||
assert false
|
||||
}
|
||||
|
||||
fn test_incr() {
|
||||
mut redis := setup()!
|
||||
defer {
|
||||
cleanup(mut redis) or { panic(err) }
|
||||
}
|
||||
redis.set('test15', '100')!
|
||||
r1 := redis.incr('test15') or {
|
||||
assert false
|
||||
return
|
||||
}
|
||||
assert r1 == 101
|
||||
|
||||
r2 := redis.incr('test16') or {
|
||||
assert false
|
||||
return
|
||||
}
|
||||
assert r2 == 1
|
||||
|
||||
redis.set('test17', 'nan')!
|
||||
redis.incr('test17') or {
|
||||
assert true
|
||||
return
|
||||
}
|
||||
assert false
|
||||
}
|
||||
|
||||
fn test_decr() {
|
||||
mut redis := setup()!
|
||||
defer {
|
||||
cleanup(mut redis) or { panic(err) }
|
||||
}
|
||||
redis.set('test18', '100')!
|
||||
r1 := redis.decr('test18') or {
|
||||
assert false
|
||||
return
|
||||
}
|
||||
assert r1 == 99
|
||||
|
||||
r2 := redis.decr('test19') or {
|
||||
assert false
|
||||
return
|
||||
}
|
||||
assert r2 == -1
|
||||
|
||||
redis.set('test20', 'nan')!
|
||||
redis.decr('test20') or {
|
||||
assert true
|
||||
return
|
||||
}
|
||||
assert false
|
||||
}
|
||||
|
||||
fn test_decrby() {
|
||||
mut redis := setup()!
|
||||
defer {
|
||||
cleanup(mut redis) or { panic(err) }
|
||||
}
|
||||
redis.set('test21', '100')!
|
||||
r1 := redis.decrby('test21', 4) or {
|
||||
assert false
|
||||
return
|
||||
}
|
||||
assert r1 == 96
|
||||
|
||||
r2 := redis.decrby('test22', 2) or {
|
||||
assert false
|
||||
return
|
||||
}
|
||||
assert r2 == -2
|
||||
|
||||
redis.set('test23', 'nan')!
|
||||
redis.decrby('test23', 1) or {
|
||||
assert true
|
||||
return
|
||||
}
|
||||
assert false
|
||||
}
|
||||
|
||||
fn test_incrbyfloat() {
|
||||
mut redis := setup()!
|
||||
defer {
|
||||
cleanup(mut redis) or { panic(err) }
|
||||
}
|
||||
redis.set('test24', '3.1415')!
|
||||
r1 := redis.incrbyfloat('test24', 3.1415) or {
|
||||
assert false
|
||||
return
|
||||
}
|
||||
assert r1 == 6.283
|
||||
|
||||
r2 := redis.incrbyfloat('test25', 3.14) or {
|
||||
assert false
|
||||
return
|
||||
}
|
||||
assert r2 == 3.14
|
||||
|
||||
r3 := redis.incrbyfloat('test25', -3.14) or {
|
||||
assert false
|
||||
return
|
||||
}
|
||||
assert r3 == 0
|
||||
|
||||
redis.set('test26', 'nan')!
|
||||
redis.incrbyfloat('test26', 1.5) or {
|
||||
assert true
|
||||
return
|
||||
}
|
||||
assert false
|
||||
}
|
||||
|
||||
fn test_append() {
|
||||
mut redis := setup()!
|
||||
defer {
|
||||
cleanup(mut redis) or { panic(err) }
|
||||
}
|
||||
redis.set('test27', 'bac')!
|
||||
r1 := redis.append('test27', 'on') or {
|
||||
assert false
|
||||
return
|
||||
}
|
||||
assert r1 == 5
|
||||
|
||||
r2 := redis.get('test27') or {
|
||||
assert false
|
||||
return
|
||||
}
|
||||
assert r2 == 'bacon'
|
||||
}
|
||||
|
||||
fn test_lpush() {
|
||||
mut redis := setup()!
|
||||
defer {
|
||||
cleanup(mut redis) or { panic(err) }
|
||||
}
|
||||
r := redis.lpush('test28', 'item 1') or {
|
||||
assert false
|
||||
return
|
||||
}
|
||||
assert r == 1
|
||||
}
|
||||
|
||||
fn test_rpush() {
|
||||
mut redis := setup()!
|
||||
defer {
|
||||
cleanup(mut redis) or { panic(err) }
|
||||
}
|
||||
r := redis.rpush('test29', 'item 1') or {
|
||||
assert false
|
||||
return
|
||||
}
|
||||
assert r == 1
|
||||
}
|
||||
|
||||
fn test_setrange() {
|
||||
mut redis := setup()!
|
||||
defer {
|
||||
cleanup(mut redis) or { panic(err) }
|
||||
}
|
||||
r1 := redis.setrange('test30', 0, 'bac') or {
|
||||
assert false
|
||||
return
|
||||
}
|
||||
assert r1 == 3
|
||||
|
||||
r2 := redis.setrange('test30', 3, 'on') or {
|
||||
assert false
|
||||
return
|
||||
}
|
||||
assert r2 == 5
|
||||
}
|
||||
|
||||
fn test_expire() {
|
||||
mut redis := setup()!
|
||||
defer {
|
||||
cleanup(mut redis) or { panic(err) }
|
||||
}
|
||||
r1 := redis.expire('test31', 2) or {
|
||||
assert false
|
||||
return
|
||||
}
|
||||
assert r1 == 0
|
||||
|
||||
redis.set('test31', '123')!
|
||||
r2 := redis.expire('test31', 2) or {
|
||||
assert false
|
||||
return
|
||||
}
|
||||
assert r2 == 1
|
||||
}
|
||||
|
||||
fn test_pexpire() {
|
||||
mut redis := setup()!
|
||||
defer {
|
||||
cleanup(mut redis) or { panic(err) }
|
||||
}
|
||||
r1 := redis.pexpire('test32', 200) or {
|
||||
assert false
|
||||
return
|
||||
}
|
||||
assert r1 == 0
|
||||
|
||||
redis.set('test32', '123')!
|
||||
r2 := redis.pexpire('test32', 200) or {
|
||||
assert false
|
||||
return
|
||||
}
|
||||
assert r2 == 1
|
||||
}
|
||||
|
||||
fn test_expireat() {
|
||||
mut redis := setup()!
|
||||
defer {
|
||||
cleanup(mut redis) or { panic(err) }
|
||||
}
|
||||
r1 := redis.expireat('test33', 1293840000) or {
|
||||
assert false
|
||||
return
|
||||
}
|
||||
assert r1 == 0
|
||||
|
||||
redis.set('test33', '123')!
|
||||
r2 := redis.expireat('test33', 1293840000) or {
|
||||
assert false
|
||||
return
|
||||
}
|
||||
assert r2 == 1
|
||||
}
|
||||
|
||||
fn test_pexpireat() {
|
||||
mut redis := setup()!
|
||||
defer {
|
||||
cleanup(mut redis) or { panic(err) }
|
||||
}
|
||||
r1 := redis.pexpireat('test34', 1555555555005) or {
|
||||
assert false
|
||||
return
|
||||
}
|
||||
assert r1 == 0
|
||||
|
||||
redis.set('test34', '123')!
|
||||
r2 := redis.pexpireat('test34', 1555555555005) or {
|
||||
assert false
|
||||
return
|
||||
}
|
||||
assert r2 == 1
|
||||
}
|
||||
|
||||
fn test_persist() {
|
||||
mut redis := setup()!
|
||||
defer {
|
||||
cleanup(mut redis) or { panic(err) }
|
||||
}
|
||||
r1 := redis.persist('test35') or {
|
||||
assert false
|
||||
return
|
||||
}
|
||||
assert r1 == 0
|
||||
redis.setex('test35', 2, '123')!
|
||||
r2 := redis.persist('test35') or {
|
||||
assert false
|
||||
return
|
||||
}
|
||||
assert r2 == 1
|
||||
}
|
||||
|
||||
fn test_get() {
|
||||
mut redis := setup()!
|
||||
defer {
|
||||
cleanup(mut redis) or { panic(err) }
|
||||
}
|
||||
redis.set('test36', '123')!
|
||||
mut r := redis.get('test36')!
|
||||
assert r == '123'
|
||||
assert helper_get_key_not_found(mut redis, 'test37') == true
|
||||
}
|
||||
|
||||
fn test_getset() {
|
||||
mut redis := setup()!
|
||||
defer {
|
||||
cleanup(mut redis) or { panic(err) }
|
||||
}
|
||||
mut r1 := redis.getset('test38', '10') or { '' }
|
||||
assert r1 == ''
|
||||
|
||||
r2 := redis.getset('test38', '15') or {
|
||||
assert false
|
||||
return
|
||||
}
|
||||
assert r2 == '10'
|
||||
|
||||
r3 := redis.get('test38') or {
|
||||
assert false
|
||||
return
|
||||
}
|
||||
assert r3 == '15'
|
||||
}
|
||||
|
||||
fn test_getrange() {
|
||||
mut redis := setup()!
|
||||
defer {
|
||||
cleanup(mut redis) or { panic(err) }
|
||||
}
|
||||
redis.set('test39', 'community')!
|
||||
r1 := redis.getrange('test39', 4, -1) or {
|
||||
assert false
|
||||
return
|
||||
}
|
||||
assert r1 == 'unity'
|
||||
|
||||
r2 := redis.getrange('test40', 0, -1) or {
|
||||
assert false
|
||||
return
|
||||
}
|
||||
assert r2 == ''
|
||||
}
|
||||
|
||||
fn test_randomkey() {
|
||||
mut redis := setup()!
|
||||
defer {
|
||||
cleanup(mut redis) or { panic(err) }
|
||||
}
|
||||
assert helper_randomkey_database_empty(mut redis) == true
|
||||
redis.set('test41', '123')!
|
||||
r2 := redis.randomkey() or {
|
||||
assert false
|
||||
return
|
||||
}
|
||||
assert r2 == 'test41'
|
||||
assert helper_get_key_not_found(mut redis, 'test42') == true
|
||||
}
|
||||
|
||||
fn test_strlen() {
|
||||
mut redis := setup()!
|
||||
defer {
|
||||
cleanup(mut redis) or { panic(err) }
|
||||
}
|
||||
redis.set('test43', 'bacon')!
|
||||
r1 := redis.strlen('test43') or {
|
||||
assert false
|
||||
return
|
||||
}
|
||||
assert r1 == 5
|
||||
|
||||
r2 := redis.strlen('test44') or {
|
||||
assert false
|
||||
return
|
||||
}
|
||||
assert r2 == 0
|
||||
}
|
||||
|
||||
fn test_lpop() {
|
||||
mut redis := setup()!
|
||||
defer {
|
||||
cleanup(mut redis) or { panic(err) }
|
||||
}
|
||||
redis.lpush('test45', '123') or {
|
||||
assert false
|
||||
return
|
||||
}
|
||||
r1 := redis.lpop('test45') or {
|
||||
assert false
|
||||
return
|
||||
}
|
||||
assert r1 == '123'
|
||||
assert helper_lpop_key_not_found(mut redis, 'test46') == true
|
||||
}
|
||||
|
||||
fn test_rpop() {
|
||||
mut redis := setup()!
|
||||
defer {
|
||||
cleanup(mut redis) or { panic(err) }
|
||||
}
|
||||
redis.lpush('test47', '123') or {
|
||||
assert false
|
||||
return
|
||||
}
|
||||
r1 := redis.rpop('test47') or {
|
||||
assert false
|
||||
return
|
||||
}
|
||||
assert r1 == '123'
|
||||
assert helper_rpop_key_not_found(mut redis, 'test48') == true
|
||||
}
|
||||
|
||||
fn test_brpop() {
|
||||
mut redis := setup()!
|
||||
defer {
|
||||
cleanup(mut redis) or { panic(err) }
|
||||
}
|
||||
redis.lpush('test47', '123')!
|
||||
redis.lpush('test48', 'balbal')!
|
||||
r1 := redis.brpop(['test47', 'test48'], 1)!
|
||||
assert r1[0] == 'test47'
|
||||
assert r1[1] == '123'
|
||||
r2 := redis.brpop(['test47', 'test48'], 1)!
|
||||
assert r2[0] == 'test48'
|
||||
assert r2[1] == 'balbal'
|
||||
r3 := redis.brpop(['test47'], 1) or { return }
|
||||
assert false, 'brpop should timeout'
|
||||
}
|
||||
|
||||
fn test_lrpop() {
|
||||
mut redis := setup()!
|
||||
defer {
|
||||
cleanup(mut redis) or { panic(err) }
|
||||
}
|
||||
redis.lpush('test47', '123')!
|
||||
redis.lpush('test48', 'balbal')!
|
||||
r1 := redis.blpop(['test47', 'test48'], 1)!
|
||||
assert r1[0] == 'test47'
|
||||
assert r1[1] == '123'
|
||||
r2 := redis.blpop(['test47', 'test48'], 1)!
|
||||
assert r2[0] == 'test48'
|
||||
assert r2[1] == 'balbal'
|
||||
r3 := redis.blpop(['test47'], 1) or { return }
|
||||
assert false, 'blpop should timeout'
|
||||
}
|
||||
|
||||
fn test_llen() {
|
||||
mut redis := setup()!
|
||||
defer {
|
||||
cleanup(mut redis) or { panic(err) }
|
||||
}
|
||||
r1 := redis.lpush('test49', '123') or {
|
||||
assert false
|
||||
return
|
||||
}
|
||||
r2 := redis.llen('test49') or {
|
||||
assert false
|
||||
return
|
||||
}
|
||||
assert r2 == r1
|
||||
|
||||
r3 := redis.llen('test50') or {
|
||||
assert false
|
||||
return
|
||||
}
|
||||
assert r3 == 0
|
||||
|
||||
redis.set('test51', 'not a list')!
|
||||
redis.llen('test51') or {
|
||||
assert true
|
||||
return
|
||||
}
|
||||
assert false
|
||||
}
|
||||
|
||||
fn test_ttl() {
|
||||
mut redis := setup()!
|
||||
defer {
|
||||
cleanup(mut redis) or { panic(err) }
|
||||
}
|
||||
redis.setex('test52', 15, '123')!
|
||||
r1 := redis.ttl('test52') or {
|
||||
assert false
|
||||
return
|
||||
}
|
||||
assert r1 == 15
|
||||
|
||||
redis.set('test53', '123')!
|
||||
r2 := redis.ttl('test53') or {
|
||||
assert false
|
||||
return
|
||||
}
|
||||
assert r2 == -1
|
||||
|
||||
r3 := redis.ttl('test54') or {
|
||||
assert false
|
||||
return
|
||||
}
|
||||
assert r3 == -2
|
||||
}
|
||||
|
||||
fn test_pttl() {
|
||||
mut redis := setup()!
|
||||
defer {
|
||||
cleanup(mut redis) or { panic(err) }
|
||||
}
|
||||
redis.psetex('test55', 1500, '123')!
|
||||
r1 := redis.pttl('test55') or {
|
||||
assert false
|
||||
return
|
||||
}
|
||||
assert r1 >= 1490 && r1 <= 1500
|
||||
|
||||
redis.set('test56', '123')!
|
||||
r2 := redis.pttl('test56') or {
|
||||
assert false
|
||||
return
|
||||
}
|
||||
assert r2 == -1
|
||||
|
||||
r3 := redis.pttl('test57') or {
|
||||
assert false
|
||||
return
|
||||
}
|
||||
assert r3 == -2
|
||||
}
|
||||
|
||||
fn test_exists() {
|
||||
mut redis := setup()!
|
||||
defer {
|
||||
cleanup(mut redis) or { panic(err) }
|
||||
}
|
||||
r1 := redis.exists('test58') or {
|
||||
assert false
|
||||
return
|
||||
}
|
||||
assert r1 == false
|
||||
|
||||
redis.set('test59', '123')!
|
||||
r2 := redis.exists('test59') or {
|
||||
assert false
|
||||
return
|
||||
}
|
||||
assert r2 == true
|
||||
}
|
||||
|
||||
fn test_type_of() {
|
||||
mut redis := setup()!
|
||||
defer {
|
||||
cleanup(mut redis) or { panic(err) }
|
||||
}
|
||||
_ := redis.type_of('test60') or {
|
||||
assert true
|
||||
return
|
||||
}
|
||||
|
||||
redis.set('test61', '123')!
|
||||
mut r := redis.type_of('test61') or {
|
||||
assert false
|
||||
return
|
||||
}
|
||||
assert r == 'string'
|
||||
|
||||
_ := redis.lpush('test62', '123')!
|
||||
r = redis.type_of('test62') or {
|
||||
assert false
|
||||
return
|
||||
}
|
||||
assert r == 'list'
|
||||
}
|
||||
|
||||
fn test_del() {
|
||||
mut redis := setup()!
|
||||
defer {
|
||||
cleanup(mut redis) or { panic(err) }
|
||||
}
|
||||
redis.set('test63', '123')!
|
||||
c := redis.del('test63') or {
|
||||
assert false
|
||||
return
|
||||
}
|
||||
assert c == 1
|
||||
assert helper_get_key_not_found(mut redis, 'test63') == true
|
||||
}
|
||||
|
||||
fn test_rename() {
|
||||
mut redis := setup()!
|
||||
defer {
|
||||
cleanup(mut redis) or { panic(err) }
|
||||
}
|
||||
redis.rename('test64', 'test65') or { console.print_debug('key not found') }
|
||||
redis.set('test64', 'will be 65')!
|
||||
redis.rename('test64', 'test65')!
|
||||
r := redis.get('test65') or {
|
||||
assert false
|
||||
return
|
||||
}
|
||||
assert r == 'will be 65'
|
||||
}
|
||||
|
||||
fn test_renamenx() {
|
||||
mut redis := setup()!
|
||||
defer {
|
||||
cleanup(mut redis) or { panic(err) }
|
||||
}
|
||||
assert helper_renamenx_err_helper(mut redis, 'test66', 'test67') == 'no such key'
|
||||
redis.set('test68', '123')!
|
||||
redis.set('test66', 'will be 67')!
|
||||
r1 := redis.renamenx('test66', 'test67') or {
|
||||
assert false
|
||||
return
|
||||
}
|
||||
assert r1 == 1
|
||||
|
||||
r2 := redis.get('test67') or {
|
||||
assert false
|
||||
return
|
||||
}
|
||||
assert r2 == 'will be 67'
|
||||
|
||||
r3 := redis.renamenx('test67', 'test68') or {
|
||||
assert false
|
||||
return
|
||||
}
|
||||
assert r3 == 0
|
||||
}
|
||||
|
||||
fn test_flushall() {
|
||||
mut redis := setup()!
|
||||
defer {
|
||||
cleanup(mut redis) or { panic(err) }
|
||||
}
|
||||
redis.set('test69', '123')!
|
||||
redis.flushall()!
|
||||
assert helper_get_key_not_found(mut redis, 'test69') == true
|
||||
}
|
||||
|
||||
fn test_keys() {
|
||||
mut redis := setup()!
|
||||
defer {
|
||||
cleanup(mut redis) or { panic(err) }
|
||||
}
|
||||
redis.set('test70:1', '1')!
|
||||
redis.set('test70:2', '2')!
|
||||
r1 := redis.keys('test70:*') or {
|
||||
assert false
|
||||
return
|
||||
}
|
||||
assert r1.len == 2
|
||||
}
|
||||
|
||||
fn helper_get_key_not_found(mut redis redisclient.Redis, key string) bool {
|
||||
return redis.get(key) or {
|
||||
if err.msg() == 'key not found' || err.msg() == '' {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
} == ''
|
||||
}
|
||||
|
||||
fn helper_randomkey_database_empty(mut redis redisclient.Redis) bool {
|
||||
return redis.randomkey() or {
|
||||
if err.msg() == 'database is empty' || err.msg() == '' {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
} == ''
|
||||
}
|
||||
|
||||
fn helper_renamenx_err_helper(mut redis redisclient.Redis, key string, newkey string) string {
|
||||
redis.renamenx(key, newkey) or { return 'no such key' }
|
||||
return ''
|
||||
}
|
||||
|
||||
fn helper_lpop_key_not_found(mut redis redisclient.Redis, key string) bool {
|
||||
return redis.lpop(key) or {
|
||||
if err.msg() == 'key not found' || err.msg() == '' {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
} == ''
|
||||
}
|
||||
|
||||
fn helper_rpop_key_not_found(mut redis redisclient.Redis, key string) bool {
|
||||
return redis.rpop(key) or {
|
||||
if err.msg() == 'key not found' || err.msg() == '' {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
} == ''
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
import freeflowuniverse.herolib.clients.redisclient
|
||||
import freeflowuniverse.herolib.ui.console
|
||||
|
||||
fn setup() !&redisclient.Redis {
|
||||
mut redis := redisclient.core_get()!
|
||||
// Select db 10 to be away from default one '0'
|
||||
redis.selectdb(10) or { panic(err) }
|
||||
return &redis
|
||||
}
|
||||
|
||||
fn cleanup(mut redis redisclient.Redis) ! {
|
||||
redis.flushall()!
|
||||
// redis.disconnect()
|
||||
}
|
||||
|
||||
fn process_test(cmd string, data string) !string {
|
||||
return '${cmd}+++++${data}\n\n\n\n'
|
||||
}
|
||||
|
||||
fn test_rpc() {
|
||||
mut redis := setup()!
|
||||
defer {
|
||||
cleanup(mut redis) or { panic(err) }
|
||||
}
|
||||
mut r := redis.rpc_get('testrpc')
|
||||
|
||||
r.call(cmd: 'test.cmd', data: 'this is my data, normally json', wait: false)!
|
||||
returnqueue := r.process(10000, process_test)!
|
||||
mut res := r.result(10000, returnqueue)!
|
||||
console.print_debug(res)
|
||||
|
||||
assert res.str().trim_space() == 'test.cmd+++++this is my data, normally json'
|
||||
}
|
||||
0
lib/clients/sendgrid/.heroscript
Normal file
0
lib/clients/sendgrid/.heroscript
Normal file
0
lib/clients/zdb/.heroscript
Normal file
0
lib/clients/zdb/.heroscript
Normal file
Reference in New Issue
Block a user