Просмотр исходного кода

Add support for uuid and uuid arrays (from soundrop: https://github.com/soundrop/epgsql/ )

Conflicts:
	src/pgsql_binary.erl
Ali Sabil 11 лет назад
Родитель
Сommit
0003ccdacb
2 измененных файлов с 22 добавлено и 0 удалено
  1. 18 0
      src/pgsql_binary.erl
  2. 4 0
      src/pgsql_types.erl

+ 18 - 0
src/pgsql_binary.erl

@@ -27,6 +27,7 @@ encode(interval = Type, B)                  -> ?datetime:encode(Type, B);
 encode(bytea, B) when is_binary(B)          -> <<(byte_size(B)):?int32, B/binary>>;
 encode(text, B) when is_binary(B)           -> <<(byte_size(B)):?int32, B/binary>>;
 encode(varchar, B) when is_binary(B)        -> <<(byte_size(B)):?int32, B/binary>>;
+encode(uuid, B) when is_binary(B)           -> encode_uuid(B);
 encode(boolarray, L) when is_list(L)        -> encode_array(bool, L);
 encode(int2array, L) when is_list(L)        -> encode_array(int2, L);
 encode(int4array, L) when is_list(L)        -> encode_array(int4, L);
@@ -41,6 +42,7 @@ encode(timetzarray, L) when is_list(L)      -> encode_array(timetz, L);
 encode(timestamparray, L) when is_list(L)   -> encode_array(timestamp, L);
 encode(timestamptzarray, L) when is_list(L) -> encode_array(timestamptz, L);
 encode(intervalarray, L) when is_list(L)    -> encode_array(interval, L);
+encode(uuidarray, L) when is_list(L)        -> encode_array(uuid, L);
 encode(Type, L) when is_list(L)             -> encode(Type, list_to_binary(L));
 encode(_Type, _Value)                       -> {error, unsupported}.
 
@@ -59,6 +61,7 @@ decode(date = Type, B)                      -> ?datetime:decode(Type, B);
 decode(timestamp = Type, B)                 -> ?datetime:decode(Type, B);
 decode(timestamptz = Type, B)               -> ?datetime:decode(Type, B);
 decode(interval = Type, B)                  -> ?datetime:decode(Type, B);
+decode(uuid, B)                             -> decode_uuid(B);
 decode(boolarray, B)                        -> decode_array(B);
 decode(int2array, B)                        -> decode_array(B);
 decode(int4array, B)                        -> decode_array(B);
@@ -73,6 +76,7 @@ decode(timetzarray, B)                      -> decode_array(B);
 decode(timestamparray, B)                   -> decode_array(B);
 decode(timestamptzarray, B)                 -> decode_array(B);
 decode(intervalarray, B)                    -> decode_array(B);
+decode(uuidarray, B)                        -> decode_array(B);
 decode(_Other, Bin)                         -> Bin.
 
 encode_array(Type, A) ->
@@ -95,6 +99,13 @@ encode_array(Type, Array, NDims, Lengths) ->
     {Data, {NDims2, Lengths3}} = lists:mapfoldl(F, {NDims, Lengths2}, Array),
     {Data, {NDims2 + 1, Lengths3}}.
 
+encode_uuid(U) when is_binary(U) ->
+    encode_uuid(binary_to_list(U));
+encode_uuid(U) ->
+    Hex = [H || H <- U, H =/= $-],
+    {ok, [Int], _} = io_lib:fread("~16u", Hex),
+    <<16:?int32,Int:128>>.
+
 decode_array(<<NDims:?int32, _HasNull:?int32, Oid:?int32, Rest/binary>>) ->
     {Dims, Data} = erlang:split_binary(Rest, NDims * 2 * 4),
     Lengths = [Len || <<Len:?int32, _LBound:?int32>> <= Dims],
@@ -126,6 +137,10 @@ decode_record(<<Type:?int32, Len:?int32, Value:Len/binary, Rest/binary>>, Acc) -
     Value2 = decode(pgsql_types:oid2type(Type), Value),
     decode_record(Rest, [Value2 | Acc]).
 
+decode_uuid(<<U0:32, U1:16, U2:16, U3:16, U4:48>>) ->
+    Format = "~8.16.0b-~4.16.0b-~4.16.0b-~4.16.0b-~12.16.0b",
+    iolist_to_binary(io_lib:format(Format, [U0, U1, U2, U3, U4])).
+
 supports(bool)    -> true;
 supports(bpchar)  -> true;
 supports(int2)    -> true;
@@ -143,6 +158,7 @@ supports(timetz)  -> true;
 supports(timestamp)   -> true;
 supports(timestamptz) -> true;
 supports(interval)    -> true;
+supports(uuid)        -> true;
 supports(boolarray)   -> true;
 supports(int2array)   -> true;
 supports(int4array)   -> true;
@@ -157,4 +173,6 @@ supports(timetzarray) -> true;
 supports(timestamparray)     -> true;
 supports(timestamptzarray)   -> true;
 supports(intervalarray)      -> true;
+supports(varchararray) -> true;
+supports(uuidarray)   -> true;
 supports(_Type)       -> false.

+ 4 - 0
src/pgsql_types.erl

@@ -89,6 +89,8 @@ oid2type(2281) -> internal;
 oid2type(2282) -> opaque;
 oid2type(2283) -> anyelement;
 oid2type(2776) -> anynonarray;
+oid2type(2950) -> uuid;
+oid2type(2951) -> uuidarray;
 oid2type(3500) -> anyenum;
 oid2type(Oid)  -> {unknown_oid, Oid}.
 
@@ -179,5 +181,7 @@ type2oid(internal)              -> 2281;
 type2oid(opaque)                -> 2282;
 type2oid(anyelement)            -> 2283;
 type2oid(anynonarray)           -> 2776;
+type2oid(uuid)                  -> 2950;
+type2oid(uuidarray)             -> 2951;
 type2oid(anyenum)               -> 3500;
 type2oid(Type)                  -> {unknown_type, Type}.