2017-07-21 11 views
1

簡単例:/ruby​​でpostgresのバイト配列がエスケープされていますか?

Zlib::Inflate.inflate(Zlib::Deflate.deflate('["128,491,128,487"]')) 
=> "[\"128,491,128,487\"]" 

解析が失敗した文字列に依存して成功します:以下のため、これはzlibの問題ではありません

Zlib::Inflate.inflate(PG::Connection.unescape_bytea(PG::Connection.escape_bytea(Zlib::Deflate.deflate('["128,491,128,487"]')))) 
Zlib::DataError: incorrect data check 

は成功

Zlib::Inflate.inflate(PG::Connection.unescape_bytea(PG::Connection.escape_bytea(Zlib::Deflate.deflate('["128,491,128,487", "128,491,128,490", "38,465,40,463"]')))) 
=> "[\"128,491,128,487\", \"128,491,128,490\", \"38,465,40,463\"]" 

私が何か間違ったことをしていますまたはpostgresバイトフィールドが壊れたルビーでエスケープですか?代わりに何をすることができますか?

試してみました:Ruby 2.2.3p173、gem pg-0.18.4;ルビー2.4.1p111は、GEM PG-0.21.0 https://bitbucket.org/ged/ruby-pg/issues/262/postgres-bytearray-escapingから

答えて

0

回答:

(UN)escape_byteaの説明は誤解を招きます。お互いの正反対ではありません。

PG :: Connection.escape_byteaは、古いものと廃止予定のエスケープメカニズムを使用します。これは、最初はBYTEA、2番目は文字列リテラル(文字列の前後に追加)ごとにSQL文字列に挿入されます。これは、便宜とパフォーマンスの理由から1つのステップで行われます。

逆に、PG :: Connection.unescape_byteaはBYTEAのみエスケープ処理を行います。これは、クエリによって取得された列データをデコードするためです。このデータは文字列リテラルとしてエスケープされません。これは、代わりのlibpqのPG宝石の種類エンコーダを使用する

enco = PG::TextEncoder::Bytea.new 
deco = PG::TextDecoder::Bytea.new 
Zlib::Inflate.inflate(deco.decode(enco.encode(Zlib::Deflate.deflate('["128,491,128,487"]')))) 

: あなたは今以上の仕事を作るために2つのオプションがあります。エンコーダは新しいBYTEAエスケープマカニズムを使用しており、libpqの機能よりも少し速いです。これは依然としてサーバー接続から独立しています。 でCONN = PG.connect

Zlib::Inflate.inflate(conn.unescape_bytea(conn.escape_bytea(Zlib::Deflate.deflate('["128,491,128,487"]')))) 

これはlibpqのの機能を脱出バインド接続を利用します。また、新しいエスケープメカニズムを使用しているため、ダブルエスケープは発生しません。

関連する問題