Alexey Kishkin avatar Alexey Kishkin committed e30afab Merge

merge version without op type

Comments (0)

Files changed (5)

+Client memcache ocaml library
+
+This is a ocaml library that implements binary protocol for memcache.
+
+Author         : Alexey Kishkin (alexey@kishkin.name)
+Status         : beta version
+Reason         : Was not able to find good memcache client that implements decent binary protocol.
+How to install : Just drop memcache.ml and memcache.mli files to your project. memcache.ml uses unix library.
+
+Example:
+ 
+open Memcache
+
+let connector = new memcache_connector "localhost" 1999;;
+
+connector#add "walrus" "Odobenus rosmarus" 0 0;;
+
+connector#add "wax" "dum spiro -- spero" 0 0;;
+
+let result,key,value = connector#get "walrus" in
+      match result with
+       | MC_Key_not_found -> print_endline "not found"
+       | MC_No_error -> print_endline value
+       | _ -> print_endline "Something wrong"
+ end
+;;
+
 #!/bin/bash -
 
-ocamlbuild  -cflags -I,/usr/local/lib/ocaml/site-lib/oUnit -lflags -I,/usr/local/lib/ocaml/site-lib/oUnit -libs unix,oUnit  mc_test.byte
+#ocamlbuild  -cflags -I,/usr/lib/ocaml/oUnit -lflags -I,/usr/lib/ocaml/oUnit -libs unix,oUnit  mc_test.byte
+ocamlfind ocamlc -c memcache.mli  
+ocamlfind ocamlc -c memcache.ml 
+ocamlfind ocamlc -c mc_test.ml -package oUnit unix.cma oUnit.cma 
+ocamlfind ocamlc -o mc_test -package oUnit unix.cma oUnit.cma memcache.cmo mc_test.cmo 
+ 
 
 let test_fixture = "Memcache binary protocol tests " >:::
    [
-   "set_i8" >:: (fun () ->
-      assert_equal "\000" (let cargo = Buffer.create 1 in (set_i8 cargo 0; Buffer.contents cargo)); 
-      assert_equal "\010" (let cargo = Buffer.create 1 in (set_i8 cargo 10; Buffer.contents cargo)); 
-      assert_equal "\255" (let cargo = Buffer.create 1 in (set_i8 cargo 255; Buffer.contents cargo));
+   " set_i8" >:: (fun () ->
+      assert_equal "\000" (let cargo = Buffer.create 1 in ( set_i8 cargo 0; Buffer.contents cargo)); 
+      assert_equal "\010" (let cargo = Buffer.create 1 in ( set_i8 cargo 10; Buffer.contents cargo)); 
+      assert_equal "\255" (let cargo = Buffer.create 1 in ( set_i8 cargo 255; Buffer.contents cargo));
       );
-   "set_i16" >:: (fun() ->  
-       assert_equal "\000\000" (let cargo = Buffer.create 2 in (set_i16 cargo 0; Buffer.contents cargo)); 
-       assert_equal "\000\010" (let cargo = Buffer.create 2 in (set_i16 cargo 10; Buffer.contents cargo)); 
-       assert_equal "\000\255" (let cargo = Buffer.create 2 in (set_i16 cargo 255; Buffer.contents cargo));
-       assert_equal "\001\000" (let cargo = Buffer.create 2 in (set_i16 cargo 256; Buffer.contents cargo));
-       assert_equal "\255\255" (let cargo = Buffer.create 2 in (set_i16 cargo 0xFFFF; Buffer.contents cargo));
+   " set_i16" >:: (fun() ->  
+       assert_equal "\000\000" (let cargo = Buffer.create 2 in ( set_i16 cargo 0; Buffer.contents cargo)); 
+       assert_equal "\000\010" (let cargo = Buffer.create 2 in ( set_i16 cargo 10; Buffer.contents cargo)); 
+       assert_equal "\000\255" (let cargo = Buffer.create 2 in ( set_i16 cargo 255; Buffer.contents cargo));
+       assert_equal "\001\000" (let cargo = Buffer.create 2 in ( set_i16 cargo 256; Buffer.contents cargo));
+       assert_equal "\255\255" (let cargo = Buffer.create 2 in ( set_i16 cargo 0xFFFF; Buffer.contents cargo));
       );
-   "set_i32" >:: (fun() ->  
-       assert_equal "\000\000\000\000" (let cargo = Buffer.create 4 in (set_i32 cargo 0; Buffer.contents cargo)); 
-       assert_equal "\000\000\000\010" (let cargo = Buffer.create 4 in (set_i32 cargo 10; Buffer.contents cargo)); 
-       assert_equal "\000\000\000\255" (let cargo = Buffer.create 4 in (set_i32 cargo 255; Buffer.contents cargo));
-       assert_equal "\000\000\001\000" (let cargo = Buffer.create 4 in (set_i32 cargo 256; Buffer.contents cargo));
-       assert_equal "\000\000\255\255" (let cargo = Buffer.create 4 in (set_i32 cargo 0xFFFF; Buffer.contents cargo));
-       assert_equal "\000\001\000\000" (let cargo = Buffer.create 4 in (set_i32 cargo 0x10000; Buffer.contents cargo));
-       assert_equal "\000\255\255\255" (let cargo = Buffer.create 4 in (set_i32 cargo 0xFFFFFF; Buffer.contents cargo));
-       assert_equal "\001\000\000\000" (let cargo = Buffer.create 4 in (set_i32 cargo 0x1000000; Buffer.contents cargo));
+   " set_i32" >:: (fun() ->  
+       assert_equal "\000\000\000\000" (let cargo = Buffer.create 4 in ( set_i32 cargo 0; Buffer.contents cargo)); 
+       assert_equal "\000\000\000\010" (let cargo = Buffer.create 4 in ( set_i32 cargo 10; Buffer.contents cargo)); 
+       assert_equal "\000\000\000\255" (let cargo = Buffer.create 4 in ( set_i32 cargo 255; Buffer.contents cargo));
+       assert_equal "\000\000\001\000" (let cargo = Buffer.create 4 in ( set_i32 cargo 256; Buffer.contents cargo));
+       assert_equal "\000\000\255\255" (let cargo = Buffer.create 4 in ( set_i32 cargo 0xFFFF; Buffer.contents cargo));
+       assert_equal "\000\001\000\000" (let cargo = Buffer.create 4 in ( set_i32 cargo 0x10000; Buffer.contents cargo));
+       assert_equal "\000\255\255\255" (let cargo = Buffer.create 4 in ( set_i32 cargo 0xFFFFFF; Buffer.contents cargo));
+       assert_equal "\001\000\000\000" (let cargo = Buffer.create 4 in ( set_i32 cargo 0x1000000; Buffer.contents cargo));
       );
-   "set_int32" >:: (fun() ->  
-       assert_equal "\000\000\000\000" (let cargo = Buffer.create 4 in (set_int32 cargo 0l; Buffer.contents cargo)); 
-       assert_equal "\000\000\000\010" (let cargo = Buffer.create 4 in (set_int32 cargo 10l; Buffer.contents cargo)); 
-       assert_equal "\000\000\000\255" (let cargo = Buffer.create 4 in (set_int32 cargo 255l; Buffer.contents cargo));
-       assert_equal "\000\000\001\000" (let cargo = Buffer.create 4 in (set_int32 cargo 256l; Buffer.contents cargo));
-       assert_equal "\000\000\255\255" (let cargo = Buffer.create 4 in (set_int32 cargo 0xFFFFl; Buffer.contents cargo));
-       assert_equal "\000\001\000\000" (let cargo = Buffer.create 4 in (set_int32 cargo 0x10000l; Buffer.contents cargo));
-       assert_equal "\000\255\255\255" (let cargo = Buffer.create 4 in (set_int32 cargo 0xFFFFFFl; Buffer.contents cargo));
-       assert_equal "\001\000\000\000" (let cargo = Buffer.create 4 in (set_int32 cargo 0x1000000l; Buffer.contents cargo));
+   " set_int32" >:: (fun() ->  
+       assert_equal "\000\000\000\000" (let cargo = Buffer.create 4 in ( set_int32 cargo 0l; Buffer.contents cargo)); 
+       assert_equal "\000\000\000\010" (let cargo = Buffer.create 4 in ( set_int32 cargo 10l; Buffer.contents cargo)); 
+       assert_equal "\000\000\000\255" (let cargo = Buffer.create 4 in ( set_int32 cargo 255l; Buffer.contents cargo));
+       assert_equal "\000\000\001\000" (let cargo = Buffer.create 4 in ( set_int32 cargo 256l; Buffer.contents cargo));
+       assert_equal "\000\000\255\255" (let cargo = Buffer.create 4 in ( set_int32 cargo 0xFFFFl; Buffer.contents cargo));
+       assert_equal "\000\001\000\000" (let cargo = Buffer.create 4 in ( set_int32 cargo 0x10000l; Buffer.contents cargo));
+       assert_equal "\000\255\255\255" (let cargo = Buffer.create 4 in ( set_int32 cargo 0xFFFFFFl; Buffer.contents cargo));
+       assert_equal "\001\000\000\000" (let cargo = Buffer.create 4 in ( set_int32 cargo 0x1000000l; Buffer.contents cargo));
       );
-    "get_i8" >:: (fun() ->
-        assert_equal 0 (get_i8 "\000" 0);  
-        assert_equal 1 (get_i8 "\001" 0);  
-        assert_equal 255 (get_i8 "\255" 0);  
-        assert_equal 128 (get_i8 "\000\128" 1);  
+    " get_i8" >:: (fun() ->
+        assert_equal 0 ( get_i8 "\000" 0);  
+        assert_equal 1 ( get_i8 "\001" 0);  
+        assert_equal 255 ( get_i8 "\255" 0);  
+        assert_equal 128 ( get_i8 "\000\128" 1);  
       );  
-    "get_i16" >:: (fun() ->
-        assert_equal 0 (get_i16 "\000\000" 0);  
-        assert_equal 1 (get_i16 "\000\001" 0);  
-        assert_equal 255 (get_i16 "\000\255" 0);  
-        assert_equal 256 (get_i16 "\001\000" 0);  
-        assert_equal 0xFFFF (get_i16 "\255\255" 0);  
+    " get_i16" >:: (fun() ->
+        assert_equal 0 ( get_i16 "\000\000" 0);  
+        assert_equal 1 ( get_i16 "\000\001" 0);  
+        assert_equal 255 ( get_i16 "\000\255" 0);  
+        assert_equal 256 ( get_i16 "\001\000" 0);  
+        assert_equal 0xFFFF ( get_i16 "\255\255" 0);  
       );  
    ];;
 
 
 **********************************************************************)
 
-(** Low level operations *)
-type operation =
-   | Get
-   | Set
-   | Add
-   | Replace
-   | Delete
-   | Increment
-   | Decrement
-   | Quit
-   | Flush
-   | GetQ
-   | Noop
-   | Version
-   | GetK
-   | GetKQ
-   | Append
-   | Prepend
-   | Stat
-   | SetQ
-   | AddQ
-   | ReplaceQ
-   | DeleteQ
-   | IncrementQ
-   | DecrementQ
-   | QuitQ
-   | FlushQ
-   | AppendQ
-   | PrependQ;;
+(* Some constants of operations *)
+
+let opGet = 0x00
+let opSet = 0x01
+let opAdd = 0x02
+let opReplace = 0x03
+let opDelete = 0x04
+let opIncrement = 0x05
+let opDecrement = 0x06
+let opQuit = 0x07
+let opFlush = 0x08
+let opGetQ = 0x09
+let opNoop = 0x0a
+let opVersion = 0x0b
+let opGetK = 0x0c
+let opGetKQ = 0x0d
+let opAppend = 0x0e
+let opPrepend = 0x0f
+let opStat = 0x10
+let opSetQ = 0x11
+let opAddQ = 0x12
+let opReplaceQ = 0x13
+let opDeleteQ = 0x14
+let opIncrementQ = 0x15
+let opDecrementQ = 0x16
+let opQuitQ = 0x17
+let opFlushQ = 0x18
+let opAppendQ = 0x19
+let opPrependQ = 0x1a
+
 
 (** packet header *)
 type magic = Request | Response;;
    val port = port
    val mutable i_channel = stdin
    val mutable o_channel = stdout
-   method operation_encode = function
-      | Get -> 0x00
-      | Set -> 0x01
-      | Add -> 0x02
-      | Replace -> 0x03
-      | Delete -> 0x04
-      | Increment -> 0x05
-      | Decrement -> 0x06
-      | Quit -> 0x07
-      | Flush -> 0x08
-      | GetQ -> 0x09
-      | Noop -> 0x0a
-      | Version -> 0x0b
-      | GetK -> 0x0c
-      | GetKQ -> 0x0d
-      | Append -> 0x0e
-      | Prepend -> 0x0f
-      | Stat -> 0x10
-      | SetQ -> 0x11
-      | AddQ -> 0x12
-      | ReplaceQ -> 0x13
-      | DeleteQ -> 0x14
-      | IncrementQ -> 0x15
-      | DecrementQ -> 0x16
-      | QuitQ -> 0x17
-      | FlushQ -> 0x18
-      | AppendQ -> 0x19
-      | PrependQ -> 0x1a
-   
+
    method magic_code_encode = function
       | Request -> 0x80
       | Response -> 0x81
       else
          let buffer = Buffer.create (24 + vllen + keylen + extralen) in
          set_i8 buffer (self#magic_code_encode Request);           (* 0 *)
-         set_i8 buffer (self#operation_encode op);                 (* 1 *)
+         set_i8 buffer  op;                                        (* 1 *)
          set_i16 buffer keylen;                                    (*2 3*)
          set_i8 buffer extralen;                                   (* 4 *)
          set_i8 buffer 0;                                          (* 5 *) (* RAW data type *)
       let buf = Buffer.create 8 in
       let _ = set_i32 buf flags and _ = set_i32 buf expiration in
       let extras = Buffer.contents buf in
-      let cargo = self#encode_packet Set key extras v 0 0L in
+      let cargo = self#encode_packet opSet key extras v 0 0L in
       begin
          (* self#printhex cargo; *)
          output_string o_channel cargo;
       let buf = Buffer.create 8 in
       let _ = set_i32 buf flags and _ = set_i32 buf expiration in
       let extras = Buffer.contents buf in
-      let cargo = self#encode_packet SetQ key extras v 0 0L in
+      let cargo = self#encode_packet opSetQ key extras v 0 0L in
       begin
          (* self#printhex cargo; *)
          output_string o_channel cargo;
       let buf = Buffer.create 8 in
       let _ = set_i32 buf flags and _ = set_i32 buf expiration in
       let extras = Buffer.contents buf in
-      let cargo = self#encode_packet Add key extras v 0 0L in
+      let cargo = self#encode_packet opAdd key extras v 0 0L in
       begin
          (* self#printhex cargo; *)
          output_string o_channel cargo;
       let buf = Buffer.create 8 in
       let _ = set_i32 buf flags and _ = set_i32 buf expiration in
       let extras = Buffer.contents buf in
-      let cargo = self#encode_packet AddQ key extras v 0 0L in
+      let cargo = self#encode_packet opAddQ key extras v 0 0L in
       begin
          (* self#printhex cargo; *)
          output_string o_channel cargo;
       let buf = Buffer.create 8 in
       let _ = set_i32 buf flags and _ = set_i32 buf expiration in
       let extras = Buffer.contents buf in
-      let cargo = self#encode_packet Replace key extras v 0 0L in
+      let cargo = self#encode_packet opReplace key extras v 0 0L in
       begin
          (* self#printhex cargo; *)
          output_string o_channel cargo;
       let buf = Buffer.create 8 in
       let _ = set_i32 buf flags and _ = set_i32 buf expiration in
       let extras = Buffer.contents buf in
-      let cargo = self#encode_packet ReplaceQ key extras v 0 0L in
+      let cargo = self#encode_packet opReplaceQ key extras v 0 0L in
       begin
          (* self#printhex cargo; *)
          output_string o_channel cargo;
    *)
    
    method delete key =
-      let cargo = self#encode_packet Delete key "" "" 0 0L in
+      let cargo = self#encode_packet opDelete key "" "" 0 0L in
       begin
          output_string o_channel cargo;
          flush o_channel;
      *)
    
    method deleteq key =
-      let cargo = self#encode_packet DeleteQ key "" "" 0 0L in
+      let cargo = self#encode_packet opDeleteQ key "" "" 0 0L in
       begin
          output_string o_channel cargo;
          flush o_channel;
       @return  (status, key, value)  Key and value -- strings,  Status is 'response_status" type 
     *)
    method get key =
-      let cargo = self#encode_packet GetK key "" "" 0 0L in
+      let cargo = self#encode_packet opGetK key "" "" 0 0L in
       begin
          output_string o_channel cargo;
          flush o_channel;
    
    method multiget keys =
       List.iter (fun key ->
-                  let cargo = self#encode_packet GetKQ key "" "" 0 0L in
+                  let cargo = self#encode_packet opGetKQ key "" "" 0 0L in
                   let () = output_string o_channel cargo in
                   flush o_channel) keys;
-      let cargo = self#encode_packet Noop "" "" "" 0 0L in
+      let cargo = self#encode_packet opNoop "" "" "" 0 0L in
       begin
          (* self#printhex cargo; *)
          output_string o_channel cargo;
       and _ = set_int64 buf initial_value
       and _ = set_i32 buf expiration in
       let extras = Buffer.contents buf in
-      let cargo = self#encode_packet Increment key extras "" 0 0L in
+      let cargo = self#encode_packet opIncrement key extras "" 0 0L in
       begin
          (* self#printhex cargo; *)
          output_string o_channel cargo;
       and _ = set_int64 buf initial_value
       and _ = set_i32 buf expiration in
       let extras = Buffer.contents buf in
-      let cargo = self#encode_packet IncrementQ key extras "" 0 0L in
+      let cargo = self#encode_packet opIncrementQ key extras "" 0 0L in
       begin
          (* self#printhex cargo; *)
          output_string o_channel cargo;
       and _ = set_int64 buf initial_value
       and _ = set_i32 buf expiration in
       let extras = Buffer.contents buf in
-      let cargo = self#encode_packet Decrement key extras "" 0 0L in
+      let cargo = self#encode_packet opDecrement key extras "" 0 0L in
       begin
          (* self#printhex cargo; *)
          output_string o_channel cargo;
       and _ = set_int64 buf initial_value
       and _ = set_i32 buf expiration in
       let extras = Buffer.contents buf in
-      let cargo = self#encode_packet DecrementQ key extras "" 0 0L in
+      let cargo = self#encode_packet opDecrementQ key extras "" 0 0L in
       begin
          (* self#printhex cargo; *)
          output_string o_channel cargo;
       @return (status, key, value)  Key and value -- strings (must be ignored),  Status is response_status type 
   *) 
    method quit =
-      let cargo = self#encode_packet Quit "" "" "" 0 0L in
+      let cargo = self#encode_packet opQuit "" "" "" 0 0L in
       begin
          (* self#printhex cargo; *)
          output_string o_channel cargo;
 
   (** Close connection, dont wait for answer *) 
    method quitq =
-      let cargo = self#encode_packet QuitQ "" "" "" 0 0L in
+      let cargo = self#encode_packet opQuitQ "" "" "" 0 0L in
       begin
          (* self#printhex cargo; *)
          output_string o_channel cargo;
       let buf = Buffer.create 4 in
       let _ = set_i32 buf expiration in
       let extras = Buffer.contents buf in
-      let cargo = self#encode_packet Flush "" extras "" 0 0L in
+      let cargo = self#encode_packet opFlush "" extras "" 0 0L in
       begin
          (* self#printhex cargo; *)
          output_string o_channel cargo;
       let buf = Buffer.create 4 in
       let _ = set_i32 buf expiration in
       let extras = Buffer.contents buf in
-      let cargo = self#encode_packet FlushQ "" extras "" 0 0L in
+      let cargo = self#encode_packet opFlushQ "" extras "" 0 0L in
       begin
          (* self#printhex cargo; *)
          output_string o_channel cargo;
       end
    
    method noop =
-      let cargo = self#encode_packet Noop "" "" "" 0 0L in
+      let cargo = self#encode_packet opNoop "" "" "" 0 0L in
       begin
          (* self#printhex cargo; *)
          output_string o_channel cargo;
    
    (** Return version of memcache server *)
    method version =
-      let cargo = self#encode_packet Version "" "" "" 0 0L in
+      let cargo = self#encode_packet opVersion "" "" "" 0 0L in
       begin
          (* self#printhex cargo; *)
          output_string o_channel cargo;
       end
    
    method append key v =
-      let cargo = self#encode_packet Append key "" v 0 0L in
+      let cargo = self#encode_packet opAppend key "" v 0 0L in
       begin
          (* self#printhex cargo; *)
          output_string o_channel cargo;
       end
    
    method appendq key v =
-      let cargo = self#encode_packet AppendQ key "" v 0 0L in
+      let cargo = self#encode_packet opAppendQ key "" v 0 0L in
       begin
          (* self#printhex cargo; *)
          output_string o_channel cargo;
       end
    
    method prepend key v =
-      let cargo = self#encode_packet Prepend key "" v 0 0L in
+      let cargo = self#encode_packet opPrepend key "" v 0 0L in
       begin
          (* self#printhex cargo; *)
          output_string o_channel cargo;
       end
    
    method prependq key v =
-      let cargo = self#encode_packet PrependQ key "" v 0 0L in
+      let cargo = self#encode_packet opPrependQ key "" v 0 0L in
       begin
          (* self#printhex cargo; *)
          output_string o_channel cargo;
       end
    
    method stat key =
-      let cargo = self#encode_packet Stat key "" "" 0 0L in
+      let cargo = self#encode_packet opStat key "" "" 0 0L in
       begin
          (* self#printhex cargo; *)
          output_string o_channel cargo;
       end
    
    method stat_all =
-      let cargo = self#encode_packet Stat "" "" "" 0 0L in
+      let cargo = self#encode_packet opStat "" "" "" 0 0L in
       begin
          (* self#printhex cargo; *)
          output_string o_channel cargo;
 end;;
 
 
-
 (* Example *)
 (*
 let print_result (status, key, value) =
-type operation =
-    Get
-  | Set
-  | Add
-  | Replace
-  | Delete
-  | Increment
-  | Decrement
-  | Quit
-  | Flush
-  | GetQ
-  | Noop
-  | Version
-  | GetK
-  | GetKQ
-  | Append
-  | Prepend
-  | Stat
-  | SetQ
-  | AddQ
-  | ReplaceQ
-  | DeleteQ
-  | IncrementQ
-  | DecrementQ
-  | QuitQ
-  | FlushQ
-  | AppendQ
-  | PrependQ
 type magic = Request | Response
 type response_status =
     MC_No_error
     method delete : string -> response_status * string * string
     method deleteq : string -> unit
     method encode_packet :
-      operation -> string -> string -> string -> int -> int64 -> string
+      int -> string -> string -> string -> int -> int64 -> string
     method flush : int -> response_status * string * string
     method flushq : int -> unit
     method magic_code_decode : int -> magic
     method magic_code_encode : magic -> int
     method multiget : string list -> (response_status * string * string) list
     method noop : response_status * string * string
-    method operation_encode : operation -> int
     method prepend : string -> string -> response_status * string * string
     method prependq : string -> string -> unit
     method quit : response_status * string * string
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.