Change to a client. Appears to work. Docs aren't updated yet.
authorPete <pete@debu.gs>
Wed, 24 Apr 2019 16:03:15 +0000 (09:03 -0700)
committerPete <pete@debu.gs>
Wed, 24 Apr 2019 16:03:15 +0000 (09:03 -0700)
appl/cmd/redis.b
appl/lib/redis.b
module/redis.m

index db5488b99058166618cd372d50af6b0176a58c91..1e1f02fd14713c0d2d55818c5c6f719d349699fd 100644 (file)
@@ -7,7 +7,7 @@ include "arg.m";
 include "bufio.m"; bufio: Bufio; Iobuf: import bufio;
 include "string.m"; str: String;
 include "redis.m"; redis: Redis;
-       call, sendcmd, packcmd, parsecmd, printresult, parseresult: import redis;
+       RedisClient, packcmd, parsecmd: import redis;
 
 RedisC: module {
        init: fn(nil: ref Draw->Context, args: list of string);
@@ -20,6 +20,9 @@ init(nil: ref Draw->Context, args: list of string) {
        bufio = load Bufio Bufio->PATH;
        str = load String String->PATH;
        redis = load Redis Redis->PATH;
+
+       debug := 0;
+
        if(redis == nil) {
                sys->fprint(sys->fildes(2), "Can't load %s! %r\n", Redis->PATH);
                raise "fail:load";
@@ -55,7 +58,7 @@ init(nil: ref Draw->Context, args: list of string) {
                        arg->usage();
                        return;
                'D' =>
-                       redis->setdebug(1);
+                       debug = 1;
                * =>
                        arg->usage();
                        raise "fail:usage";
@@ -63,23 +66,21 @@ init(nil: ref Draw->Context, args: list of string) {
        }
        if(cmd == nil)
                interactive = 1;
-       
-       conn := dial->dial(addr, nil);
-       if(conn == nil) {
-               sys->fprint(sys->fildes(2), "redis: dialing %s: %r\n", addr);
+       redis->setdebug(debug);
+
+       c := redis->connect(addr);
+       if(c == nil) {
+               sys->fprint(sys->fildes(2), "redis: connecting to %s: %r\n", addr);
                raise "fail:errors";
        }
 
-       io := bufio->fopen(conn.dfd, bufio->ORDWR);
-       if(io == nil)
-               raise "fail:bufio";
-
        stdin := bufio->fopen(sys->fildes(0), bufio->OREAD);
-       if(io == nil)
+       if(stdin == nil)
                raise "fail:bufio";
 
-       # sys->fprint(sys->fildes(2), "redis: dialing %s, selecting %s\n", addr, dbno);
-       selectdb(io, dbno);
+       if(debug)
+               sys->fprint(sys->fildes(2), "redis: dialing %s, selecting %s\n", addr, dbno);
+       selectdb(c, dbno);
 
        cmd = rev(cmd);
 
@@ -89,9 +90,9 @@ init(nil: ref Draw->Context, args: list of string) {
                        arg->usage();
                        raise "fail:parse";
                }
-               if(sendcmd(io, ls)) {
+               if(c.sendcmd(ls)) {
                        cmd = tl cmd;
-                       printresult(io);
+                       c.printresult();
                }
        }
        if(!interactive)
@@ -108,15 +109,15 @@ init(nil: ref Draw->Context, args: list of string) {
                (ls, donep) := parsecmd(l, quotechar);
                if(donep) {
                        l = "";
-                       if(sendcmd(io, ls))
-                               printresult(io);
+                       if(c.sendcmd(ls))
+                               c.printresult();
                }
        }
 }
 
-selectdb(io: ref Iobuf, dbno: string) {
-       sendcmd(io, parsecmd("SELECT " + dbno, 0).t0);
-       printresult(io);
+selectdb(c: ref Redis->RedisClient, dbno: string) {
+       c.sendcmd(parsecmd("SELECT " + dbno, 0).t0);
+       c.printresult();
 }
 
 rev[T](s: list of T): list of T {
index 14f3541b0c3df82d88cb8aba71b6f2b8697af61b..ada837e1a2315fa56b58ccabe59f9c15458fc20e 100644 (file)
@@ -19,10 +19,29 @@ initmod(s: Sys, d: Dial, b: Bufio, st: String) {
        debug = 0;
 }
 
-call(io: ref Iobuf, cmd: list of string): list of (int, string) {
-       if(!sendcmd(io, cmd))
+connect(addr: string): ref RedisClient {
+       conn := dial->dial(addr, nil);
+       if(conn == nil) {
+               if(debug)
+                       sys->fprint(sys->fildes(2), "redis: dialing %s: %r\n", addr);
+               return nil;
+       }
+
+       io := bufio->fopen(conn.dfd, bufio->ORDWR);
+       if(io == nil)
+               return nil;
+
+       return client(io);
+}
+
+client(io: ref Iobuf): ref RedisClient {
+       return ref RedisClient(io);
+}
+
+RedisClient.call(c: self ref RedisClient, cmd: list of string): list of (int, string) {
+       if(!c.sendcmd(cmd))
                return nil;
-       return parseresult(io);
+       return c.parseresult();
 }
 
 setdebug(state: int) {
@@ -33,7 +52,7 @@ setdebug(state: int) {
 # particular, we expect to only parse atoms and arrays and we flatten all of the
 # data we get back into a list of (tag, data) tuples, even if the data that
 # comes back is not a list.
-parseresult(io: ref Iobuf): list of (int, string) {
+RedisClient.parseresult(cl: self ref RedisClient): list of (int, string) {
        r: list of (int, string) = nil;
        lt := array[256] of {
                '-' => RErr,
@@ -45,15 +64,15 @@ parseresult(io: ref Iobuf): list of (int, string) {
        sys->fprint(sys->fildes(2), "Connection dropped:  %r\n");
        raise "fail:errors";
 
-       c := io.getb();
+       c := cl.io.getb();
        if(debug)
                sys->fprint(sys->fildes(2), "« %c", c);
        case c {
        '-' or ':' or '+' =>
-               ln := chomp(io.gets('\n'));
+               ln := chomp(cl.io.gets('\n'));
                r = (lt[c], ln) :: r;
        '$' => # String
-               ln := io.gets('\n');
+               ln := cl.io.gets('\n');
                sz := str->toint(ln, 10).t0;
                if(debug)
                        sys->fprint(sys->fildes(2), "%s\n", ln);
@@ -63,10 +82,10 @@ parseresult(io: ref Iobuf): list of (int, string) {
                        r = (RStr, chomp(ln)) :: r;
                }
        '*' => # Array
-               ln := io.gets('\n');
+               ln := cl.io.gets('\n');
                sz := str->toint(ln, 10).t0;
                for(i := sz; i > 0; i--) {
-                       nx := parseresult(io);
+                       nx := cl.parseresult();
                        while(nx != nil) {
                                r = hd nx :: r;
                                nx = tl nx;
@@ -80,12 +99,12 @@ parseresult(io: ref Iobuf): list of (int, string) {
        return rev2(r, nil);
 }
 
-printresult(io: ref Iobuf) {
+RedisClient.printresult(cl: self ref RedisClient) {
        # Error:  -ERROR\r\n
        # Ints:  :NUMBER\r\n
        # Strings:  $size\r\nRAW\r\n *or* +RAW\r\n
        # Lists:  *size\r\nSTRING1 or INT1\r\n⋯\r\n
-       c := io.getb();
+       c := cl.io.getb();
        if(debug)
                sys->fprint(sys->fildes(2), "« %c", c);
        
@@ -95,12 +114,12 @@ printresult(io: ref Iobuf) {
        }
        case c {
        '-' or ':' or '+' =>
-               ln := chomp(io.gets('\n'));
+               ln := chomp(cl.io.gets('\n'));
                if(debug)
                        sys->fprint(sys->fildes(2), "%s\n", ln);
                sys->print("%s\n", ln);
        '$' =>
-               ln := io.gets('\n');
+               ln := cl.io.gets('\n');
                if(debug)
                        sys->fprint(sys->fildes(2), "%s\n", ln);
                sz := str->toint(ln, 10).t0;
@@ -109,13 +128,13 @@ printresult(io: ref Iobuf) {
                        return;
                }
                buf := array[sz + 2] of byte; # For the extra crlf.
-               i := io.read(buf, len buf);
+               i := cl.io.read(buf, len buf);
                if(debug)
                        sys->fprint(sys->fildes(2), "%s\n", string buf[:i]);
                s := chomp(string buf[:i]);
                sys->print("%s\n", s);
        '*' =>
-               ln := io.gets('\n');
+               ln := cl.io.gets('\n');
                if(debug)
                        sys->fprint(sys->fildes(2), "%s\n", ln);
                sz := str->toint(ln, 10).t0;
@@ -124,7 +143,7 @@ printresult(io: ref Iobuf) {
                        return;
                }
                for(i := sz; i; i--)
-                       printresult(io);
+                       cl.printresult();
        * =>
                sys->fprint(sys->fildes(2), "Mystery response: %d  %r\n", c);
                raise "fail:errors";
@@ -139,13 +158,13 @@ chomp(s: string): string {
        return s;
 }
 
-sendcmd(io: ref Iobuf, cmd: list of string): int {
+RedisClient.sendcmd(c: self ref RedisClient, cmd: list of string): int {
        cs := packcmd(cmd);
        if(debug)
                sys->fprint(sys->fildes(2), "» %s\n", cs);
        if(cs == nil)
                return 0;
-       io.puts(cs);
+       c.io.puts(cs);
        return 1;
 }
 
index d47a53bacbf8bd6898c79e3f5b9024cd689a185a..0ef8c37d059269574a456f1b7beaa6ba2a211436 100644 (file)
@@ -3,14 +3,25 @@ Redis: module {
        PATH: con "/dis/lib/redis.dis";
 
        initmod: fn(s: Sys, d: Dial, b: Bufio, st: String);
-       call: fn(io: ref Iobuf, cmd: list of string): list of (int, string);
-       sendcmd: fn(io: ref Iobuf, cmd: list of string): int;
-       packcmd: fn(cmd: list of string): string;
+       connect: fn(addr: string): ref RedisClient;
+       client: fn(io: ref Iobuf): ref RedisClient;
+
        parsecmd: fn(s: string, qc: int): (list of string, int);
-       printresult: fn(io: ref Iobuf);
-       parseresult: fn(io: ref Iobuf): list of (int, string);
+       packcmd: fn(cmd: list of string): string;
 
        RStr, RInt, RErr: con iota + 1;
 
        setdebug: fn(state: int);
+
+       RedisClient: adt {
+               call: fn(c: self ref RedisClient, cmd: list of string): list of (int, string);
+
+               # You probably won't need these:
+               sendcmd: fn(c: self ref RedisClient, cmd: list of string): int;
+               printresult: fn(c: self ref RedisClient);
+               parseresult: fn(c: self ref RedisClient): list of (int, string);
+
+               # Internal:
+               io: ref Bufio->Iobuf;
+       };
 };