pg
-
ããŒã :: github.com/ged/ruby-pg
-
ããã¥ã¡ã³ã :: deveiate.org/code/pg/README_md.html ïŒè±èªïŒã deveiate.org/code/pg/README_ja_md.html ïŒæ¥æ¬èªïŒ
-
倿Žå±¥æŽ :: CHANGELOG.md
説æ
Pgã¯PostgreSQL RDBMSãžã®Rubyã®ã€ã³ã¿ãŒãã§ãŒã¹ã§ããPostgreSQL 10以éã§åäœããŸãã
ç°¡åãªäœ¿çšäŸã¯æ¬¡ã®éãã§ãã
#!/usr/bin/env ruby require 'pg' # ããŒã¿ããŒã¹ãžã®çŸåšã®æ¥ç¶ã衚ã«åºåããŸã conn = PG.connect( dbname: 'sales' ) conn.exec( "SELECT * FROM pg_stat_activity" ) do |result| puts " PID | User | Query" result.each do |row| puts " %7d | %-16s | %s " % row.values_at('pid', 'usename', 'query') end end
åãåããã®ã¡ãœããã«ã€ããŠã¯ PG::Connection ã¯ã©ã¹ããåãåããã®çµæãåãåãéã®æ
å ±ã«ã€ããŠã¯ PG::Resultã¯ã©ã¹ãåç
§ããŠãã ããã
ãã«ãç¶æ³
èŠä»¶
-
Ruby 3.1ãããããæ°ããããŒãžã§ã³
-
PostgreSQL 10.x以é
-
ãœãŒã¹ããgemãã€ã³ã¹ããŒã«ããå ŽåïŒ-devã®ããã±ãŒãžãªã©ããããä»ãã®libpq
ã€ã³ã¹ããŒã«æ¹æ³
RubyGemsãçµç±ããŠã€ã³ã¹ããŒã«ããã«ã¯ä»¥äžãšããŸãã
gem install pg
ãããããšãã€ããªgemããšãããå®è¡ããŠãããã©ãããã©ãŒã ã«åºæã®ãã®ãæ¢å®ã§ã€ã³ã¹ããŒã«ãããŸãã
ãã€ããªgem
ãã€ããªgemã¯å®è¡äžã®ã·ã¹ãã ã®libpqããã±ãŒãžã«äŸåããŸãããçµèŸŒã¿ã§libpqãæã¡ãŸãã
x86_64-linuxãšaarch64-linuxã®ãã©ãããã©ãŒã ã®gemã¯Alpine Linuxã§èµ°ããŸãããgcompatããã±ãŒãžãèŠæ±ãããŸããäžæ¹ã*-linux-muslã®ãã©ãããã©ãŒã ã®ãã€ãã£ãgemã¯ãã®äŸåé¢ä¿ãªãã«åäœããŸãã
ãã€ããªgemã察å¿ããŠããªãçšéã1ã€ããããããLDAPããã®æ¥ç¶ãªãã·ã§ã³ã®ååŸã§ããããã«å¯Ÿå¿ããã«ã¯libldapãå¿
èŠã§ãããããæ²¢å±±ã®äŸåé¢ä¿ããããŸããåºã䜿ãããŠããæ©èœã®ããã«ã察å¿ãã䟡å€ããããšãæãããŸãããå¿
èŠã§ããã°ããœãŒã¹gemã«åŒ·å¶ã§ããŸãã
ãœãŒã¹gem
ãœãŒã¹gemã¯æ¬¡ã®ããã«åŒ·å¶ã§ããŸãã
gem uninstall pg --all gem install pg --platform ruby
Postgresãšäžç·ã«ã€ã³ã¹ããŒã«ãããâpg_configâããã°ã©ã ãžã®ãã¹ãæå®ããå¿ èŠããããããããŸããã
gem install pg -- --with-pg-config=<path to pg_config>
Bundlerãä»ããŠã€ã³ã¹ããŒã«ããå Žåã¯æ¬¡ã®ããã«ã³ã³ãã€ã«ã®ããã®ãã³ããäžããããŸãã
bundle config build.pg --with-pg-config=<path to pg_config>
Bundler
å¿ èŠãªãã©ãããã©ãŒã ãšãœãŒã¹gemãbundlerã«ããååŸãããããšã確å®ã«ããããã«ã¯ã次ã®ããã«å ããããŸãã
bundle lock --add-platform x86_64-linux bundle lock --add-platform arm64-darwin bundle lock --add-platform x64-mingw-ucrt bundle lock --add-platform ruby bundle package --all-platforms
bundle packageã®åå®è¡ã¯bundle updateåŸã«ãå¿
é ã§ãããããã¯ãã¹ãŠã®ãã©ãããã©ãŒã ã®æ°ããç¹å®ã®gemãååŸããããã§ãã
ãã€ããªgemãäœããã®çç±ã§åäœããªããªããGemfileã§ãœãŒã¹gemã®å©çšãç°¡åã«åŒ·å¶ã§ããŸãã
gem "pg", force_ruby_platform: true
ãã®ä»
MacOS Xãžã€ã³ã¹ããŒã«ãã詳ããæ å ±ã«ã€ããŠã¯ README-OS_X.rdoc ããWindowsçšã®ãã«ããã€ã³ã¹ããŒã«ã®èª¬æã«ã€ããŠã¯README-Windows.rdoc ãåç §ããŠãã ããã
è©°ãŸã£ããšãããã äœãåããããšãã®ããã«Google+ã°ã«ãŒããšã¡ãŒãªã³ã°ãªã¹ãããããŸãã
眲åãããgemãšããŠã€ã³ã¹ããŒã«ãããå Žåã¯ããªããžããªã®certsãã£ã¬ã¯ããªã«gemã®çœ²åãããå
¬éèšŒææžããããŸãã
ããŒãžã§ã³ç®¡ç
ã»ãã³ãã£ãã¯ããŒãžã§ãã³ã°ã®ååã«ãããã£ãŠgemãã¿ã°ä»ãããŠãªãªãŒã¹ããŠããŸãã
ãã®æ¹éã®çµæãšããŠã2ã€ã®æ°åãæå®ããæ²èŠ³çããŒãžã§ã³å¶çŽã䜿ã£ãŠãã®gemãžã®äŸåé¢ä¿ãæå®ããããšãã§ããŸãïŒãŸããããã¹ãã§ãïŒã
äŸãã°æ¬¡ã®éãã§ãã
spec.add_dependency 'pg', '~> 1.0'
å倿
Pgã§ã¯ä»»æã§RubyãšçŽ ã®Cã³ãŒãã«ããçµæã®å€ãåãåããåŒæ°ã®å倿ãã§ããŸããããããããšã§ããŒã¿ããŒã¹ãšã®ããŒã¿ã®åŸæ¥ãå éãããããŸãããªããªãæååã®ã¢ãã±ãŒã·ã§ã³ãæžããïŒæ¯èŒçé ãïŒRubyã®ã³ãŒãã§ã®å€æéšåãçãããããã§ãã
ãšãŠãåºæ¬çãªåå€æã¯æ¬¡ã®ããã«ã§ããŸãã
conn.type_map_for_results = PG::BasicTypeMapForResults.new conn # âŠâŠããã¯çµæã®å€ã®å¯Ÿå¿ä»ãã«äœçšããŸãã conn.exec("select 1, now(), '{2,3}'::int[]").values # => [[1, 2014-09-21 20:51:56 +0200, [2, 3]]] conn.type_map_for_queries = PG::BasicTypeMapForQueries.new conn # âŠâŠãããŠããã¯åŒæ°å€ã®å¯Ÿå¿ä»ãã®ããã®ãã®ã§ãã conn.exec_params("SELECT $1::text, $2::text, $3::text", [1, 1.23, [2,3]]).values # => [["1", "1.2300000000000000E+00", "{2,3}"]]
ãããPgã®å倿ã¯ããªã調æŽãå¹ããŸãã2å±€ã«åãããŠããã®ããã®çç±ã§ãã
ãšã³ã³ãŒããŒãšãã³ãŒã㌠(ext/pg_*coder.c, lib/pg/*coder.rb)
ãã¡ãã¯ããäœå±€ã§ãDBMSãžè»¢éããããã«Rubyã®ãªããžã§ã¯ãã倿ãããšã³ã³ãŒãã£ã³ã°ã¯ã©ã¹ãšãååŸããŠããããŒã¿ãRubyã®ãªããžã§ã¯ãã«å€æãæ»ããã³ãŒãã£ã³ã°ã¯ã©ã¹ãå«ãŸããŠããŸããã¯ã©ã¹ã¯ããããã®åœ¢åŒã«ãã£ãŠåå空é PG::TextEncoder, PG::TextDecoder, PG::BinaryEncoder, PG::BinaryDecoder ã«åãããŠããŸãã
ãšã³ã³ãŒããŒãªãããã³ãŒããŒãªããžã§ã¯ãã«OIDããŒã¿åã圢åŒã³ãŒãïŒããã¹ããªãããã€ããªïŒãä»»æã§ååãå²ãåœãŠãããšãã§ããŸããèŠçŽ ã®ãšã³ã³ãŒããŒãªãããã³ãŒããŒãå²ãåœãŠãããšã«ãã£ãŠè€ååãæ§ç¯ããããšãã§ããŸããPG::Coder ãªããžã§ã¯ã㯠PG::TypeMap ãã»ããã¢ãããããããã®ä»£ããã«åäžã®å€ãšæåå衚çŸãšãçžäºã«å€æãããããã®ã«äœ¿ããŸãã
ruby-pgã§ã¯ä»¥äžã®PostgreSQLã«ã©ã åã«å¯Ÿå¿ããŠããŸãïŒTE = Text EncoderãTD = Text DecoderãBE = Binary EncoderãBD = Binary DecoderïŒã
-
Integer: TEãTDãBD ð¡ ãªã³ã¯ããªãã§ããããããã¡ãã代ããã«èŠãŠãã ãã ð¡
-
Timestamp:
-
TE: çŸå°æéãUTCãã¿ã€ã ãŸãŒã³ä»ã
-
TD: çŸå°æéãUTCãUTCããçŸå°æéãž
-
BE: çŸå°æéãUTC
-
BD: çŸå°æéãUTCãUTCããçŸå°æéãž
-
-
è€ååïŒãè¡ãããã¬ã³ãŒãããªã©ãšãèšããŸãïŒïŒTEãTD
ã«ã©ã åãšããŠäœ¿ãããŠããŸãããã以äžã®ããã¹ã圢åŒãšãã€ããªåœ¢åŒããšã³ã³ãŒãã§ããŸãã
-
SQLæååã«æ¿å ¥ãããªãã©ã«ïŒTE
TypeMap ãšãã®æŽŸç (ext/pg_type_map*.c, lib/pg/type_map*.rb)
PG::TypeMap ã¯ã©ã®ãšã³ã³ãŒããŒãªãããã³ãŒããŒã«ãã£ãŠã©ã®å€ã倿ãããããå®çŸ©ããŸããæ§ã
ãªåã®å¯Ÿå¿ä»ãã®æŠç¥ãããããã®ã¯ã©ã¹ã®è€æ°ã®æŽŸçã«ããå®è£
ãããŠããŸããå倿ã®ç¹æã®éèŠã«åãããŠãããããéžãã§æ§æã§ããŸããæ¢å®ã®åã®å¯Ÿå¿ä»ã㯠PG::TypeMapAllStrings ã§ãã
åã®å¯Ÿå¿ä»ãã¯ãçµæã®éåããããã«å¯Ÿããæ¥ç¶æ¯ãªããåãåããæ¯ã«å²ãåœãŠãããšãã§ããŸããåã®å¯Ÿå¿ä»ãã¯COPYã®å ¥åºåããŒã¿ã¹ããªãŒãã³ã°ã§ã䜿ãããšãã§ããŸããPG::Connection#copy_data ãåç §ããŠãã ããã
以äžã®åºåºãšãªãåã®å¯Ÿå¿ä»ãã䜿ããŸãã
-
PG::TypeMapAllStrings- å šãŠã®å€ãšæååã«ã€ããŠçžäºã«ãšã³ã³ãŒããšãã³ãŒããè¡ããŸãïŒæ¢å®ïŒ -
PG::TypeMapByClass- éä¿¡ããå€ã®ã¯ã©ã¹ã«åºã¥ããŠãšã³ã³ãŒããŒãéžæããŸã -
PG::TypeMapByColumn- ã«ã©ã ã®é çªã«ãã£ãŠãšã³ã³ãŒããŒãšãã³ãŒããŒãéžæããŸã -
PG::TypeMapByOid- PostgreSQLã®OIDããŒã¿åã«ãã£ãŠãã³ãŒããŒãéžæããŸã -
PG::TypeMapInRuby- Rubyã§ç¬èªã®åã®å¯Ÿå¿ä»ããå®çŸ©ããŸã
以äžã®åã®å¯Ÿå¿ä»ã㯠PG::BasicTypeRegistry ç±æ¥ã®åã®å¯Ÿå¿ä»ããå
¥ã£ãç¶æ
ã«ãªã£ãŠããŸãã
-
PG::BasicTypeMapForResults-PG::TypeMapByOidã«ããããPostgreSQLã«ã©ã åçšã«ãã³ãŒããŒãå ¥ã£ãç¶æ ã«ãªã£ãŠããŸã -
PG::BasicTypeMapBasedOnResult-PG::TypeMapByOidã«ããããPostgreSQLã«ã©ã åçšã®ãšã³ã³ãŒããŒãå ¥ã£ãç¶æ ã«ãªã£ãŠããŸã -
PG::BasicTypeMapForQueries-PG::TypeMapByClassã«ããããRubyã®å€ã¯ã©ã¹çšã«ãšã³ã³ãŒããŒãå ¥ã£ãç¶æ ã«ãªã£ãŠããŸã
PG::TypeMap::DefaultTypeMappable#default_type_mapãèšå®ããããšã§è€æ°ã®åã®å¯Ÿå¿ä»ããé£éãããããŸãã
ã¹ã¬ãã察å¿
PG ã«ã¯åã
ã®ã¹ã¬ãããªãããã¡ã€ããåã
ã® PG::Connection ãªããžã§ã¯ãã䞊è¡ã«äœ¿ãããšããç¹ã§ã¹ã¬ããå®å
šã§ããããããªãã1ã€ä»¥äžã®ã¹ã¬ãããªãããã¡ã€ãããåæã«äœããã® PG ã®ãªããžã§ã¯ãã«ã¢ã¯ã»ã¹ããã®ã¯å®å
šã§ã¯ãããŸããããã®ããå¿
ããæ°ããã¹ã¬ãããªãããã¡ã€ãã®äžã€äžã€ã«å¯ŸããŠæ°ããããŒã¿ããŒã¹ãµãŒããŒæ¥ç¶ãéãããã¹ã¬ããå®å
šãªæ¹æ³ã§æ¥ç¶ã管çããActiveRecordã®ãããªã©ãããŒã©ã€ãã©ãªã䜿ã£ãŠãã ããã
以äžã®ãããªã¡ãã»ãŒãžãæšæºãšã©ãŒåºåã«è¡šç€ºãããå Žåãæããè€æ°ã®ã¹ã¬ããã1ã€ã®æ¥ç¶ã䜿ã£ãŠããŸãã
message type 0x31 arrived from server while idle message type 0x32 arrived from server while idle message type 0x54 arrived from server while idle message type 0x43 arrived from server while idle message type 0x5a arrived from server while idle
Fiber IOã¹ã±ãžã¥ãŒã©ãŒå¯Ÿå¿
pg-1.3.0以éã§ãPgã¯Ruby-3.0ã§å°å
¥ãããFiber.schedulerã«å®å
šã«å¯Ÿå¿ããŠããŸããFiber.schedulerãèµ°ãããŠããã¹ã¬ããã«ç»é²ãããŠããå Žåãèµ·ããããå
šãŠã®ããããã³ã°IOæäœã¯ãã®ã¹ã±ãžã¥ãŒã©ãŒãçµç±ããŸããåæçã§ãã£ãããããã¯ãããããã¡ãœããåŒã³åºãã«ã€ããŠãpgãå
éšçã«éåæã®libpqã€ã³ã¿ãŒãã§ãŒã¹ã䜿ã£ãŠããã®ã¯ãããçç±ã§ãããŸãlibpqã®çµã¿èŸŒã¿é¢æ°ã«ä»£ããŠRubyã®DNS解決ã䜿ã£ãŠããŸãã
å
éšçã« Pg ã¯åžžã«libpqã®ãã³ããããã³ã°æ¥ç¶ã¢ãŒãã䜿ããŸããããããããããã³ã°ã¢ãŒãã§èµ°ã£ãŠããããã«æ¯èããŸããããã¹ãŠã®ããããã³ã°IOããå¯èœã§ããã°ç»é²ãããFiber.schedularãéããŠã確å®ã«Rubyã§å¶åŸ¡ãããŸããPG::Connection.setnonblocking(true)ãåŒã°ããããã³ããããã³ã°ç¶æ
ãæå¹ã«ãªã£ããŸãŸã«ãªããŸããããã以éã®ããããã³ã°ç¶æ
ã®å¶åŸ¡ãç¡å¹ã«ãªãã®ã§ãåŒã³åºããŠããããã°ã©ã ã¯ããããã³ã°ç¶æ
ãèªåã§å¶åŸ¡ããªããã°ãªããŸããã
ãã®èŠåã®1ã€ã®äŸå€ã«ã¯ãPG::Connection#lo_createãå€éšã©ã€ãã©ãªã䜿ãèªèšŒã¡ãœããïŒGSSAPIèªèšŒãªã©ïŒã®ãããªã倧ããã®ãªããžã§ã¯ãçšã®ã¡ãœããããããŸãããããã¯Fiber.schedulerãšäºææ§ããªããããããããã³ã°ç¶æ
ã¯ç»é²ãããIOã¹ã±ãžã¥ãŒã©ã«æž¡ãããŸãããã€ãŸãæäœã¯é©åã«å®è¡ãããŸãããIOåŸ
ã¡ç¶æ
ã«å¥ã®IOãæ±ãFiberãã䜿çšãåãæ¿ããŠããããšãã§ããªããªããŸãã
Ractor察å¿
pg-1.5.0以éã§ãPgã¯Ruby-3.0ã§å°å
¥ãããRactorãšå®å
šãªäºææ§ããããŸããåãšã³ã³ãŒããŒãªãããã³ãŒããŒãåã³åã®å¯Ÿå¿ä»ããRactor.make_shareableã«ããåçµãããŠããå Žåãããããractoréã§å
±æã§ããŸãããŸãåçµããã PG::Result ãš PG::Tuple ãªããžã§ã¯ããå
±æã§ããŸããå°ãªããšãå
šãŠã®åçµããããªããžã§ã¯ãïŒãã ã PG::Connectionãé€ãïŒã¯PostgreSQLãµãŒããŒãšã®ããåãããããååŸãããããŒã¿ãèªãã®ã«äœ¿ããŸãã
PG::Connection ã¯å
±æã§ããŸãããåã
ã®æ¥ç¶ã確ç«ããããã«ãããããã®Ractorå
ã§äœãããªããã°ãªããŸããã
è²¢ç®
ãã°ãå ±åãããæ©èœãææ¡ãããGitã§ãœãŒã¹ããã§ãã¯ã¢ãŠããããããã«ã¯ãããžã§ã¯ãããŒãžãã確èªãã ããã
ãœãŒã¹ããã§ãã¯ã¢ãŠãããããšã¯å šãŠã®äŸåé¢ä¿ãã€ã³ã¹ããŒã«ããŸãã
$ bundle install
æ¡åŒµãã¡ã€ã«ãããã±ãŒãžãã¡ã€ã«ããã¹ãããŒã¿ããŒã¹ãäžæããã«ã¯ããã®ã³ãã³ããèµ°ãããŠãã ãããPostgreSQLã®ããŒãžã§ã³ãåãæ¿ãããŸãã
$ rake clean
æ¡åŒµãã³ã³ãã€ã«ããã«ã¯æ¬¡ã®ããã«ããŸãã
$ rake compile
pg_config --bindirãæãPostgreSQLã®ããŒãžã§ã³ã§ãã¹ããã¹ããã¯ãèµ°ãããã«ã¯æ¬¡ã®ããã«ããŸãã
$ rake test
ãããã¯ç¹å®ã®PostgreSQLã®ããŒãžã§ã³ã§ããã¡ã€ã«äžã®è¡çªå·ã䜿ã£ãŠç¹å®ã®ãã¹ããèµ°ãããã«ã¯æ¬¡ã®ããã«ããŸãã
$ PATH=/usr/lib/postgresql/14/bin:$PATH rspec -Ilib -fd spec/pg/connection_spec.rb:455
APIããã¥ã¡ã³ããçæããã«ã¯æ¬¡ã®ããã«ããŸãã
$ rake docs
å¿ ãå šãŠã®ãã°ãšæ°æ©èœã«ã€ããŠãã¹ãã䜿ã£ãŠæ€èšŒããŠãã ããã
çŸåšã®ã¡ã³ããã¯Michael Granger ged@FaerieMUD.orgãšLars Kanis lars@greiz-reinsdorf.deã§ãã
èäœæš©
Copyright © 1997-2022 by the authors.
-
Jeff Davis ruby-pg@j-davis.com
-
Guy Decoux (ts) decoux@moulon.inra.fr
-
Michael Granger ged@FaerieMUD.org
-
Lars Kanis lars@greiz-reinsdorf.de
-
Dave Lee
-
Eiji Matsumoto usagi@ruby.club.or.jp
-
Yukihiro Matsumoto matz@ruby-lang.org
-
Noboru Saitou noborus@netlab.jp
You may redistribute this software under the same terms as Ruby itself; see www.ruby-lang.org/en/about/license.txt or the BSDL file in the source for details.ïŒåèèš³ïŒãã®ãœãããŠã§ã¢ã¯Rubyèªäœãšåãæ¡ä»¶ã®å ã§åé åžããããšãã§ããŸãã詳现ã«ã€ããŠã¯www.ruby-lang.org/en/about/license.txt ããœãŒã¹äžã®BSDLãã¡ã€ã«ãåç §ããŠãã ããïŒ
Portions of the code are from the PostgreSQL project, and are distributed â âunder the terms of the PostgreSQL license, included in the file POSTGRES.ïŒåèèš³ïŒã³ãŒãã®äžéšã¯PostgreSQLãããžã§ã¯ãããæ¥ãŠãããPostgreSQLã®äœ¿çšèš±è«Ÿã®æ¡ä»¶ã®å ã§é åžãããŸãããã¡ã€ã«POSTGRESã«å«ãŸããŠããŸãïŒ
Portions copyright LAIKA, Inc.
è¬èŸ
é·å¹Žã«ããã£ãŠè²¢ç®ããŠãã ãã£ãæ¹ã ã«ã€ããŠã¯ Contributors.rdoc ãåç §ããŠãã ããã
ruby-listãšruby-devã¡ãŒãªã³ã°ãªã¹ãã®æ¹ã ã«æè¬ããŸãããŸãPostgreSQLãéçºãããæ¹ã ãžãè¬æã衚ããŸãã