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

Add support for {array, hstore}

bullno1 11 лет назад
Родитель
Сommit
65f28578c0
3 измененных файлов с 13 добавлено и 1 удалено
  1. 2 0
      src/pgsql_binary.erl
  2. 2 0
      src/pgsql_types.erl
  3. 9 1
      test/pgsql_tests.erl

+ 2 - 0
src/pgsql_binary.erl

@@ -28,6 +28,7 @@ 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(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(varchar, B) when is_binary(B)        -> <<(byte_size(B)):?int32, B/binary>>;
 encode(uuid, B) when is_binary(B)           -> encode_uuid(B);
 encode(uuid, B) when is_binary(B)           -> encode_uuid(B);
+encode(hstore, {Hstore}) when is_list(Hstore) -> encode_hstore(Hstore);
 encode(hstore, Hstore) when is_list(Hstore) -> encode_hstore(Hstore);
 encode(hstore, Hstore) when is_list(Hstore) -> encode_hstore(Hstore);
 encode({array, char}, L) when is_list(L)    -> encode_array(bpchar, L);
 encode({array, char}, L) when is_list(L)    -> encode_array(bpchar, L);
 encode({array, Type}, L) when is_list(L)    -> encode_array(Type, L);
 encode({array, Type}, L) when is_list(L)    -> encode_array(Type, L);
@@ -182,6 +183,7 @@ supports({array, timetz}) -> true;
 supports({array, timestamp})     -> true;
 supports({array, timestamp})     -> true;
 supports({array, timestamptz})   -> true;
 supports({array, timestamptz})   -> true;
 supports({array, interval})      -> true;
 supports({array, interval})      -> true;
+supports({array, hstore})        -> true;
 supports({array, varchar}) -> true;
 supports({array, varchar}) -> true;
 supports({array, uuid})   -> true;
 supports({array, uuid})   -> true;
 supports(_Type)       -> false.
 supports(_Type)       -> false.

+ 2 - 0
src/pgsql_types.erl

@@ -93,6 +93,7 @@ oid2type(2950) -> uuid;
 oid2type(2951) -> {array, uuid};
 oid2type(2951) -> {array, uuid};
 oid2type(3500) -> anyenum;
 oid2type(3500) -> anyenum;
 oid2type(16831) -> hstore;
 oid2type(16831) -> hstore;
+oid2type(16836) -> {array, hstore};
 oid2type(Oid)  -> {unknown_oid, Oid}.
 oid2type(Oid)  -> {unknown_oid, Oid}.
 
 
 type2oid(bool)                  -> 16;
 type2oid(bool)                  -> 16;
@@ -186,4 +187,5 @@ type2oid(uuid)                  -> 2950;
 type2oid({array, uuid})         -> 2951;
 type2oid({array, uuid})         -> 2951;
 type2oid(anyenum)               -> 3500;
 type2oid(anyenum)               -> 3500;
 type2oid(hstore)                -> 16831;
 type2oid(hstore)                -> 16831;
+type2oid({array, hstore})       -> 16836;
 type2oid(Type)                  -> {unknown_type, Type}.
 type2oid(Type)                  -> {unknown_type, Type}.

+ 9 - 1
test/pgsql_tests.erl

@@ -551,6 +551,8 @@ hstore_type_test(Module) ->
     Values = [
     Values = [
         [],
         [],
         [{null, null}],
         [{null, null}],
+        [{1, null}],
+        [{1.0, null}],
         [{<<"a">>, <<"c">>}, {<<"c">>, <<"d">>}],
         [{<<"a">>, <<"c">>}, {<<"c">>, <<"d">>}],
         [{<<"a">>, <<"c">>}, {<<"c">>, null}]
         [{<<"a">>, <<"c">>}, {<<"c">>, null}]
     ],
     ],
@@ -587,7 +589,9 @@ array_type_test(Module) ->
           Select(timetz, [{{0,1,2.0},1*60*60}, {{0,1,3.0},1*60*60}]),
           Select(timetz, [{{0,1,2.0},1*60*60}, {{0,1,3.0},1*60*60}]),
           Select(timestamp, [{{2008,1,2},{3,4,5.0}}, {{2008,1,2},{3,4,6.0}}]),
           Select(timestamp, [{{2008,1,2},{3,4,5.0}}, {{2008,1,2},{3,4,6.0}}]),
           Select(timestamptz, [{{2008,1,2},{3,4,5.0}}, {{2008,1,2},{3,4,6.0}}]),
           Select(timestamptz, [{{2008,1,2},{3,4,5.0}}, {{2008,1,2},{3,4,6.0}}]),
-          Select(interval, [{{1,2,3.1},0,0}, {{1,2,3.2},0,0}])
+          Select(interval, [{{1,2,3.1},0,0}, {{1,2,3.2},0,0}]),
+          Select(hstore, [{[{null, null}, {a, 1}, {1, 2}]}]),
+          Select(hstore, [[{[{null, null}, {a, 1}, {1, 2}]}, {[]}], [{[{a, 1}]}, {[{null, 2}]}]])
       end).
       end).
 
 
 text_format_test(Module) ->
 text_format_test(Module) ->
@@ -841,6 +845,8 @@ check_type(Module, Type, In, Out, Values, Column) ->
 compare(_Type, null, null) -> true;
 compare(_Type, null, null) -> true;
 compare(float4, V1, V2)    -> abs(V2 - V1) < 0.000001;
 compare(float4, V1, V2)    -> abs(V2 - V1) < 0.000001;
 compare(float8, V1, V2)    -> abs(V2 - V1) < 0.000000000000001;
 compare(float8, V1, V2)    -> abs(V2 - V1) < 0.000000000000001;
+compare(hstore, {V1}, V2)  -> compare(hstore, V1, V2);
+compare(hstore, V1, {V2})  -> compare(hstore, V1, V2);
 compare(hstore, V1, V2)    ->
 compare(hstore, V1, V2)    ->
     orddict:from_list(format_hstore(V1)) =:= orddict:from_list(format_hstore(V2));
     orddict:from_list(format_hstore(V1)) =:= orddict:from_list(format_hstore(V2));
 compare(Type, V1 = {_, _, MS}, {D2, {H2, M2, S2}}) when Type == timestamp;
 compare(Type, V1 = {_, _, MS}, {D2, {H2, M2, S2}}) when Type == timestamp;
@@ -849,6 +855,7 @@ compare(Type, V1 = {_, _, MS}, {D2, {H2, M2, S2}}) when Type == timestamp;
     ({D1, H1, M1} =:= {D2, H2, M2}) and (abs(S1 + MS/1000000 - S2) < 0.000000000000001);
     ({D1, H1, M1} =:= {D2, H2, M2}) and (abs(S1 + MS/1000000 - S2) < 0.000000000000001);
 compare(_Type, V1, V2)     -> V1 =:= V2.
 compare(_Type, V1, V2)     -> V1 =:= V2.
 
 
+format_hstore({Hstore}) -> Hstore;
 format_hstore(Hstore) ->
 format_hstore(Hstore) ->
     [{format_hstore_key(Key), format_hstore_value(Value)} || {Key, Value} <- Hstore].
     [{format_hstore_key(Key), format_hstore_value(Value)} || {Key, Value} <- Hstore].
 
 
@@ -857,6 +864,7 @@ format_hstore_key(Key) -> format_hstore_string(Key).
 format_hstore_value(null) -> null;
 format_hstore_value(null) -> null;
 format_hstore_value(Value) -> format_hstore_string(Value).
 format_hstore_value(Value) -> format_hstore_string(Value).
 
 
+format_hstore_string(Num) when is_number(Num) -> iolist_to_binary(io_lib:format("~w", [Num]));
 format_hstore_string(Str) -> iolist_to_binary(io_lib:format("~s", [Str])).
 format_hstore_string(Str) -> iolist_to_binary(io_lib:format("~s", [Str])).
 
 
 %% flush mailbox
 %% flush mailbox