You can subscribe to this list here.
2003 |
Jan
|
Feb
(27) |
Mar
(132) |
Apr
(63) |
May
(100) |
Jun
(22) |
Jul
(7) |
Aug
(3) |
Sep
(14) |
Oct
(24) |
Nov
(49) |
Dec
(17) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2004 |
Jan
(13) |
Feb
(43) |
Mar
(67) |
Apr
(21) |
May
(24) |
Jun
(3) |
Jul
(15) |
Aug
|
Sep
(1) |
Oct
(40) |
Nov
(2) |
Dec
(94) |
2005 |
Jan
(5) |
Feb
(36) |
Mar
(10) |
Apr
(8) |
May
(35) |
Jun
(13) |
Jul
(55) |
Aug
(82) |
Sep
(59) |
Oct
(20) |
Nov
(55) |
Dec
(15) |
2006 |
Jan
(40) |
Feb
(25) |
Mar
(42) |
Apr
(1) |
May
(12) |
Jun
(3) |
Jul
(2) |
Aug
(23) |
Sep
(33) |
Oct
(4) |
Nov
(5) |
Dec
(22) |
2007 |
Jan
(10) |
Feb
|
Mar
(4) |
Apr
(3) |
May
(8) |
Jun
(4) |
Jul
|
Aug
(3) |
Sep
(12) |
Oct
(9) |
Nov
(1) |
Dec
|
2008 |
Jan
|
Feb
(5) |
Mar
(4) |
Apr
|
May
(4) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(7) |
Nov
|
Dec
|
2009 |
Jan
(8) |
Feb
(1) |
Mar
|
Apr
|
May
|
Jun
|
Jul
(11) |
Aug
|
Sep
(3) |
Oct
|
Nov
|
Dec
|
2011 |
Jan
(7) |
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: Christian S. <no...@us...> - 2007-11-15 23:00:28
|
Update of /cvsroot/jungerl/jungerl/lib/pgsql/src In directory sc8-pr-cvs6.sourceforge.net:/tmp/cvs-serv17569 Modified Files: pgsql_util.erl Log Message: Another oid (the 'void' oid) to atom mapping added. Daniel Caune <dan...@ub...> wrote: > Hi, > > I did a small patch on the file pgsql_util.erl to support PostgreSQL > function that returns void. I'm contacting Christian Sunesson to ask > him whether he would like to integrate this patch in CVS. Index: pgsql_util.erl =================================================================== RCS file: /cvsroot/jungerl/jungerl/lib/pgsql/src/pgsql_util.erl,v retrieving revision 1.6 retrieving revision 1.7 diff -u -d -r1.6 -r1.7 --- pgsql_util.erl 13 Sep 2007 22:00:55 -0000 1.6 +++ pgsql_util.erl 15 Nov 2007 23:00:17 -0000 1.7 @@ -233,6 +233,7 @@ 1560 -> bit; 1562 -> varbit; 1700 -> numeric; + 2278 -> void; Oid -> throw({unknown_oid, Oid}) end. |
From: Chandru <cha...@us...> - 2007-10-19 12:50:01
|
Update of /cvsroot/jungerl/jungerl/lib/ibrowse In directory sc8-pr-cvs6.sourceforge.net:/tmp/cvs-serv14705 Modified Files: vsn.mk Log Message: Fix for case when chunk trailer spans two TCP packets provided by Matthew Reilly. Index: vsn.mk =================================================================== RCS file: /cvsroot/jungerl/jungerl/lib/ibrowse/vsn.mk,v retrieving revision 1.9 retrieving revision 1.10 diff -u -d -r1.9 -r1.10 --- vsn.mk 9 Oct 2007 00:02:30 -0000 1.9 +++ vsn.mk 19 Oct 2007 12:49:03 -0000 1.10 @@ -1,2 +1,2 @@ -IBROWSE_VSN = 1.2.8 +IBROWSE_VSN = 1.2.9 |
From: Chandru <cha...@us...> - 2007-10-19 12:43:57
|
Update of /cvsroot/jungerl/jungerl/lib/ibrowse In directory sc8-pr-cvs6.sourceforge.net:/tmp/cvs-serv12666 Modified Files: README Log Message: Fix for case when chunk trailer spans two TCP packets provided by Matthew Reilly. Index: README =================================================================== RCS file: /cvsroot/jungerl/jungerl/lib/ibrowse/README,v retrieving revision 1.11 retrieving revision 1.12 diff -u -d -r1.11 -r1.12 --- README 9 Oct 2007 00:02:30 -0000 1.11 +++ README 19 Oct 2007 12:43:48 -0000 1.12 @@ -22,6 +22,11 @@ CONTRIBUTIONS & CHANGE HISTORY ============================== +17-10-2007 - Matthew Reilly (matthew dot reilly _at_ sipphone dot com) + sent a bug report and a fix. If the chunk trailer spans two TCP + packets, then ibrowse fails to recognise that the chunked transfer + has ended. + 29-08-2007 - Bug report by Peter Kristensen(ptx _at_ daimi dot au dot dk). ibrowse crashes when the webserver returns just the Status line and nothing else. |
From: Chandru <cha...@us...> - 2007-10-19 12:43:56
|
Update of /cvsroot/jungerl/jungerl/lib/ibrowse/src In directory sc8-pr-cvs6.sourceforge.net:/tmp/cvs-serv12666/src Modified Files: ibrowse_http_client.erl Log Message: Fix for case when chunk trailer spans two TCP packets provided by Matthew Reilly. Index: ibrowse_http_client.erl =================================================================== RCS file: /cvsroot/jungerl/jungerl/lib/ibrowse/src/ibrowse_http_client.erl,v retrieving revision 1.13 retrieving revision 1.14 diff -u -d -r1.13 -r1.14 --- ibrowse_http_client.erl 9 Oct 2007 00:02:30 -0000 1.13 +++ ibrowse_http_client.erl 19 Oct 2007 12:43:48 -0000 1.14 @@ -761,7 +761,7 @@ chunk_size=ChunkSize}) end; {no, Data_1} -> - State#state{reply_buffer=Data_1} + State#state{reply_buffer=Data_1, rep_buf_size=length(Data_1)} end; %% This clause is there to remove the CRLF between two chunks @@ -778,7 +778,10 @@ %% %% Do we have to preserve the chunk encoding when streaming? %% - State_1 = State#state{chunk_size=chunk_start, deleted_crlf=true}, + State_1 = State#state{chunk_size=chunk_start, + rep_buf_size=0, + reply_buffer=[], + deleted_crlf=true}, State_2 = case StreamTo of undefined -> State_1#state{chunks = [Buf | Chunks]}; @@ -788,7 +791,7 @@ end, parse_11_response(NextChunk, State_2); {no, Data_1} -> - State#state{reply_buffer=Data_1} + State#state{reply_buffer=Data_1, rep_buf_size=length(Data_1)} end; %% This clause deals with the end of a chunked transfer @@ -815,7 +818,7 @@ State_1 = handle_response(CurReq, State#state{reqs=Reqs_1}), parse_response(Rem, reset_state(State_1)); {no, Rem} -> - State#state{reply_buffer=Rem, rep_buf_size=length(Rem), chunk_size=tbd} + State#state{reply_buffer=Rem, rep_buf_size=length(Rem), deleted_crlf=false} end; %% This clause extracts a chunk, given the size. |
From: Chandru <cha...@us...> - 2007-10-09 00:02:54
|
Update of /cvsroot/jungerl/jungerl/lib/ibrowse In directory sc8-pr-cvs6.sourceforge.net:/tmp/cvs-serv20900 Modified Files: README vsn.mk Log Message: Bug fix for the case when the webserver returns only a Status line and no headers. Thanks to Peter Kristensen Index: README =================================================================== RCS file: /cvsroot/jungerl/jungerl/lib/ibrowse/README,v retrieving revision 1.10 retrieving revision 1.11 diff -u -d -r1.10 -r1.11 --- README 28 Jun 2007 22:29:00 -0000 1.10 +++ README 9 Oct 2007 00:02:30 -0000 1.11 @@ -22,6 +22,10 @@ CONTRIBUTIONS & CHANGE HISTORY ============================== +29-08-2007 - Bug report by Peter Kristensen(ptx _at_ daimi dot au dot dk). + ibrowse crashes when the webserver returns just the Status line + and nothing else. + 28-06-2007 - Added host_header option to enable connection to secure sites via stunnel Index: vsn.mk =================================================================== RCS file: /cvsroot/jungerl/jungerl/lib/ibrowse/vsn.mk,v retrieving revision 1.8 retrieving revision 1.9 diff -u -d -r1.8 -r1.9 --- vsn.mk 28 Jun 2007 22:29:01 -0000 1.8 +++ vsn.mk 9 Oct 2007 00:02:30 -0000 1.9 @@ -1,2 +1,2 @@ -IBROWSE_VSN = 1.2.7 +IBROWSE_VSN = 1.2.8 |
From: Chandru <cha...@us...> - 2007-10-09 00:02:54
|
Update of /cvsroot/jungerl/jungerl/lib/ibrowse/src In directory sc8-pr-cvs6.sourceforge.net:/tmp/cvs-serv20900/src Modified Files: ibrowse_http_client.erl Log Message: Bug fix for the case when the webserver returns only a Status line and no headers. Thanks to Peter Kristensen Index: ibrowse_http_client.erl =================================================================== RCS file: /cvsroot/jungerl/jungerl/lib/ibrowse/src/ibrowse_http_client.erl,v retrieving revision 1.12 retrieving revision 1.13 diff -u -d -r1.12 -r1.13 --- ibrowse_http_client.erl 28 Jun 2007 22:29:01 -0000 1.12 +++ ibrowse_http_client.erl 9 Oct 2007 00:02:30 -0000 1.13 @@ -984,7 +984,7 @@ parse_header([], _) -> invalid. -scan_header([$\n|T], [$\r,$\n,$\r|L]) -> {yes, lists:reverse(L), T}; +scan_header([$\n|T], [$\r,$\n,$\r|L]) -> {yes, lists:reverse([$\n,$\r| L]), T}; scan_header([H|T], L) -> scan_header(T, [H|L]); scan_header([], L) -> {no, L}. |
From: David N. W. <da...@us...> - 2007-10-02 14:39:19
|
Update of /cvsroot/jungerl/jungerl/lib/memcached/src In directory sc8-pr-cvs6.sourceforge.net:/tmp/cvs-serv11398/src Modified Files: memcached.erl Log Message: * src/memcached.erl: Some more minor tweaks. Index: memcached.erl =================================================================== RCS file: /cvsroot/jungerl/jungerl/lib/memcached/src/memcached.erl,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -r1.3 -r1.4 --- memcached.erl 2 Oct 2007 14:23:10 -0000 1.3 +++ memcached.erl 2 Oct 2007 14:39:15 -0000 1.4 @@ -222,7 +222,7 @@ true -> <<Bytes:Len/binary>> = Combined, %% Read anything left. - {ok, <<"\r\n", Rest/binary>>} = gen_tcp:recv(Sock, 0) + {ok, <<Rest/binary>>} = gen_tcp:recv(Sock, 0) end, {Bytes, Rest}. @@ -234,7 +234,8 @@ parse_responses(Sock, <<"VALUE ", Data/binary>>, Acc) -> {ok, [_, _, Len], More} = io_lib:fread("~s ~u ~u\r\n", binary_to_list(Data)), if - length(More) < Len -> + %% 5 is size(<<"\r\nEND\r\n">>) + length(More) < Len + 7 -> %% If we didn't read all the data, fetch the rest. {Bytes, Rest} = fetchmore(Sock, Len, list_to_binary(More)); true -> |
From: David N. W. <da...@us...> - 2007-10-02 14:23:14
|
Update of /cvsroot/jungerl/jungerl/lib/memcached/tests In directory sc8-pr-cvs6.sourceforge.net:/tmp/cvs-serv3888/tests Modified Files: memcached_tests.erl Log Message: * tests/memcached_tests.erl (getbig_test): Added tests to check for big data. * src/memcached.erl (fetchmore): Added a function to deal with large chunks of data coming back from the server. Index: memcached_tests.erl =================================================================== RCS file: /cvsroot/jungerl/jungerl/lib/memcached/tests/memcached_tests.erl,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- memcached_tests.erl 24 Sep 2007 11:15:19 -0000 1.2 +++ memcached_tests.erl 2 Oct 2007 14:23:11 -0000 1.3 @@ -9,6 +9,11 @@ start() -> test(). +%% Generate lots of data to utilize for tests. +generate_data() -> + lists:flatten([io_lib:format("~p", [X]) || + X <- lists:seq(1, 1000)]). + get_server_pid() -> {ok, Pid} = memcached:start_link('localhost', 11211), Pid. @@ -47,5 +52,12 @@ deletefail_test() -> not_found = memcached:mcdelete(get_server_pid(), doesntexist). +setbig_test() -> + memcached:mcset(get_server_pid(), big, + generate_data()). +getbig_test() -> + Data = generate_data(), + {ok, Data} = memcached:mcget(get_server_pid(), big). + quit_test() -> memcached:mcquit(get_server_pid()). |
From: David N. W. <da...@us...> - 2007-10-02 14:23:14
|
Update of /cvsroot/jungerl/jungerl/lib/memcached In directory sc8-pr-cvs6.sourceforge.net:/tmp/cvs-serv3888 Added Files: ChangeLog Log Message: * tests/memcached_tests.erl (getbig_test): Added tests to check for big data. * src/memcached.erl (fetchmore): Added a function to deal with large chunks of data coming back from the server. --- NEW FILE: ChangeLog --- 2007-10-02 David N. Welton <da...@de...> * tests/memcached_tests.erl (getbig_test): Added tests to check for big data. 2007-10-02 David N. Welton <da...@ef...> * src/memcached.erl (fetchmore): Added a function to deal with large chunks of data coming back from the server. |
From: David N. W. <da...@us...> - 2007-10-02 14:23:14
|
Update of /cvsroot/jungerl/jungerl/lib/memcached/src In directory sc8-pr-cvs6.sourceforge.net:/tmp/cvs-serv3888/src Modified Files: memcached.erl Log Message: * tests/memcached_tests.erl (getbig_test): Added tests to check for big data. * src/memcached.erl (fetchmore): Added a function to deal with large chunks of data coming back from the server. Index: memcached.erl =================================================================== RCS file: /cvsroot/jungerl/jungerl/lib/memcached/src/memcached.erl,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- memcached.erl 24 Sep 2007 11:15:19 -0000 1.2 +++ memcached.erl 2 Oct 2007 14:23:10 -0000 1.3 @@ -211,24 +211,43 @@ to_list(Key) when is_list(Key) -> Key. +%% parse_response helper to fetch data if there's a lot of it. +fetchmore(Sock, Len, More) -> + %% Read what we need to grab the data. + {ok, <<Data/binary>>} = gen_tcp:recv(Sock, Len - size(More)), + Combined = <<More/binary, Data/binary>>, + if + size(Combined) < Len -> + {Bytes, Rest} = fetchmore(Sock, Len, Combined); + true -> + <<Bytes:Len/binary>> = Combined, + %% Read anything left. + {ok, <<"\r\n", Rest/binary>>} = gen_tcp:recv(Sock, 0) + end, + {Bytes, Rest}. + %% Parse the get response. -parse_responses(<<"END\r\n", _/binary>>, Acc) -> +parse_responses(_, <<"END\r\n", _/binary>>, Acc) -> Acc; -parse_responses(<<"\r\n", Data/binary>>, Acc) -> - parse_responses(Data, Acc); -parse_responses(<<"VALUE ", Data/binary>>, Acc) -> +parse_responses(Sock, <<"\r\n", Data/binary>>, Acc) -> + parse_responses(Sock, Data, Acc); +parse_responses(Sock, <<"VALUE ", Data/binary>>, Acc) -> {ok, [_, _, Len], More} = io_lib:fread("~s ~u ~u\r\n", binary_to_list(Data)), - <<Bytes:Len/binary, Rest/binary>> = list_to_binary(More), - parse_responses(Rest, Acc ++ [binary_to_term(Bytes)]). + if + length(More) < Len -> + %% If we didn't read all the data, fetch the rest. + {Bytes, Rest} = fetchmore(Sock, Len, list_to_binary(More)); + true -> + <<Bytes:Len/binary, Rest/binary>> = list_to_binary(More) + end, + parse_responses(Sock, Rest, Acc ++ [binary_to_term(Bytes)]). %% Send get and handle the response. process_get(Sock, Keys) -> - io:format("Keys ~p ~n", [Keys]), KeyList = [to_list(X) || X <- Keys], - io:format("CHECK ~p ~n", [KeyList]), ok = gen_tcp:send(Sock, list_to_binary(["get ", string_join(KeyList), "\r\n"])), {ok, <<Data/binary>>} = gen_tcp:recv(Sock, 0), - {ok, parse_responses(Data, [])}. + {ok, parse_responses(Sock, Data, [])}. %% Set set and handle the response. process_set(Sock, Operation, Key, Flags, Expire, Data) -> |
From: David N. W. <da...@us...> - 2007-09-24 11:15:24
|
Update of /cvsroot/jungerl/jungerl/lib/memcached/src In directory sc8-pr-cvs6.sourceforge.net:/tmp/cvs-serv9978/src Modified Files: memcached.erl Log Message: * Makefile: Made 'test' target work a bit better. * src/memcached.erl: Added some commands, refactored slightly, changed API for single key get requests to not return a list of items. * tests/memcached_tests.erl: Added tests for new commands. Index: memcached.erl =================================================================== RCS file: /cvsroot/jungerl/jungerl/lib/memcached/src/memcached.erl,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- memcached.erl 21 Sep 2007 22:59:04 -0000 1.1 +++ memcached.erl 24 Sep 2007 11:15:19 -0000 1.2 @@ -11,7 +11,7 @@ -behaviour(gen_server). %% API --export([start_link/2, mcset/3, mcset/5, mcget/2, mcquit/1]). +-export([start_link/2, mcset/3, mcset/5, mcget/2, mcdelete/3, mcdelete/2, mcquit/1]). %% gen_server callbacks -export([init/1, handle_call/3, handle_cast/2, handle_info/2, @@ -36,40 +36,92 @@ %%-------------------------------------------------------------------- mcset(Pid, Key, Bytes) -> - gen_server:call(Pid, {set, Key, Bytes}). + gen_server:call(Pid, {set, set, Key, 0, 0, Bytes}). %%-------------------------------------------------------------------- %% Function: mcset(Pid, Key, Flags, Expire, Bytes) -> %% -%% Description: Assocates Bytes with Key, with flags, and a possible +%% Description: Associates Bytes with Key, with flags, and a possible %% expiration date. %%-------------------------------------------------------------------- mcset(Pid, Key, Flags, Expire, Bytes) -> - gen_server:call(Pid, {set, Key, Flags, Expire, Bytes}). + gen_server:call(Pid, {set, set, Key, Flags, Expire, Bytes}). %%-------------------------------------------------------------------- -%% Function: mcget(Pid, Key) -> +%% Function: mcadd(Pid, Key, Bytes) -> +%% +%% Description: Associates Bytes with Key, but only if the server +%% doesn't already have data associated with Key. +%% +%%-------------------------------------------------------------------- + +mcadd(Pid, Key, Bytes) -> + gen_server:call(Pid, {add, add, Key, 0, 0, Bytes}). + +mcadd(Pid, Key, Flags, Expire, Bytes) -> + gen_server:call(Pid, {add, add, Key, Flags, Expire, Bytes}). + +%%-------------------------------------------------------------------- +%% Function: mcreplace(Pid, Key, Bytes) -> +%% +%% Description: Associates Bytes with Key, but only if the server +%% already has data associated with Key. +%% +%%-------------------------------------------------------------------- + +mcreplace(Pid, Key, Bytes) -> + gen_server:call(Pid, {replace, replace, Key, 0, 0, Bytes}). + +mcreplace(Pid, Key, Flags, Expire, Bytes) -> + gen_server:call(Pid, {replace, replace, Key, Flags, Expire, Bytes}). + + +%%-------------------------------------------------------------------- +%% Function: mcget(Pid, Key) -> {ok, Value} %% %% Description: Returns Bytes associated with Key. %%-------------------------------------------------------------------- mcget(Pid, Key) when is_atom(Key) -> - io:format("Keys2 ~p ~n", [Key]), - gen_server:call(Pid, {get, [Key]}); + {ok, [Res]} = gen_server:call(Pid, {get, [Key]}), + {ok, Res}; + +%%-------------------------------------------------------------------- +%% Function: mcget(Pid, [key1, key2, ...]) -> {ok, [Values]} +%% +%% Description: Returns Bytes associated with Key. +%%-------------------------------------------------------------------- + %% This could be a list like [foo, bar] or ["foo", "bar"] mcget(Pid, [Head|Tail]) when is_atom(Head) -> Keys = [Head] ++ Tail, - io:format("Keys1 ~p ~n", [Keys]), gen_server:call(Pid, {get, Keys}); mcget(Pid, [Head|Tail]) when is_list(Head) -> Keys = [Head] ++ Tail, - io:format("Keys1 ~p ~n", [Keys]), gen_server:call(Pid, {get, Keys}); mcget(Pid, Key) -> gen_server:call(Pid, {get, [Key]}). %%-------------------------------------------------------------------- +%% Function: mcdelete(Pid, Key, Time) -> +%% +%% Description: Delete a key in memcached. +%%-------------------------------------------------------------------- +mcdelete(Pid, Key, Time) -> + gen_server:call(Pid, {delete, Key, Time}). + +%%-------------------------------------------------------------------- +%% Function: mcdelete(Pid, Key) -> +%% +%% Description: Delete a key in memcached - use default value of 0 for +%% time. +%% ------------------------------------------------------------------- + +mcdelete(Pid, Key) -> + gen_server:call(Pid, {delete, Key, 0}). + +%%-------------------------------------------------------------------- %% Function: mcquit(Pid) -> %% %% Description: Terminate the connection. @@ -104,16 +156,13 @@ handle_call({get, Keys}, _From, #state{sock = Sock} = S) -> Reply = process_get(Sock, Keys), {reply, Reply, S#state{sock = Sock}}; -handle_call({set, Key, Bytes}, _From, #state{sock = Sock} = S) -> - Reply = process_set(Sock, Key, 0, 0, Bytes), - {reply, Reply, S#state{sock = Sock}}; -handle_call({set, Key, Flags, Expire, Bytes}, _From, #state{sock = Sock} = S) -> - Reply = process_set(Sock, Key, Flags, Expire, Bytes), +handle_call({set, Operation, Key, Flags, Expire, Bytes}, _From, #state{sock = Sock} = S) -> + Reply = process_set(Sock, Operation, Key, Flags, Expire, Bytes), {reply, Reply, S#state{sock = Sock}}; -handle_call({delete, Key}, _From, #state{sock = Sock} = S) -> - Reply = ok, +handle_call({delete, Key, Time}, _From, #state{sock = Sock} = S) -> + Reply = process_delete(Sock, Key, Time), {reply, Reply, #state{sock = Sock} = S}; -handle_call(quit, _From, #state{sock = Sock} = S) -> +handle_call(quit, _From, #state{sock = Sock} = _) -> gen_tcp:close(Sock), {reply, ok, {}}. @@ -168,7 +217,7 @@ parse_responses(<<"\r\n", Data/binary>>, Acc) -> parse_responses(Data, Acc); parse_responses(<<"VALUE ", Data/binary>>, Acc) -> - {ok, [Key, Flags, Len], More} = io_lib:fread("~s ~u ~u\r\n", binary_to_list(Data)), + {ok, [_, _, Len], More} = io_lib:fread("~s ~u ~u\r\n", binary_to_list(Data)), <<Bytes:Len/binary, Rest/binary>> = list_to_binary(More), parse_responses(Rest, Acc ++ [binary_to_term(Bytes)]). @@ -182,12 +231,13 @@ {ok, parse_responses(Data, [])}. %% Set set and handle the response. -process_set(Sock, Key, Flags, Expire, Data) -> +process_set(Sock, Operation, Key, Flags, Expire, Data) -> + Op = to_list(Operation), K = to_list(Key), Bytes = term_to_binary(Data), Len = size(Bytes), L = list_to_binary( - io_lib:format("set ~s ~p ~p ~p", [K, Flags, Expire, Len])), + io_lib:format("~s ~s ~p ~p ~p", [Op, K, Flags, Expire, Len])), Line = <<L/binary, "\r\n">>, ok = gen_tcp:send(Sock, Line), ok = gen_tcp:send(Sock, <<Bytes/binary, "\r\n">>), @@ -199,6 +249,19 @@ not_stored end. +process_delete(Sock, Key, Time) -> + Line = list_to_binary( + io_lib:format("delete ~s ~p\r\n", [to_list(Key), Time])), + ok = gen_tcp:send(Sock, Line), + {ok, Response} = gen_tcp:recv(Sock, 0), + case Response of + <<"DELETED\r\n">> -> + ok; + <<"NOT_FOUND\r\n">> -> + not_found + end. + + %% When oh when will we see this in Erlang proper. string_join(Items) -> string_join(Items, " "). |
From: David N. W. <da...@us...> - 2007-09-24 11:15:24
|
Update of /cvsroot/jungerl/jungerl/lib/memcached/tests In directory sc8-pr-cvs6.sourceforge.net:/tmp/cvs-serv9978/tests Modified Files: memcached_tests.erl Log Message: * Makefile: Made 'test' target work a bit better. * src/memcached.erl: Added some commands, refactored slightly, changed API for single key get requests to not return a list of items. * tests/memcached_tests.erl: Added tests for new commands. Index: memcached_tests.erl =================================================================== RCS file: /cvsroot/jungerl/jungerl/lib/memcached/tests/memcached_tests.erl,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- memcached_tests.erl 21 Sep 2007 22:59:05 -0000 1.1 +++ memcached_tests.erl 24 Sep 2007 11:15:19 -0000 1.2 @@ -23,7 +23,7 @@ memcached:mcset(get_server_pid(), pi, 3.14156). get_test() -> - {ok, [1]} = memcached:mcget(get_server_pid(), foo). + {ok, 1} = memcached:mcget(get_server_pid(), foo). get2_test() -> {ok, [1, "bar"]} = memcached:mcget(get_server_pid(), [foo, bar]). @@ -35,7 +35,17 @@ {ok, [1, "bar"]} = memcached:mcget(get_server_pid(), ["foo", "bar"]). getfloat_test() -> - {ok, [3.14156]} = memcached:mcget(get_server_pid(), pi). + {ok, 3.14156} = memcached:mcget(get_server_pid(), pi). + +delete_test() -> + Data = "To be, or not to be", + memcached:mcset(get_server_pid(), todelete, Data), + {ok, Res1} = memcached:mcget(get_server_pid(), todelete), + Res2 = memcached:mcdelete(get_server_pid(), todelete), + {Data, ok} = {Res1, Res2}. + +deletefail_test() -> + not_found = memcached:mcdelete(get_server_pid(), doesntexist). quit_test() -> memcached:mcquit(get_server_pid()). |
From: David N. W. <da...@us...> - 2007-09-24 11:15:24
|
Update of /cvsroot/jungerl/jungerl/lib/memcached In directory sc8-pr-cvs6.sourceforge.net:/tmp/cvs-serv9978 Modified Files: Makefile Log Message: * Makefile: Made 'test' target work a bit better. * src/memcached.erl: Added some commands, refactored slightly, changed API for single key get requests to not return a list of items. * tests/memcached_tests.erl: Added tests for new commands. Index: Makefile =================================================================== RCS file: /cvsroot/jungerl/jungerl/lib/memcached/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- Makefile 21 Sep 2007 22:59:04 -0000 1.1 +++ Makefile 24 Sep 2007 11:15:19 -0000 1.2 @@ -1,9 +1,9 @@ include ../../support/subdir.mk tests/memcached_tests.beam: tests/memcached_tests.erl - cp ./ebin/memcached.beam tests/ /usr/bin/erlc -W +debug_info -o tests/ tests/memcached_tests.erl # Run the test suite. -test: tests/memcached_tests.beam - erl -noshell -pa tests/ -run memcached_tests \ No newline at end of file +test: all tests/memcached_tests.beam + cp ./ebin/memcached.beam tests/ + erl -noshell -pa tests/ -run memcached_tests -s init stop \ No newline at end of file |
From: David N. W. <da...@us...> - 2007-09-21 23:02:57
|
Update of /cvsroot/jungerl/jungerl/lib/memcached/ebin In directory sc8-pr-cvs6.sourceforge.net:/tmp/cvs-serv21686/ebin Log Message: Directory /cvsroot/jungerl/jungerl/lib/memcached/ebin added to the repository |
From: David N. W. <da...@us...> - 2007-09-21 22:59:09
|
Update of /cvsroot/jungerl/jungerl/lib/memcached/src In directory sc8-pr-cvs6.sourceforge.net:/tmp/cvs-serv20043/src Added Files: Makefile memcached.erl Log Message: * Initial commit. Not a stable release by any means. --- NEW FILE: memcached.erl --- %%%------------------------------------------------------------------- %%% File : memcached.erl %%% Author : David N. Welton <da...@ef...> %%% Description : memcached client for Erlang %%% Protocol described here: http://cvs.danga.com/browse.cgi/wcmtools/memcached/doc/protocol.txt?rev=HEAD %%% %%% Created : 20 Sep 2007 by David N. Welton <da...@ef...> %%%------------------------------------------------------------------- -module(memcached). -behaviour(gen_server). %% API -export([start_link/2, mcset/3, mcset/5, mcget/2, mcquit/1]). %% gen_server callbacks -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). -record(state, {sock}). %%==================================================================== %% API %%==================================================================== %%-------------------------------------------------------------------- %% Function: start_link() -> {ok,Pid} | ignore | {error,Error} %% Description: Starts the server %%-------------------------------------------------------------------- start_link(Host, Port) -> gen_server:start_link(?MODULE, [Host, Port], []). %%-------------------------------------------------------------------- %% Function: mcset(Pid, Key, Bytes) -> %% %% Description: Associates Bytes with Key in memcached. %%-------------------------------------------------------------------- mcset(Pid, Key, Bytes) -> gen_server:call(Pid, {set, Key, Bytes}). %%-------------------------------------------------------------------- %% Function: mcset(Pid, Key, Flags, Expire, Bytes) -> %% %% Description: Assocates Bytes with Key, with flags, and a possible %% expiration date. %%-------------------------------------------------------------------- mcset(Pid, Key, Flags, Expire, Bytes) -> gen_server:call(Pid, {set, Key, Flags, Expire, Bytes}). %%-------------------------------------------------------------------- %% Function: mcget(Pid, Key) -> %% %% Description: Returns Bytes associated with Key. %%-------------------------------------------------------------------- mcget(Pid, Key) when is_atom(Key) -> io:format("Keys2 ~p ~n", [Key]), gen_server:call(Pid, {get, [Key]}); %% This could be a list like [foo, bar] or ["foo", "bar"] mcget(Pid, [Head|Tail]) when is_atom(Head) -> Keys = [Head] ++ Tail, io:format("Keys1 ~p ~n", [Keys]), gen_server:call(Pid, {get, Keys}); mcget(Pid, [Head|Tail]) when is_list(Head) -> Keys = [Head] ++ Tail, io:format("Keys1 ~p ~n", [Keys]), gen_server:call(Pid, {get, Keys}); mcget(Pid, Key) -> gen_server:call(Pid, {get, [Key]}). %%-------------------------------------------------------------------- %% Function: mcquit(Pid) -> %% %% Description: Terminate the connection. %%-------------------------------------------------------------------- mcquit(Pid) -> gen_server:call(Pid, quit). %%==================================================================== %% gen_server callbacks %%==================================================================== %%-------------------------------------------------------------------- %% Function: init(Args) -> {ok, State} | %% {ok, State, Timeout} | %% ignore | %% {stop, Reason} %% Description: Initiates the server %%-------------------------------------------------------------------- init([Host, Port]) -> {ok, Sock} = gen_tcp:connect(Host, Port, [binary, {active, false}]), {ok, #state{sock = Sock}}. %%-------------------------------------------------------------------- %% Function: %% handle_call(Request, From, State) -> {reply, Reply, State} | %% {reply, Reply, State, Timeout} | %% {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, Reply, State} | %% {stop, Reason, State} %% Description: Handling call messages %%-------------------------------------------------------------------- handle_call({get, Keys}, _From, #state{sock = Sock} = S) -> Reply = process_get(Sock, Keys), {reply, Reply, S#state{sock = Sock}}; handle_call({set, Key, Bytes}, _From, #state{sock = Sock} = S) -> Reply = process_set(Sock, Key, 0, 0, Bytes), {reply, Reply, S#state{sock = Sock}}; handle_call({set, Key, Flags, Expire, Bytes}, _From, #state{sock = Sock} = S) -> Reply = process_set(Sock, Key, Flags, Expire, Bytes), {reply, Reply, S#state{sock = Sock}}; handle_call({delete, Key}, _From, #state{sock = Sock} = S) -> Reply = ok, {reply, Reply, #state{sock = Sock} = S}; handle_call(quit, _From, #state{sock = Sock} = S) -> gen_tcp:close(Sock), {reply, ok, {}}. %%-------------------------------------------------------------------- %% Function: handle_cast(Msg, State) -> {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, State} %% Description: Handling cast messages %%-------------------------------------------------------------------- handle_cast(_Msg, State) -> {noreply, State}. %%-------------------------------------------------------------------- %% Function: handle_info(Info, State) -> {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, State} %% Description: Handling all non call/cast messages %%-------------------------------------------------------------------- handle_info(_Info, State) -> {noreply, State}. %%-------------------------------------------------------------------- %% Function: terminate(Reason, State) -> void() %% Description: This function is called by a gen_server when it is about to %% terminate. It should be the opposite of Module:init/1 and do any necessary %% cleaning up. When it returns, the gen_server terminates with Reason. %% The return value is ignored. %%-------------------------------------------------------------------- terminate(_Reason, _State) -> ok. %%-------------------------------------------------------------------- %% Func: code_change(OldVsn, State, Extra) -> {ok, NewState} %% Description: Convert process state when code is changed %%-------------------------------------------------------------------- code_change(_OldVsn, State, _Extra) -> {ok, State}. %%-------------------------------------------------------------------- %%% Internal functions %%-------------------------------------------------------------------- %% If it's an atom, transform it. If it's a string, leave it alone. to_list(Key) when is_atom(Key) -> atom_to_list(Key); to_list(Key) when is_list(Key) -> Key. %% Parse the get response. parse_responses(<<"END\r\n", _/binary>>, Acc) -> Acc; parse_responses(<<"\r\n", Data/binary>>, Acc) -> parse_responses(Data, Acc); parse_responses(<<"VALUE ", Data/binary>>, Acc) -> {ok, [Key, Flags, Len], More} = io_lib:fread("~s ~u ~u\r\n", binary_to_list(Data)), <<Bytes:Len/binary, Rest/binary>> = list_to_binary(More), parse_responses(Rest, Acc ++ [binary_to_term(Bytes)]). %% Send get and handle the response. process_get(Sock, Keys) -> io:format("Keys ~p ~n", [Keys]), KeyList = [to_list(X) || X <- Keys], io:format("CHECK ~p ~n", [KeyList]), ok = gen_tcp:send(Sock, list_to_binary(["get ", string_join(KeyList), "\r\n"])), {ok, <<Data/binary>>} = gen_tcp:recv(Sock, 0), {ok, parse_responses(Data, [])}. %% Set set and handle the response. process_set(Sock, Key, Flags, Expire, Data) -> K = to_list(Key), Bytes = term_to_binary(Data), Len = size(Bytes), L = list_to_binary( io_lib:format("set ~s ~p ~p ~p", [K, Flags, Expire, Len])), Line = <<L/binary, "\r\n">>, ok = gen_tcp:send(Sock, Line), ok = gen_tcp:send(Sock, <<Bytes/binary, "\r\n">>), {ok, Response} = gen_tcp:recv(Sock, 0), case Response of <<"STORED\r\n">> -> ok; <<"NOT_STORED\r\n">> -> not_stored end. %% When oh when will we see this in Erlang proper. string_join(Items) -> string_join(Items, " "). string_join(Items, Sep) -> lists:flatten(lists:reverse(string_join1(Items, Sep, []))). string_join1([Head | []], _Sep, Acc) -> [Head | Acc]; string_join1([Head | Tail], Sep, Acc) -> string_join1(Tail, Sep, [Sep, Head | Acc]). --- NEW FILE: Makefile --- include ../../../support/include.mk all: $(ERL_OBJECTS) clean: -rm $(ERL_OBJECTS) |
From: David N. W. <da...@us...> - 2007-09-21 22:59:08
|
Update of /cvsroot/jungerl/jungerl/lib/memcached In directory sc8-pr-cvs6.sourceforge.net:/tmp/cvs-serv20043 Added Files: Makefile Log Message: * Initial commit. Not a stable release by any means. --- NEW FILE: Makefile --- include ../../support/subdir.mk tests/memcached_tests.beam: tests/memcached_tests.erl cp ./ebin/memcached.beam tests/ /usr/bin/erlc -W +debug_info -o tests/ tests/memcached_tests.erl # Run the test suite. test: tests/memcached_tests.beam erl -noshell -pa tests/ -run memcached_tests |
From: David N. W. <da...@us...> - 2007-09-21 22:59:08
|
Update of /cvsroot/jungerl/jungerl/lib/memcached/tests In directory sc8-pr-cvs6.sourceforge.net:/tmp/cvs-serv20043/tests Added Files: memcached_tests.erl Log Message: * Initial commit. Not a stable release by any means. --- NEW FILE: memcached_tests.erl --- -module(memcached_tests). -export([start/0]). %% You need to make eunit available with something like this in your .erlang file: %% code:add_pathz("/home/davidw/downloads/eunit/ebin"). -include_lib("eunit/include/eunit.hrl"). start() -> test(). get_server_pid() -> {ok, Pid} = memcached:start_link('localhost', 11211), Pid. set_test() -> memcached:mcset(get_server_pid(), foo, 1). setstr_test() -> memcached:mcset(get_server_pid(), bar, "bar"). setfloat_test() -> memcached:mcset(get_server_pid(), pi, 3.14156). get_test() -> {ok, [1]} = memcached:mcget(get_server_pid(), foo). get2_test() -> {ok, [1, "bar"]} = memcached:mcget(get_server_pid(), [foo, bar]). get1str_test() -> {ok, [1]} = memcached:mcget(get_server_pid(), "foo"). get2str_test() -> {ok, [1, "bar"]} = memcached:mcget(get_server_pid(), ["foo", "bar"]). getfloat_test() -> {ok, [3.14156]} = memcached:mcget(get_server_pid(), pi). quit_test() -> memcached:mcquit(get_server_pid()). |
From: David N. W. <da...@us...> - 2007-09-21 22:53:18
|
Update of /cvsroot/jungerl/jungerl/lib/memcached/src In directory sc8-pr-cvs6.sourceforge.net:/tmp/cvs-serv18044/src Log Message: Directory /cvsroot/jungerl/jungerl/lib/memcached/src added to the repository |
From: David N. W. <da...@us...> - 2007-09-21 22:51:55
|
Update of /cvsroot/jungerl/jungerl/lib/memcached/tests In directory sc8-pr-cvs6.sourceforge.net:/tmp/cvs-serv17243/tests Log Message: Directory /cvsroot/jungerl/jungerl/lib/memcached/tests added to the repository |
From: David N. W. <da...@us...> - 2007-09-21 18:44:52
|
Update of /cvsroot/jungerl/jungerl/lib/memcached In directory sc8-pr-cvs6.sourceforge.net:/tmp/cvs-serv11638/memcached Log Message: Directory /cvsroot/jungerl/jungerl/lib/memcached added to the repository |
From: Christian S. <no...@us...> - 2007-09-13 22:01:02
|
Update of /cvsroot/jungerl/jungerl/lib/pgsql/src In directory sc8-pr-cvs6.sourceforge.net:/tmp/cvs-serv13797 Modified Files: pgsql_proto.erl pgsql_util.erl Log Message: Spreading changes into parametric queries too. Index: pgsql_util.erl =================================================================== RCS file: /cvsroot/jungerl/jungerl/lib/pgsql/src/pgsql_util.erl,v retrieving revision 1.5 retrieving revision 1.6 diff -u -d -r1.5 -r1.6 --- pgsql_util.erl 12 Sep 2007 23:55:48 -0000 1.5 +++ pgsql_util.erl 13 Sep 2007 22:00:55 -0000 1.6 @@ -265,14 +265,16 @@ <<Year:4/binary, $-, Month:2/binary, $-, Day:2/binary>> = Value, {b2i(Year), b2i(Month), b2i(Day)}; decode_col(#desc{format=text, type=time}, Value) -> - <<Hour:2/binary, $:, Minute:2/binary, $:, Second:2/binary>> = Value, + <<Hour:2/binary, $:, Minute:2/binary, $:, Second:2/binary,_/binary>> = Value, {b2i(Hour), b2i(Minute), b2i(Second)}; decode_col(#desc{format=text, type=timestamp}, Value) -> <<Year:4/binary, _, Month:2/binary, _, Day:2/binary, $\s, - Hour:2/binary, $:, Minute:2/binary, $:, Second:2/binary>> = Value, + Hour:2/binary, $:, Minute:2/binary, $:, Second:2/binary,_/binary>> = Value, {{b2i(Year), b2i(Month), b2i(Day)}, {b2i(Hour), b2i(Minute), b2i(Second)}}; decode_col(#desc{format=text}, Value) -> Value; +decode_col(#desc{format=binary}, Value) -> + Value; decode_col(_, Value) -> throw({unknown_format, Value}). Index: pgsql_proto.erl =================================================================== RCS file: /cvsroot/jungerl/jungerl/lib/pgsql/src/pgsql_proto.erl,v retrieving revision 1.6 retrieving revision 1.7 diff -u -d -r1.6 -r1.7 --- pgsql_proto.erl 12 Sep 2007 23:55:48 -0000 1.6 +++ pgsql_proto.erl 13 Sep 2007 22:00:55 -0000 1.7 @@ -231,7 +231,7 @@ %% simplistic version using the unnammed prepared statement and portal. {equery, Ref, Pid, {Query, Params}} -> ParseP = encode_message(parse, {"", Query, []}), - BindP = encode_message(bind, {"", "", Params, [binary]}), + BindP = encode_message(bind, {"", "", Params, [text]}), DescribeP = encode_message(describe, {portal, ""}), ExecuteP = encode_message(execute, {"", 0}), SyncP = encode_message(sync, []), @@ -239,12 +239,7 @@ {ok, Command, Desc, Status, Logs} = process_equery([]), - OidMap = get(oidmap), - NameTypes = lists:map(fun({Name, _Format, _ColNo, Oid, _, _, _}) -> - {Name, dict:fetch(Oid, OidMap)} - end, - Desc), - Pid ! {pgsql, Ref, {Command, Status, NameTypes, Logs}}, + Pid ! {pgsql, Ref, {Command, Status, Desc, Logs}}, idle(Sock, Pid); %% Prepare a statement, so it can be used for queries later on. {prepare, Ref, Pid, {Name, Query}} -> @@ -272,7 +267,7 @@ {execute, Ref, Pid, {Name, Params}} -> %%io:format("execute: ~p ~p ~n", [Name, Params]), begin % Issue first requests for the prepared statement. - BindP = encode_message(bind, {"", Name, Params, [binary]}), + BindP = encode_message(bind, {"", Name, Params, [text]}), DescribeP = encode_message(describe, {portal, ""}), ExecuteP = encode_message(execute, {"", 0}), FlushP = encode_message(flush, []), |
From: Christian S. <no...@us...> - 2007-09-12 23:55:55
|
Update of /cvsroot/jungerl/jungerl/lib/pgsql/src In directory sc8-pr-cvs6.sourceforge.net:/tmp/cvs-serv12861 Modified Files: pgsql_proto.erl pgsql_util.erl Log Message: A backwards incompatible change, but slow steps to a better library. * Supports null values * Convert types into sensible erlang terms (many, not all). Index: pgsql_util.erl =================================================================== RCS file: /cvsroot/jungerl/jungerl/lib/pgsql/src/pgsql_util.erl,v retrieving revision 1.4 retrieving revision 1.5 diff -u -d -r1.4 -r1.5 --- pgsql_util.erl 28 Oct 2006 21:05:29 -0000 1.4 +++ pgsql_util.erl 12 Sep 2007 23:55:48 -0000 1.5 @@ -29,6 +29,9 @@ -import(erlang, [md5/1]). -export([hexlist/2]). +-record(desc, {column, name, type, format, size, mod, table}). + + %% Lookup key in a plist stored in process dictionary under 'options'. %% Default is returned if there is no value for Key in the plist. option(Key, Default) -> @@ -157,27 +160,83 @@ 0 -> text; 1 -> binary end, - Desc = {Name, Format, ColumnNumber, - TypeId, TypeSize, TypeMod, - TableOID}, + Desc = #desc{name=Name, + format=Format, + column=ColumnNumber, + type=TypeId, + size=TypeSize, + mod=TypeMod, + table=TableOID}, coldescs(Rest, [Desc|Descs]). -datacoldescs(N, - <<Len:32/integer, Data:Len/binary, Rest/binary>>, - Descs) when N >= 0 -> +datacoldescs(N, <<-1:32/signed-integer, Rest/binary>>, Descs) + when N >= 0 -> + datacoldescs(N-1, Rest, [null|Descs]); +datacoldescs(N, <<Len:32/integer, Data:Len/binary, Rest/binary>>, Descs) + when N >= 0 -> datacoldescs(N-1, Rest, [Data|Descs]); datacoldescs(_N, _, Descs) -> lists:reverse(Descs). decode_descs(Cols) -> - decode_descs(Cols, []). -decode_descs([], Descs) -> - {ok, lists:reverse(Descs)}; -decode_descs([Col|ColTail], Descs) -> - OidMap = get(oidmap), - {Name, Format, ColNumber, Oid, _, _, _} = Col, - OidName = dict:fetch(Oid, OidMap), - decode_descs(ColTail, [{Name, Format, ColNumber, OidName, [], [], []}|Descs]). + Cols2 = [Col#desc{type=decode_oid(Oid)} || #desc{type=Oid}=Col <- Cols], + {ok, Cols2}. + + +decode_oid(Oid) -> + case Oid of + 16 -> bool; + 17 -> bytea; + 18 -> char; + 19 -> name; + 20 -> int8; + 21 -> int2; + 22 -> int2vector; + 23 -> int4; + 24 -> regproc; + 25 -> text; + 26 -> oid; + 27 -> tid; + 28 -> xid; + 29 -> cid; + 30 -> oidvector; + 71 -> pg_type; + 75 -> pg_attribute; + 81 -> pg_proc; + 83 -> pg_class; + 210 -> smgr; + 600 -> point; + 601 -> lseg; + 602 -> path; + 603 -> box; + 604 -> polygon; + 628 -> line; + 700 -> float4; + 701 -> float8; + 702 -> abstime; + 703 -> reltime; + 704 -> tinterval; + 705 -> unknown; + 790 -> money; + 829 -> macaddr; + 869 -> inet; + 650 -> cidr; + 1033 -> aclitem; + 1042 -> bpchar; + 1043 -> varchar; + 1082 -> date; + 1083 -> time; + 1114 -> timestamp; + 1184 -> timestamptz; + 1186 -> interval; + 1266 -> timetz; + 1560 -> bit; + 1562 -> varbit; + 1700 -> numeric; + Oid -> + throw({unknown_oid, Oid}) + end. + decode_row(Types, Values) -> decode_row(Types, Values, []). @@ -187,15 +246,38 @@ Out1 = decode_col(Type, Value), decode_row(TypeTail, ValueTail, [Out1|Out0]). -decode_col({_, text, _, _, _, _, _}, Value) -> - binary_to_list(Value); -decode_col({_Name, _Format, _ColNumber, varchar, _Size, _Modifier, _TableOID}, Value) -> +decode_col(_, null) -> + null; +decode_col(#desc{format=text, type=Int}, Value) + when Int =:= int2; Int =:= int4; Int =:= int8 -> + list_to_integer(binary_to_list(Value)); +decode_col(#desc{format=text, type=varchar}, Value) -> binary_to_list(Value); -decode_col({_Name, _Format, _ColNumber, int4, _Size, _Modifier, _TableOID}, Value) -> - <<Int4:32/integer>> = Value, - Int4; -decode_col({_Name, _Format, _ColNumber, Oid, _Size, _Modifier, _TableOID}, Value) -> - {Oid, Value}. +decode_col(#desc{format=text, type=Float}, Value) + when Float =:= float4; Float =:= float8 -> + list_to_float(binary_to_list(Value)); +decode_col(#desc{format=text, type=bool}, Value) -> + case Value of + <<"t">> -> true; + <<"f">> -> false + end; +decode_col(#desc{format=text, type=date}, Value) -> + <<Year:4/binary, $-, Month:2/binary, $-, Day:2/binary>> = Value, + {b2i(Year), b2i(Month), b2i(Day)}; +decode_col(#desc{format=text, type=time}, Value) -> + <<Hour:2/binary, $:, Minute:2/binary, $:, Second:2/binary>> = Value, + {b2i(Hour), b2i(Minute), b2i(Second)}; +decode_col(#desc{format=text, type=timestamp}, Value) -> + <<Year:4/binary, _, Month:2/binary, _, Day:2/binary, $\s, + Hour:2/binary, $:, Minute:2/binary, $:, Second:2/binary>> = Value, + {{b2i(Year), b2i(Month), b2i(Day)}, {b2i(Hour), b2i(Minute), b2i(Second)}}; +decode_col(#desc{format=text}, Value) -> + Value; +decode_col(_, Value) -> + throw({unknown_format, Value}). + +b2i(Bin) -> + list_to_integer(binary_to_list(Bin)). errordesc(Bin) -> errordesc(Bin, []). Index: pgsql_proto.erl =================================================================== RCS file: /cvsroot/jungerl/jungerl/lib/pgsql/src/pgsql_proto.erl,v retrieving revision 1.5 retrieving revision 1.6 diff -u -d -r1.5 -r1.6 --- pgsql_proto.erl 28 Oct 2006 21:05:29 -0000 1.5 +++ pgsql_proto.erl 12 Sep 2007 23:55:48 -0000 1.6 @@ -117,18 +117,18 @@ 2 -> % Kerberos 5 exit({nyi, auth_kerberos5}); 3 -> % Plaintext password - Password = option(password, ""), - EncodedPass = encode_message(pass_plain, Password), + Password = option(password, ""), + EncodedPass = encode_message(pass_plain, Password), ok = send(Sock, EncodedPass), authenticate(Sock); 4 -> % Hashed password exit({nyi, auth_crypt}); 5 -> % MD5 password - Password = option(password, ""), - User = option(user, ""), - EncodedPass = encode_message(pass_md5, {User, Password, Salt}), - ok = send(Sock, EncodedPass), - authenticate(Sock); + Password = option(password, ""), + User = option(user, ""), + EncodedPass = encode_message(pass_md5, {User, Password, Salt}), + ok = send(Sock, EncodedPass), + authenticate(Sock); _ -> exit({authentication, {unknown, AuthMethod}}) end; @@ -186,22 +186,6 @@ put(socket, Unwrapper) end, - %% Lookup oid to type names and store them in a dictionary under - %% 'oidmap' in the process dictionary. - begin - Packet = encode_message(squery, "SELECT oid, typname FROM pg_type"), - ok = send(Sock, Packet), - {ok, [{"SELECT", _ColDesc, Rows}]} = process_squery([]), - Rows1 = lists:map(fun ([CodeS, NameS]) -> - Code = list_to_integer(CodeS), - Name = list_to_atom(NameS), - {Code, Name} - end, - Rows), - OidMap = dict:from_list(Rows1), - put(oidmap, OidMap) - end, - %% Ready to start marshalling between frontend and backend. idle(Sock, DriverPid). @@ -341,8 +325,9 @@ process_squery(Log) -> receive {pgsql, {row_description, Cols}} -> - {ok, Command, Rows} = process_squery_cols([]), - process_squery([{Command, Cols, Rows}|Log]); + {ok, Types} = pgsql_util:decode_descs(Cols), + {ok, Command, Rows} = process_squery_cols(Types, []), + process_squery([{Command, Types, Rows}|Log]); {pgsql, {command_complete, Command}} -> process_squery([Command|Log]); {pgsql, {ready_for_query, Status}} -> @@ -352,10 +337,11 @@ {pgsql, Any} -> process_squery(Log) end. -process_squery_cols(Log) -> +process_squery_cols(Types, Log) -> receive {pgsql, {data_row, Row}} -> - process_squery_cols([lists:map(fun binary_to_list/1, Row)|Log]); + {ok, DecodedRow} = pgsql_util:decode_row(Types, Row), + process_squery_cols(Types, [DecodedRow|Log]); {pgsql, {command_complete, Command}} -> {ok, Command, lists:reverse(Log)} end. |
From: Jakub <jak...@us...> - 2007-08-24 09:54:25
|
Update of /cvsroot/jungerl/jungerl/lib/gettext/src In directory sc8-pr-cvs6.sourceforge.net:/tmp/cvs-serv7231/lib/gettext/src Added Files: gettext_checker.erl Log Message: simple module for checking and reparing the dependiences between different language .po files (eg. checking if the keys are the same), more info - gettext_checker:info/0 :) --- NEW FILE: gettext_checker.erl --- %%% ------------------------------------------------------------------- %%% File : gettext_checker.erl %%% Created : 19 Jul 2007 by <kub...@gm...> %%% Desc. : Check and validate if any translated strings are missing. %%%------------------------------------------------------------------- -module(gettext_checker). -export([dialog/0, dialog/1, info/0, get_first_key/0, next_non_translated/2, report_bug/3, check_bugs/0 ]). [...1031 lines suppressed...] io:format("wrong value~n"), get_new_value(Similar,ProperVal) end end. %% This function returns all languages that are in the system, basing on the %% content of the ../gettext/priv/lang directory all_langs() -> CustomPath=filename:join(?ROOT_DIR,"custom"), {ok,AllCustom}=file:list_dir(CustomPath), DirList = [ X || X<-AllCustom, filelib:is_dir(filename:join(CustomPath,X))==true], LangList = [ X || X<-DirList, filelib:is_regular(filename:join(CustomPath,X)++ "/gettext.po")==true], LangList. |
From: Torbjorn T. <et...@us...> - 2007-08-22 07:49:08
|
Update of /cvsroot/jungerl/jungerl/lib/dhcp In directory sc8-pr-cvs6.sourceforge.net:/tmp/cvs-serv26004 Added Files: LICENSE.txt Log Message: Added license text file. --- NEW FILE: LICENSE.txt --- Copyright (c) 2006,2007, Torbjorn Tornkvist, to...@to... Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
From: Martin B. <mb...@us...> - 2007-08-15 07:29:55
|
Update of /cvsroot/jungerl/jungerl/lib/msc/src In directory sc8-pr-cvs6.sourceforge.net:/tmp/cvs-serv2874 Modified Files: disk_log_h.erl logger.erl Log Message: updated disk_log_h and logger Index: disk_log_h.erl =================================================================== RCS file: /cvsroot/jungerl/jungerl/lib/msc/src/disk_log_h.erl,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- disk_log_h.erl 24 Feb 2003 22:07:59 -0000 1.1 +++ disk_log_h.erl 15 Aug 2007 07:29:49 -0000 1.2 @@ -9,7 +9,17 @@ %%% disk. In this case, the disk_log process is avoided. %%% %%% This module is intended to replace log_mf_h.erl. +%%% +%%% It now works with OTP R10B-9 without the need to patch +%%% disk_log.erl. However, disk_log in OTP uses the process +%%% dictionary, which means that only one disk_log_h can be +%%% installed in a single gen_event process. +%%% %%% Created : 1 Dec 2000 by Martin Bjorklund <mb...@bl...> +%%% Modified: 4 Jan 2006 by Martin Bjorklund <mb...@ta...> +%%% o Added option {force_size, true} (which really should be +%%% in disk_log instead) +%%% o Added function change_size/3 %%%---------------------------------------------------------------------- -module(disk_log_h). -author('mb...@bl...'). @@ -17,12 +27,12 @@ -behaviour(gen_event). %% External exports --export([init/2, info/2]). +-export([init/2, info/2, change_size/3]). %% gen_event callbacks -export([init/1, handle_event/2, handle_call/2, handle_info/2, terminate/2]). --record(state, {log, cnt, func}). +-record(state, {cnt, func}). -include_lib("kernel/src/disk_log.hrl"). @@ -33,7 +43,7 @@ %%----------------------------------------------------------------- %% This module is intended to be used as a gen_event handler. Instead %% of duplicating the functions to gen_event (add_handler etc), it -%% described here hoe to use these function with this module. +%% described here how to use these function with this module. %% %% The init function expects a list [Func, Opts], where: %% Func = fun(Event) -> false | binary() | [binary()] @@ -61,10 +71,11 @@ init(Func, DiskLogOpts) -> [Func, DiskLogOpts]. - info(EventMgr, Handler) -> gen_event:call(EventMgr, Handler, info). - + +change_size(EventMgr, Handler, NewSize) -> + gen_event:call(EventMgr, Handler, {change_size, NewSize}). %%%---------------------------------------------------------------------- %%% Callback functions from gen_event @@ -76,9 +87,31 @@ %% Other %%---------------------------------------------------------------------- init([Func, Opts]) -> - case disk_log:ll_open(Opts) of + Opts1 = lists:keydelete(force_size, 1, Opts), + case disk_log:ll_open(Opts1) of {ok, _, Log, Cnt} -> - {ok, #state{log = Log, cnt = Cnt, func = Func}}; + put(log, Log), + {ok, #state{cnt = Cnt, func = Func}}; + {error, {size_mismatch, _, NewSize}} = Error -> + case lists:keysearch(force_size, 1, Opts) of + {value, {force_size, true}} -> + %% open w/o size + Opts2 = lists:keydelete(size, 1, Opts1), + case disk_log:ll_open(Opts2) of + {ok, _, Log, Cnt} -> + %% we should really call check_size as well... + case catch do_change_size(Log, NewSize) of + ok -> + {ok, #state{cnt = Cnt, func = Func}}; + Else -> + {error, Else} + end; + NError -> + NError + end; + _ -> + Error + end; Error -> Error end. @@ -94,14 +127,14 @@ false -> {ok, S}; Bin -> - case disk_log:do_log(S#state.log, [Bin]) of - {N, L1} when integer(N) -> - {_, L2} = disk_log:do_sync(L1), - {ok, S#state{cnt = S#state.cnt+N, log = L2}}; - {error, {error, {full, _Name}}, L1, N} -> - {_, L2} = disk_log:do_sync(L1), - {ok, S#state{cnt = S#state.cnt+N, log = L2}}; - {error, Error, L1, N} -> + case disk_log:do_log(get(log), [Bin]) of + N when integer(N) -> + disk_log:do_sync(get(log)), + {ok, S#state{cnt = S#state.cnt+N}}; + {error, {error, {full, _Name}}, N} -> + disk_log:do_sync(get(log)), + {ok, S#state{cnt = S#state.cnt+N}}; + {error, Error, N} -> Error; Error -> Error @@ -115,8 +148,10 @@ %% {remove_handler, Reply} %%---------------------------------------------------------------------- handle_call(info, S) -> - Reply = disk_log:do_info(S#state.log, S#state.cnt), - {ok, Reply, S}. + Reply = disk_log:do_info(get(log), S#state.cnt), + {ok, Reply, S}; +handle_call({change_size, NewSize}, S) -> + {ok, catch do_change_size(get(log), NewSize), S}. %%---------------------------------------------------------------------- %% Func: handle_info/2 @@ -136,8 +171,17 @@ %% Returns: any %%---------------------------------------------------------------------- terminate(Arg, S) -> - disk_log:ll_close(S#state.log). + disk_log:ll_close(get(log)). %%%---------------------------------------------------------------------- %%% Internal functions %%%---------------------------------------------------------------------- + +%% hack so that disk_log doesn't have to be patched - code copied +%% from disk_log:do_change_size/2 +do_change_size(L, NewSize) -> + #log{extra = Extra, version = Version} = L, + {ok, Handle} = disk_log_1:change_size_wrap(Extra, NewSize, Version), + erase(is_full), + put(log, L#log{extra = Handle}), + ok. Index: logger.erl =================================================================== RCS file: /cvsroot/jungerl/jungerl/lib/msc/src/logger.erl,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- logger.erl 17 Nov 2003 19:16:09 -0000 1.1 +++ logger.erl 15 Aug 2007 07:29:49 -0000 1.2 @@ -9,6 +9,21 @@ %%% {logger, {logger, start_link, []}, %%% permanent, 2000, worker, [logger]}, %%% +%%% start_errlog() -> +%%% Opts = [{name, logger}, +%%% {file, "./elog"}, +%%% {type, wrap}, +%%% {format, external}, +%%% {force_size, true}, +%%% {size, {1024*1024, 5}}], % 5 files +%%% gen_event:add_sup_handler( +%%% error_logger, +%%% {disk_log_h, logger}, +%%% disk_log_h:init(fun logger:form_no_progress/1, Opts)). +%%% +%%% test() -> +%%% error_logger:error_msg("testing ~p\n", [self()]). +%%% %%% Initiate/deactivate system logging. %%% Owns the error log. %%% Created : 13 Apr 1999 by Magnus Fr|berg <ma...@bl...> @@ -16,7 +31,10 @@ %%% Modified: 04 Dec 2000 by Martin Bjorklund <mb...@bl...> %%% Modified: 13 Nov 2003 by Martin Bjorklund <mb...@bl...> %%% Cleanup for jungerl. +%%% Modified: 15 Aug 2007 by Martin Bjorklund <mb...@ta...> +%%% Added example, minor cleanups. %%%---------------------------------------------------------------------- + -module(logger). -vsn("$Revision$ "). -author('ma...@bl...'). @@ -53,32 +71,24 @@ set_system_error_logging(), Type = get_error_logger_mf_type(), Mf = get_error_logger_mf(), - add_error_logger_mf(Mf, Type), + ok = add_error_logger_mf(Mf, Type), {Name, Vsn} = init:script_id(), ?LOG("Starting system [~s-~s]\n", [Name, Vsn]), start_tell_started(), {ok, []}. -%%---------------------------------------------------------------------- -%%---------------------------------------------------------------------- handle_call(_Req, _, S) -> {reply, unknown_request, S}. -%%---------------------------------------------------------------------- -%%---------------------------------------------------------------------- handle_cast(_, S) -> {noreply, S}. -%%---------------------------------------------------------------------- -%%---------------------------------------------------------------------- handle_info({gen_event_EXIT, logger, Reason}, S) -> {stop, Reason, S}; handle_info(_, S) -> {noreply, S}. -%%---------------------------------------------------------------------- -%%---------------------------------------------------------------------- terminate(_Reason, _S) -> delete_error_logger_mf(), ok. @@ -107,7 +117,7 @@ {started, started} -> ?LOG("System started.\n", []); _ -> - timer:sleep(1000), + timer:sleep(100), tell_started() end. @@ -164,6 +174,12 @@ {error_report, _GL, {Pid, Type, Report}} -> [mk_hdr("ERROR REPORT", Type, Pid), io_lib:format("~p\n", [nobin(Report)])]; + %% tail-f specific debug messages + {info_report, _GL, {_, debug, {Pid, Now, Level, Tag, MsgStr}}} -> + ["*dbg* ", t2s(calendar:now_to_local_time(Now)), " ", + pid_to_list(Pid), " ", + integer_to_list(Level), "/", atom_to_list(Tag), + "\n ", MsgStr]; {info_report, _GL, {Pid, Type, Report}} -> [mk_hdr("INFO REPORT", Type, Pid), io_lib:format("~p\n", [nobin(Report)])]; @@ -199,7 +215,7 @@ pstr(T) -> io_lib:format("~p", [T]). -nobin(B) when binary(B), size(B) > 32 -> +nobin(B) when binary(B), size(B) > 1024 -> <<ShortBin:32/binary, _/binary>> = B, lists:flatten(io_lib:format("~p(~w)", [ShortBin, size(B)])); nobin(L) when list(L) -> |