Erlang:binary_to_term 解释

问题描述 投票:0回答:1

我手上有一些旧的 elrang (17.1) 项目,我需要一些帮助来理解代码的某些部分。

使用它,我使用这些值在集合表中创建一个对象

{:name=>"TestCurrency", :value=>["usd", " eur", " pln"] (当然还有 uuid)

(值以字节形式存储在 Postgres DB 中)

insert_and_return_record(Resource) ->
    #?model_name{account_uuid=AccountUuid, name=Name, value=Value} = Resource,
    Uuid = digits:uuid(AccountUuid),
    LowerValue = to_lower(Value),
    Statement = "INSERT INTO sets(uuid, account_uuid, name, value) VALUES($1, $2, $3, $4)",
    {ok, 1} = bep_db:execute(Statement, [Uuid, AccountUuid, Name, term_to_binary(LowerValue)]),
    get_record(AccountUuid, Uuid).

此代码在数据库中生成此条目

cdbee9cb-fc84-53a9-8e8b-22c90a76b211 | a9dbb489-4a97-5b15-bfcf-ca558e01687c | TestCurrencies | \x836c000000036d000000037573646d00000004206575726d0000000420706c6e6a

同时

get_record(AccountUuid, Uuid) ->
    Statement = "SELECT uuid, account_uuid, name, value FROM sets WHERE account_uuid=$1 AND uuid=$2",
    {ok, _Columns, Rows} = bep_db:execute(Statement, [AccountUuid, Uuid]),
    case Rows of
        [] ->
            {error, no_exists};
        [{Uuid, AccountUuid, Name, Value}] ->
            #?model_name{uuid=Uuid, account_uuid=AccountUuid, name=Name, value=binary_to_term(Value)}
    end.

确实返回正确的值,但手动运行

binary_to_term("\x836c000000036d000000037573646d00000004206575726d0000000420706c6e6a").
返回 bad_argument 错误。

直接从数据库获取

SELECT encode(value, 'escape') FROM sets WHERE uuid = 'cdbee9cb-fc84-53a9-8e8b-22c90a76b211';
returns

\203l\000\000\000\x03m\000\000\000\x03usdm\000\000\000\x04 eurm\000\000\000\x04 plnj

有人可以向我解释一下为什么会这样吗? 有没有办法只使用 SQL 来获取正确的值?
用 Ruby 编写的其他项目需要与同一个数据库通信并获取正确的值,这可能吗?

我尝试搜索问题,尝试在 erlang 控制台中手动运行它。我尝试过使用 SQL。

erlang bytea
1个回答
0
投票

文中标注

\x836c000000036d000000037573646d00000004206575726d0000000420706c6e6a

\x
后跟十六进制编码的二进制数据。要手动解码,您可以删除
\x
并将其作为二进制文件传递给
binary:decode_hex

1> binary_to_term(binary:decode_hex(<<"836c000000036d000000037573646d00000004206575726d0000000420706c6e6a">>)).
[<<"usd">>,<<" eur">>,<<" pln">>]

要使用原始 SQL 获得相同的值,您可以执行以下操作

encode(value, 'hex')
:

SELECT encode(value, 'hex') FROM sets WHERE uuid = 'cdbee9cb-fc84-53a9-8e8b-22c90a76b211';

用 Ruby 编写的其他项目需要与同一个数据库通信并获取正确的值,这可能吗?

为此,您需要找到一个库或编写一个可以解析 Erlang 外部术语格式 (https://www.erlang.org/doc/apps/erts/erl_ext_dist.html) 的解析器。

© www.soinside.com 2019 - 2024. All rights reserved.