ActiveRecordの
  PostgreSQLアダプタ
 周辺について調べてみた

(株)サイクル・オブ・フィフス
      石田朗雄
はじめに
ActiveRecordのPostgreSQLアダプタについて調べてみて、
はまったところや気になったとこをまとめました。
でもメインはその下のレイヤの話です。
普段Rubyを使っているわけではないので、僕の話にRubyに対
する愛が...
構成
                    ActiveRecord::Base

                AR::ConnectionAdapter::Base

 AR::CA::PostgreSQLAdapter        ...
postgres-prとの比較
    ruby-postgres-0.7.1.2006.04.06-mswin32
    postgres-pr-0.4.0
    postgres-prは、postgres.soがあればそっちを呼ぶので、...
postgres-prとの比較
  > PGconn.instance_methods(false).sort
  => [quot;async_execquot;, quot;async_queryquot;, quot;client_enc...
接続
  irb(main):013:0> c=PGconn.new(nil, 9999, nil, nil, 'ishida', 'ishida',
  nil)
  PGError: could not connect to server:...
ParameterStatus
    PostgreSQLのコンフィグのうち、クライアントの動作に影響
    するものをサーバからクライアントに対して送る
    接続時、SETコマンドによる変更、コンフィグファイルのリ
    ロード等
...
postgres-prとの比較
  irb(main):004:0> c.client_encoding
  => quot;SQL_ASCIIquot;
  irb(main):005:0> c.exec(quot;set client_en...
コイツ、、、動くぞ、、、
  PGconn.translate_results = false if PGconn.respond_to? :translate_results=
  ....
  if @connection.respond_...
PGconn#async_exec
  pgconn_async_exec():postgres.c

       if (!PQsendQuery(conn, RSTRING(str)->ptr)) {
           rb_rais...
まとめ?
    ruby-postgresとpostgres-prは結構違うけ
    ど、ActiveRecordが違いを吸収している
    今回挙げたものの他にもpostgres-prは、引数のoptionsを無
    視してたり環境...
C:rubylibrubygems1.8gemspostgres-pr-0.4.0lib>grep -r TODO *
 postgres-pr/connection.rb:         # TODO
 postgres-pr/connec...
Upcoming SlideShare
Loading in...5
×

Ruby Postgres

6,038

Published on

Published in: Technology, Education
0 Comments
3 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
6,038
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
35
Comments
0
Likes
3
Embeds 0
No embeds

No notes for slide

Ruby Postgres

  1. 1. ActiveRecordの PostgreSQLアダプタ 周辺について調べてみた (株)サイクル・オブ・フィフス 石田朗雄
  2. 2. はじめに ActiveRecordのPostgreSQLアダプタについて調べてみて、 はまったところや気になったとこをまとめました。 でもメインはその下のレイヤの話です。 普段Rubyを使っているわけではないので、僕の話にRubyに対 する愛が足りないように聞こえたらごめんなさい。
  3. 3. 構成 ActiveRecord::Base AR::ConnectionAdapter::Base AR::CA::PostgreSQLAdapter AR::CA::他のRDBMS向け ruby-postgres postgres-pr (pure ruby) libpq(C言語) 04:54:22 PM Ruby-Sapporo 2007-11-17 3
  4. 4. postgres-prとの比較 ruby-postgres-0.7.1.2006.04.06-mswin32 postgres-pr-0.4.0 postgres-prは、postgres.soがあればそっちを呼ぶので、両 方入っている環境では工夫が必要 ruby-postgres irb(main):002:0> require quot;postgresquot; => true postgres-pr irb(main):003:0> require quot;postgres-pr/postgres-compatquot; => true 04:54:22 PM Ruby-Sapporo 2007-11-17 4
  5. 5. postgres-prとの比較 > PGconn.instance_methods(false).sort => [quot;async_execquot;, quot;async_queryquot;, quot;client_encodingquot;, quot;closequot;, quot;dbquot;, quot;endcopyquot;, quot;errorquot;, quot;execquot;, quot;finishquot;, quot;get_notifyquot;, quot;getlinequot;, quot;hostquot;, quot;insert_tablequot;, quot;lo_createquot;, quot;lo_exportquot;, quot;lo_importquot;, quot;lo_openquot;, quot;lo_unlinkquot;, quot;locreatequot;, quot;loexportquot;, quot;loimportquot;, quot;loopenquot;, quot;lounlinkquot;, quot;on_noticequot;, quot;optionsquot;, quot;portquot;, quot;protocol_versionquot;, quot;putlinequot;, quot;queryquot;, quot;resetquot;, quot;select_onequot;, quot;select_valuequot;, quot;select_valuesquot;, quot;server_versionquot;, quot;set_client_encodingquot;, quot;statusquot;, quot;tracequot;, quot;transaction_statusquot;, quot;ttyquot;, quot;untracequot;, quot;userquot;] > PGconn.instance_methods(false).sort => [quot;closequot;, quot;dbquot;, quot;execquot;, quot;hostquot;, quot;queryquot;, quot;userquot;] 04:54:22 PM Ruby-Sapporo 2007-11-17 5
  6. 6. 接続 irb(main):013:0> c=PGconn.new(nil, 9999, nil, nil, 'ishida', 'ishida', nil) PGError: could not connect to server: Connection refused (0x0000274D/10061) Is the server running on host quot;???quot; and accepting TCP/IP connections on port 9999? from (irb):13:in `initialize' postgres-prではhostがnilだと from (irb):13:in `new' portが無視される from (irb):13 irb(main):004:0> c=PGconn.new(nil, 9999, nil, nil, 'ishida', 'ishida', nil) => #<PGconn:0x2dc3d98 @db=quot;ishidaquot;, @host=nil, @conn=#<PostgresPR::Connection:0x2dc3d70 @params={quot;integer_datetimesquot;=>quot;offquot;, quot;TimeZonequot;=>quot;JST-9quot;, quot;server_encodingquot;=>quot;EUC_JPquot;, quot;standard_conforming_stringsquot;=>quot;offquot;, quot;DateStylequot;=>quot;ISO, MDYquot;, quot;client_encodingquot;=>quot;EUC_JPquot;, quot;session_authorizationquot;=>quot;ishidaquot;, quot;server_versionquot;=>quot;8.1.3quot;, quot;is_superuserquot;=>quot;offquot;}, @conn=#<TCPSocket:0x2dc3bf4>>, @user=quot;ishidaquot;> 04:54:22 PM Ruby-Sapporo 2007-11-17 6
  7. 7. ParameterStatus PostgreSQLのコンフィグのうち、クライアントの動作に影響 するものをサーバからクライアントに対して送る 接続時、SETコマンドによる変更、コンフィグファイルのリ ロード等 server_version client_encoding DateStyle 等々 バージョンが上がると増えることがあるの で、PGconn#getparamみたいのが欲しい 04:54:22 PM Ruby-Sapporo 2007-11-17 7
  8. 8. postgres-prとの比較 irb(main):004:0> c.client_encoding => quot;SQL_ASCIIquot; irb(main):005:0> c.exec(quot;set client_encoding to sjisquot;) => #<PGresult:0x2dc2358> irb(main):006:0> c.client_encoding => quot;SJISquot; irb(main):010:0> c.instance_variable_get(:@conn).instance_variable_get(:@params) [quot;client_encodingquot;] => quot;SQL_ASCIIquot; irb(main):011:0> c.exec(quot;set client_encoding to sjisquot;) => #<PGresult:0x2e98cb4 @result=[], @fields=[], @res=#<PostgresPR::Connection::Result:0x2e98c50 @cmd_tag=quot;SETquot;, @fields=[], @rows=[]>> irb(main):012:0> c.instance_variable_get(:@conn).instance_variable_get(:@params) [quot;client_encodingquot;] => quot;SQL_ASCIIquot; postgres-prは ParameterStatusの変更を 04:54:22 PM Ruby-Sapporo 2007-11-17 拾っていない 8
  9. 9. コイツ、、、動くぞ、、、 PGconn.translate_results = false if PGconn.respond_to? :translate_results= .... if @connection.respond_to?(:status) ... # TODO: postgres-pr doesn't have PGconn#reset. if @connection.respond_to?(:reset) 但し、allow_concurrencyだけは使ってはいけない def query(sql, name = nil) #:nodoc: log(sql, name) do if @async @connection.async_query(sql) else @connection.query(sql) end end 04:54:22 PM Ruby-Sapporo 2007-11-17 9
  10. 10. PGconn#async_exec pgconn_async_exec():postgres.c if (!PQsendQuery(conn, RSTRING(str)->ptr)) { rb_raise(rb_ePGError, PQerrorMessage(conn)); } cs = PQsocket(conn); PQsendQueryで非同期にクエリ for(;;) { 送信した後、結果が返ってくるの FD_ZERO(&rset); を待っている? FD_SET(cs, &rset); ret = rb_thread_select(cs + 1, &rset, NULL, NULL, NULL); 04:54:22 PM Ruby-Sapporo 2007-11-17 10
  11. 11. まとめ? ruby-postgresとpostgres-prは結構違うけ ど、ActiveRecordが違いを吸収している 今回挙げたものの他にもpostgres-prは、引数のoptionsを無 視してたり環境変数も無視してたり、ParameterStatusを無 視するケースがあったり、、、 素のpostgres-prを使うには覚悟が必要 04:54:22 PM Ruby-Sapporo 2007-11-17 11
  12. 12. C:rubylibrubygems1.8gemspostgres-pr-0.4.0lib>grep -r TODO * postgres-pr/connection.rb: # TODO postgres-pr/connection.rb: # TODO: use transaction status postgres-pr/connection.rb: # TODO postgres-pr/connection.rb: # TODO postgres-pr/message.rb:# TODO postgres-pr/message.rb:# TODO postgres-pr/message.rb: # TODO: zero means unspecified. map to nil? postgres-pr/message.rb:# TODO: duplicate message-type, split into client/servermessages postgres-pr/postgres-compat.rb: # TODO: correct? postgres-pr/postgres-compat.rb: # TODO: status, getlength, cmdstatus postgres-pr/postgres-compat.rb: # TODO: correct? postgres-pr/postgres-compat.rb: # TODO: correct? postgres-pr/typeconv/TC_conv.rb: assert_equal [quot;quot;], decode_array(quot;{ }quot;) # TODO: Correct? 04:54:22 PM Ruby-Sapporo 2007-11-17 12
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×