F.65. xml2
ÐодÑÐ»Ñ xml2 пÑедоÑÑавлÑÐµÑ ÑÑнкÑии Ð´Ð»Ñ Ð²ÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð·Ð°Ð¿ÑоÑов XPath и пÑеобÑазований XSLT.
F.65.1. Уведомление об акÑÑалÑноÑÑи
ÐаÑÐ¸Ð½Ð°Ñ Ñ PostgreSQL 8.3, ÑÑнкÑионалÑноÑÑÑ, ÑвÑÐ·Ð°Ð½Ð½Ð°Ñ Ñ XML, оÑнована на ÑÑандаÑÑе SQL/XML и вклÑÑена в ÑдÑо ÑеÑвеÑа. ÐÑа ÑÑнкÑионалÑноÑÑÑ Ð¾Ñ
ваÑÑÐ²Ð°ÐµÑ Ð¿ÑовеÑÐºÑ ÑинÑакÑиÑа XML и запÑоÑÑ XPath, ÑÑо в ÑаÑÑноÑÑи Ð´ÐµÐ»Ð°ÐµÑ Ð¸ ÑÑÐ¾Ñ Ð¼Ð¾Ð´ÑлÑ, но он Ð¸Ð¼ÐµÐµÑ Ð°Ð±ÑолÑÑно неÑовмеÑÑимÑй API. ÐÑÐ¾Ñ Ð¼Ð¾Ð´ÑÐ»Ñ Ð¿Ð»Ð°Ð½Ð¸ÑÑеÑÑÑ ÑдалиÑÑ Ð² бÑдÑÑей веÑÑии Postgres Pro в полÑÐ·Ñ Ð½Ð¾Ð²Ð¾Ð³Ð¾ ÑÑандаÑÑного API, Ñак ÑÑо Ð¼Ñ ÑекомендÑем вам попÑобоваÑÑ Ð¿ÐµÑевеÑÑи Ñвои пÑÐ¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð½Ð° новÑй API. ÐÑли Ð²Ñ Ð¾Ð±Ð½Ð°ÑÑжиÑе, ÑÑо какаÑ-Ñо ÑÑнкÑионалÑноÑÑÑ ÑÑого модÑÐ»Ñ Ð½Ðµ пÑедÑÑавлена новÑм API в подÑ
одÑÑей ÑоÑме, пожалÑйÑÑа, напиÑиÑе о ваÑем заÑÑÑднении в <pgsql-hackers@lists.postgresql.org>, ÑÑÐ¾Ð±Ñ ÑÑÐ¾Ñ Ð½ÐµÐ´Ð¾ÑÑаÑок бÑл ÑаÑÑмоÑÑен и, возможно, ÑÑÑÑанÑн.
F.65.2. ÐпиÑание ÑÑнкÑий
ФÑнкÑии, пÑедоÑÑавлÑемÑе ÑÑим модÑлем, пеÑеÑиÑÐ»ÐµÐ½Ñ Ð² ТаблиÑе F.44. ÐÑи ÑÑнкÑии позволÑÑÑ Ð²ÑполнÑÑÑ Ð¿ÑоÑÑой ÑÐ°Ð·Ð±Ð¾Ñ XML и запÑоÑÑ XPath.
ТаблиÑа F.44. ФÑнкÑии xml2
ФÑнкÑÐ¸Ñ ÐпиÑание |
|---|
РазбиÑÐ°ÐµÑ ÑекÑÑ Ð¿ÐµÑеданного докÑменÑа и возвÑаÑÐ°ÐµÑ true, еÑли ÑÑо пÑавилÑно ÑÑоÑмиÑованнÑй XML. (ÐамеÑание: ÑÑо пÑевдоним ÑÑандаÑÑной ÑÑнкÑии Postgres Pro |
ÐбÑабаÑÑÐ²Ð°ÐµÑ Ð·Ð°Ð¿ÑÐ¾Ñ XPath Ð´Ð»Ñ Ð¿ÐµÑеданного докÑменÑа и пÑÐ¸Ð²Ð¾Ð´Ð¸Ñ ÑезÑлÑÑÐ°Ñ Ðº ÑÐ¸Ð¿Ñ |
ÐбÑабаÑÑÐ²Ð°ÐµÑ Ð·Ð°Ð¿ÑÐ¾Ñ XPath Ð´Ð»Ñ Ð¿ÐµÑеданного докÑменÑа и пÑÐ¸Ð²Ð¾Ð´Ð¸Ñ ÑезÑлÑÑÐ°Ñ Ðº ÑÐ¸Ð¿Ñ |
ÐбÑабаÑÑÐ²Ð°ÐµÑ Ð·Ð°Ð¿ÑÐ¾Ñ XPath Ð´Ð»Ñ Ð¿ÐµÑеданного докÑменÑа и пÑÐ¸Ð²Ð¾Ð´Ð¸Ñ ÑезÑлÑÑÐ°Ñ Ðº ÑÐ¸Ð¿Ñ |
ÐбÑабаÑÑÐ²Ð°ÐµÑ Ð·Ð°Ð¿ÑÐ¾Ñ Ð´Ð»Ñ Ð´Ð¾ÐºÑменÑа и помеÑÐ°ÐµÑ ÑезÑлÑÑÐ°Ñ Ð²Ð½ÑÑÑÑ XML-Ñегов. ÐÑли ÑезÑлÑÑÐ°Ñ ÑодеÑÐ¶Ð¸Ñ Ð½ÐµÑколÑко знаÑений, она вÑдаÑÑ: <toptag> <itemtag>ÐнаÑение 1, коÑоÑое Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ ÑÑагменÑом XML</itemtag> <itemtag>ÐнаÑение 2....</itemtag> </toptag> ÐÑли |
Ðодобна |
Ðодобна |
ÐбÑабаÑÑÐ²Ð°ÐµÑ Ð·Ð°Ð¿ÑÐ¾Ñ XPath Ð´Ð»Ñ Ð´Ð¾ÐºÑменÑа и возвÑаÑÐ°ÐµÑ Ð½ÐµÑколÑко знаÑений, вÑÑавлÑÑ Ð¼ÐµÐ¶Ð´Ñ Ð½Ð¸Ð¼Ð¸ заданнÑй ÑазделиÑÐµÐ»Ñ ( |
ÐÑо обÑÑÑка пÑедÑдÑÑей ÑÑнкÑии, ÑÑÑанавливаÑÑÐ°Ñ Ð² каÑеÑÑве ÑазделиÑÐµÐ»Ñ Ð·Ð½Ð°Ðº |
F.65.3. xpath_table
xpath_table(text key, text document, text relation, text xpaths, text criteria) returns setof record
ТаблиÑÐ½Ð°Ñ ÑÑнкÑÐ¸Ñ xpath_table вÑполнÑÐµÑ Ð½Ð°Ð±Ð¾Ñ Ð·Ð°Ð¿ÑоÑов XPath Ð´Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾ из набоÑа докÑменÑов и возвÑаÑÐ°ÐµÑ ÑезÑлÑÑаÑÑ Ð² виде ÑаблиÑÑ. РпеÑвом ÑÑолбÑе ÑезÑлÑÑаÑа возвÑаÑаеÑÑÑ Ð¿ÐµÑвиÑнÑй клÑÑ Ð¸Ð· ÑаблиÑÑ Ð´Ð¾ÐºÑменÑов, Ñак ÑÑо ÑезÑлÑÑÐ°Ñ Ð¾ÐºÐ°Ð·ÑваеÑÑÑ Ð³Ð¾ÑовÑм к пÑÐ¸Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð² ÑоединениÑÑ
. ÐаÑамеÑÑÑ ÑÑнкÑии опиÑÐ°Ð½Ñ Ð² ТаблиÑе F.45.
ТаблиÑа F.45. ÐаÑамеÑÑÑ xpath_table
| ÐаÑамеÑÑ | ÐпиÑание |
|---|---|
key | Ð¸Ð¼Ñ Â«ÐºÐ»ÑÑевого» Ð¿Ð¾Ð»Ñ â ÑодеÑжимое ÑÑого Ð¿Ð¾Ð»Ñ Ð¿ÑоÑÑо окажеÑÑÑ Ð² пеÑвом ÑÑолбÑе вÑÑ Ð¾Ð´Ð½Ð¾Ð¹ ÑаблиÑÑ, Ñо еÑÑÑ Ð¾Ð½Ð¾ ÑказÑÐ²Ð°ÐµÑ Ð½Ð° запиÑÑ, из коÑоÑой бÑла полÑÑена опÑеделÑÐ½Ð½Ð°Ñ Ð²ÑÑ Ð¾Ð´Ð½Ð°Ñ ÑÑÑока (Ñм. замеÑание о неÑколÑÐºÐ¸Ñ Ð·Ð½Ð°ÑениÑÑ Ð½Ð¸Ð¶Ðµ) |
document | Ð¸Ð¼Ñ Ð¿Ð¾Ð»Ñ, ÑодеÑжаÑего XML-докÑÐ¼ÐµÐ½Ñ |
relation | Ð¸Ð¼Ñ ÑаблиÑÑ (или пÑедÑÑавлениÑ), ÑодеÑжаÑей докÑменÑÑ |
xpaths | одно или неÑколÑко вÑÑажений XPath, ÑазделÑннÑÑ
Ñимволом |
criteria | ÑодеÑжимое пÑÐµÐ´Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ WHERE. Ðно не Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð¿ÑÑÑÑм, Ñак ÑÑо еÑли вам нÑжно обÑабоÑаÑÑ Ð²Ñе ÑÑÑоки в оÑноÑении, напиÑиÑе |
ÐÑи паÑамеÑÑÑ (за иÑклÑÑением ÑÑÑок XPath) пÑоÑÑо подÑÑавлÑÑÑÑÑ Ð² обÑÑнÑй опеÑаÑÐ¾Ñ SQL SELECT, Ñак ÑÑо Ñ Ð²Ð°Ñ ÐµÑÑÑ Ð¾Ð¿ÑеделÑÐ½Ð½Ð°Ñ Ð³Ð¸Ð±ÐºÐ¾ÑÑÑ â опеÑаÑÐ¾Ñ Ð²ÑглÑÐ´Ð¸Ñ Ñак:
SELECT <key>, <document> FROM <relation> WHERE <criteria>
поÑÑÐ¾Ð¼Ñ Ð² ÑÑÐ¸Ñ Ð¿Ð°ÑамеÑÑÐ°Ñ Ð¼Ð¾Ð¶Ð½Ð¾ пеÑедаÑÑ Ð²ÑÑ, ÑÑо бÑÐ´ÐµÑ ÐºÐ¾ÑÑекÑно воÑпÑинÑÑо в ÑÑÐ¸Ñ Ð¿Ð¾Ð·Ð¸ÑиÑÑ . ÐÑÐ¾Ñ SELECT должен возвÑаÑаÑÑ Ñовно два ÑÑолбÑа (ÑÑо и бÑÐ´ÐµÑ Ð¸Ð¼ÐµÑÑ Ð¼ÐµÑÑо, еÑли ÑолÑко Ð²Ñ Ð½Ðµ пеÑеÑиÑлиÑе неÑколÑко полей в паÑамеÑÑÐ°Ñ key или document). ÐÑдÑÑе оÑÑоÑÐ¾Ð¶Ð½Ñ â пÑи Ñаком пÑимиÑивном Ð¿Ð¾Ð´Ñ Ð¾Ð´Ðµ обÑзаÑелÑно нÑжно пÑовеÑÑÑÑ Ð²Ñе знаÑениÑ, полÑÑаемÑе Ð¾Ñ Ð¿Ð¾Ð»ÑзоваÑелÑ, во избежание аÑак Ñ Ð¸Ð½ÑекÑией SQL.
ÐÑа ÑÑнкÑÐ¸Ñ Ð¿ÑедназнаÑена Ð´Ð»Ñ Ð¸ÑполÑÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð² вÑÑажении FROM, Ñ Ð¿Ñедложением AS, задаÑÑим вÑÑ
однÑе ÑÑолбÑÑ; напÑимеÑ:
SELECT * FROM
xpath_table('article_id',
'article_xml',
'articles',
'/article/author|/article/pages|/article/title',
'date_entered > ''2003-01-01'' ')
AS t(article_id integer, author text, page_count integer, title text); ÐÑедложение AS опÑеделÑÐµÑ Ð¸Ð¼ÐµÐ½Ð° и ÑÐ¸Ð¿Ñ ÑÑолбÑов в вÑÑ
одной ÑаблиÑе. ÐеÑвÑм опÑеделÑеÑÑÑ Â«ÐºÐ»ÑÑевое» поле, а за ним полÑ, ÑооÑвеÑÑÑвÑÑÑие запÑоÑам XPath. ÐÑли запÑоÑов XPath болÑÑе, Ñем ÑÑолбÑов в ÑезÑлÑÑаÑе, лиÑние запÑоÑÑ Ð±ÑдÑÑ Ð¸Ð³Ð½Ð¾ÑиÑоваÑÑÑÑ. ÐÑли же ÑезÑлÑÑиÑÑÑÑиÑ
ÑÑолбÑов болÑÑе, Ñем запÑоÑов XPath, дополниÑелÑнÑе ÑÑолбÑÑ Ð¿ÑинимаÑÑ Ð·Ð½Ð°Ñение NULL.
ÐамеÑÑÑе, ÑÑо в ÑÑом пÑимеÑе ÑÑÐ¾Ð»Ð±ÐµÑ ÑезÑлÑÑаÑа page_count опÑеделÑн как ÑелоÑиÑленнÑй. ÐÐ°Ð½Ð½Ð°Ñ ÑÑнкÑÐ¸Ñ Ð²Ð½ÑÑÑи Ð¸Ð¼ÐµÐµÑ Ð´ÐµÐ»Ð¾ Ñо ÑÑÑоковÑми знаÑениÑми, Ñак ÑÑо, когда Ð²Ñ ÑказÑваеÑе, ÑÑо в ÑезÑлÑÑаÑе нÑжно полÑÑиÑÑ Ñелое ÑиÑло, она беÑÑÑ ÑекÑÑовое пÑедÑÑавление ÑезÑлÑÑаÑа XPath и, пÑименÑÑ ÑÑнкÑии ввода Postgres Pro, пÑеобÑазÑÐµÑ ÐµÑ Ð² Ñелое ÑиÑло (или в ÑÐ¾Ñ Ñип, коÑоÑÑй Ñказан в пÑедложении AS). ÐÑли она не ÑÐ¼Ð¾Ð¶ÐµÑ ÑделаÑÑ ÑÑо, пÑоизойдÑÑ Ð¾Ñибка â напÑимеÑ, еÑли ÑезÑлÑÑÐ°Ñ Ð¿ÑÑÑой â Ñак ÑÑо еÑли Ð²Ñ Ð´Ð¾Ð¿ÑÑкаеÑе возможноÑÑÑ ÑакиÑ
пÑоблем Ñ Ð´Ð°Ð½Ð½Ñми, возможно, бÑÐ´ÐµÑ Ð»ÑÑÑе пÑоÑÑо оÑÑавиÑÑ Ð´Ð»Ñ ÑÑолбÑа Ñип text.
ÐÑзÑваÑÑий опеÑаÑÐ¾Ñ SELECT не обÑзаÑелÑно должен бÑÑÑ Ð¿ÑоÑÑÑм SELECT * â он Ð¼Ð¾Ð¶ÐµÑ Ð¾Ð±ÑаÑаÑÑÑÑ Ðº вÑÑ
однÑм ÑÑолбÑам по именам и ÑоединÑÑÑ Ð¸Ñ
Ñ Ð´ÑÑгими ÑаблиÑами. ÐÑа ÑÑнкÑÐ¸Ñ ÑоÑмиÑÑÐµÑ Ð²Ð¸ÑÑÑалÑнÑÑ ÑаблиÑÑ, Ñ ÐºÐ¾ÑоÑой Ð²Ñ Ð¼Ð¾Ð¶ÐµÑе вÑполнÑÑÑ Ð»ÑбÑе опеÑаÑии, какие пожелаеÑе (напÑимеÑ, агÑегиÑоваÑÑ, ÑоединÑÑÑ, ÑоÑÑиÑоваÑÑ Ð´Ð°Ð½Ð½Ñе и Ñ. д.). ÐоÑÑÐ¾Ð¼Ñ Ð²Ð¾Ð·Ð¼Ð¾Ð¶ÐµÐ½ и Ñакой запÑоÑ:
SELECT t.title, p.fullname, p.email
FROM xpath_table('article_id', 'article_xml', 'articles',
'/article/title|/article/author/@id',
'xpath_string(article_xml,''/article/@date'') > ''2003-03-20'' ')
AS t(article_id integer, title text, author_id integer),
tblPeopleInfo AS p
WHERE t.author_id = p.person_id;в каÑеÑÑве более Ñложного пÑимеÑа. РазÑмееÑÑÑ, Ð´Ð»Ñ ÑдобÑÑва Ð²Ñ Ð¼Ð¾Ð¶ÐµÑе завеÑнÑÑÑ Ð²ÐµÑÑ ÑÑÐ¾Ñ Ð·Ð°Ð¿ÑÐ¾Ñ Ð² пÑедÑÑавление.
F.65.3.1. РезÑлÑÑаÑÑ Ñ Ð½Ð°Ð±Ð¾Ñом знаÑений
ФÑнкÑÐ¸Ñ xpath_table ÑаÑÑÑиÑана на Ñо, ÑÑо ÑезÑлÑÑаÑом каждого запÑоÑа XPath Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð½Ð°Ð±Ð¾Ñ Ð´Ð°Ð½Ð½ÑÑ
, Ñак ÑÑо колиÑеÑÑво возвÑаÑÑннÑÑ
ÑÑой ÑÑнкÑией ÑÑÑок Ð¼Ð¾Ð¶ÐµÑ Ð½Ðµ ÑовпадаÑÑ Ñ ÐºÐ¾Ð»Ð¸ÑеÑÑвом вÑ
однÑÑ
докÑменÑов. РпеÑвой ÑÑÑоке возвÑаÑаеÑÑÑ Ð¿ÐµÑвÑй ÑезÑлÑÑÐ°Ñ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾ запÑоÑа, во вÑоÑой â вÑоÑой ÑезÑлÑÑÐ°Ñ Ð¸ Ñ. д. ÐÑли один из запÑоÑов возвÑаÑÐ°ÐµÑ Ð¼ÐµÐ½ÑÑе знаÑений, Ñем дÑÑгие, вмеÑÑо недоÑÑаÑÑиÑ
знаÑений бÑÐ´ÐµÑ Ð²Ð¾Ð·Ð²ÑаÑаÑÑÑÑ NULL.
РнекоÑоÑÑÑ ÑлÑÑаÑÑ Ð¿Ð¾Ð»ÑзоваÑÐµÐ»Ñ Ð·Ð½Ð°ÐµÑ, ÑÑо некоÑоÑÑй запÑÐ¾Ñ XPath бÑÐ´ÐµÑ Ð²Ð¾Ð·Ð²ÑаÑаÑÑ ÑолÑко один ÑезÑлÑÑÐ°Ñ (возможно, ÑникалÑнÑй иденÑиÑикаÑÐ¾Ñ Ð´Ð¾ÐºÑменÑа) â еÑли он иÑполÑзÑеÑÑÑ ÑÑдом Ñ Ð·Ð°Ð¿ÑоÑом XPath, возвÑаÑаÑÑим неÑколÑко ÑезÑлÑÑаÑов, ÑезÑлÑÑÐ°Ñ Ñ Ð¾Ð´Ð½Ð¸Ð¼ знаÑением бÑÐ´ÐµÑ Ð²Ñведен ÑолÑко в пеÑвой вÑÑ Ð¾Ð´Ð½Ð¾Ð¹ ÑÑÑоке. ЧÑÐ¾Ð±Ñ Ð¸ÑпÑавиÑÑ ÑÑо, можно воÑполÑзоваÑÑÑÑ Ð¿Ð¾Ð»ÐµÐ¼ клÑÑа и ÑоединиÑÑ ÑезÑлÑÑÐ°Ñ Ñ Ð±Ð¾Ð»ÐµÐµ пÑоÑÑÑм запÑоÑом XPath. ÐапÑимеÑ:
CREATE TABLE test (
id int PRIMARY KEY,
xml text
);
INSERT INTO test VALUES (1, '<doc num="C1">
<line num="L1"><a>1</a><b>2</b><c>3</c></line>
<line num="L2"><a>11</a><b>22</b><c>33</c></line>
</doc>');
INSERT INTO test VALUES (2, '<doc num="C2">
<line num="L1"><a>111</a><b>222</b><c>333</c></line>
<line num="L2"><a>111</a><b>222</b><c>333</c></line>
</doc>');
SELECT * FROM
xpath_table('id','xml','test',
'/doc/@num|/doc/line/@num|/doc/line/a|/doc/line/b|/doc/line/c',
'true')
AS t(id int, doc_num varchar(10), line_num varchar(10), val1 int, val2 int, val3 int)
WHERE id = 1 ORDER BY doc_num, line_num
id | doc_num | line_num | val1 | val2 | val3
----+---------+----------+------+------+------
1 | C1 | L1 | 1 | 2 | 3
1 | | L2 | 11 | 22 | 33ЧÑÐ¾Ð±Ñ Ð¿Ð¾Ð»ÑÑиÑÑ doc_num в каждой ÑÑÑоке, можно вÑзÑваÑÑ xpath_table Ð´Ð²Ð°Ð¶Ð´Ñ Ð¸ ÑоединиÑÑ ÑезÑлÑÑаÑÑ:
SELECT t.*,i.doc_num FROM
xpath_table('id', 'xml', 'test',
'/doc/line/@num|/doc/line/a|/doc/line/b|/doc/line/c',
'true')
AS t(id int, line_num varchar(10), val1 int, val2 int, val3 int),
xpath_table('id', 'xml', 'test', '/doc/@num', 'true')
AS i(id int, doc_num varchar(10))
WHERE i.id=t.id AND i.id=1
ORDER BY doc_num, line_num;
id | line_num | val1 | val2 | val3 | doc_num
----+----------+------+------+------+---------
1 | L1 | 1 | 2 | 3 | C1
1 | L2 | 11 | 22 | 33 | C1
(2 rows)F.65.4. ФÑнкÑии XSLT
ÐÑли ÑÑÑановлена libxslt, доÑÑÑÐ¿Ð½Ñ ÑледÑÑÑие ÑÑнкÑии:
F.65.4.1. xslt_process
xslt_process(text document, text stylesheet, text paramlist) returns text
ÐÑа ÑÑнкÑÐ¸Ñ Ð¿ÑименÑÐµÑ ÑÑÐ¸Ð»Ñ XSL к докÑменÑÑ Ð¸ возвÑаÑÐ°ÐµÑ ÑезÑлÑÑÐ°Ñ Ð¿ÑеобÑазованиÑ. Ð paramlist пеÑедаÑÑÑÑ ÑпиÑок пÑиÑваиваний знаÑений паÑамеÑÑам, коÑоÑÑе бÑдÑÑ Ð¸ÑполÑзоваÑÑÑÑ Ð² пÑеобÑазовании, в ÑоÑме a=1,b=2. УÑÑиÑе, ÑÑо ÑÐ°Ð·Ð±Ð¾Ñ Ð¿Ð°ÑамеÑÑов вÑполнен оÑÐµÐ½Ñ Ð¿ÑоÑÑо: знаÑÐµÐ½Ð¸Ñ Ð¿Ð°ÑамеÑÑов не могÑÑ ÑодеÑжаÑÑ Ð·Ð°Ð¿ÑÑÑе!
ÐÑÑÑ Ñакже веÑÑÐ¸Ñ xslt_process Ñ Ð´Ð²ÑÐ¼Ñ Ð°ÑгÑменÑами, коÑоÑÐ°Ñ Ð½Ðµ пеÑедаÑÑ Ð½Ð¸ÐºÐ°ÐºÐ¸Ðµ паÑамеÑÑÑ Ð¿ÑеобÑазованиÑ.
F.65.5. ÐвÑоÑ
Ðжон ÐÑей <jgray@azuli.co.uk>
РазÑабоÑÐºÑ ÑÑого модÑÐ»Ñ ÑпонÑиÑовала ÐºÐ¾Ð¼Ð¿Ð°Ð½Ð¸Ñ Torchbox Ltd. (www.torchbox.com). ÐÑÐ¾Ñ Ð¼Ð¾Ð´ÑÐ»Ñ Ð²ÑпÑÑкаеÑÑÑ Ð¿Ð¾Ð´ Ñой же лиÑензией BSD, ÑÑо и Postgres Pro.