
çªç¶ãç§ãã¡ã®åšãã«ã²ã©ãããŒã ããããŸãã...ãããŠããŠã§ãå šäœãLAMPã«é¢ãããããã®èšäºã§ãã£ã±ãã§ãã...
ã©ããªããŒãºã«ã察å¿ã§ããããã«æžãããŠããããã§ãã perlãbashãããã«ã¯Cã§ãã䜿çšããŠããã¿ã¹ã¯ãæé·ãããåžåããŸãããããããã®èšäºã«ã€ããŠè©±ãæå³ã¯ãããŸããã 誰ãããã§ã«ãããç¥ã£ãŠããŸãã
5çªç®ã®IEãå°ãã®NetscapeãOperaãããã³perlã®éå€ãªcgiã¢ãžã¥ãŒã«ããããŸããã å¿ èŠãªæè¡ã¹ã¿ãã¯ã§ã¯ãªãã£ãã ããããããããªãããã³ã»ã³ã¹ãéãå§ããããæ¢ããã®ã¯é£ãããªããŸãã ç§ãå¿é ããŠããã®ã¯PHPã䜿çšããŠããåŠçã ãã§ãã ã ããã»ã©ç¡åã§ç¡è²¬ä»»ã§çãããããŠãããã®ã¯ãããŸããã é ããæ©ããããã®ãŽãã«é²ãããšãç¥ã£ãŠããŸããã
æåã¯ããã§ã¯ãªãã£ã
ãã©ãŠã¶éã®JSãã³ã«ã¯ã®éŠ¬ã®ããã«ç°ãªããXMLHttpRequestã¯ActiveXãä»ããŠã®ã¿å¯èœã§ããã ããŸãéã¯ãããŸããã§ããã ãã€ãããã¯Webãåæžãããã®ã IE 6ã¯é©åœã®ããã«èŠããŸããã ããããã¯ãã¹ãã©ãããã©ãŒã ãå¿ èŠãªå Žåã¯ãèšå€§ãªããã«ãŠã§ã¢ããã¹ããŸããã phpãããŒã«ãããã³é¢é£ããæ°ããã©ã€ãã©ãªã«é¢ããå€æ°ã®èšäºããã®åœ¹ç®ãæãããŸããã
ã²ã©ãPHPã§ãå€ãã¢ã€ã«ã©ã³ãã®å°èª¬ã«é ã£ãåœãåºæ¬çãªéåæ©èœã®å®å šãªåªå€±ãèŠçã®ãŒãããæšè£œã®èãææã®è³ã®ããã«æ¯ãèããŸãã ãã¹ãŠãèŠãããšãã§ããããäœãå¶åŸ¡ããããšãã§ããªãé¢çœãç¶æ ã ããŒã¿ãã©ãã«ãããã©ãã«ããžãã¯ããããã©ãã«è¡šçŸãããããæ確ã«ææ¡ããŠãã¿ã¹ã¯ã«ã¢ãããŒãããŸãã ãããããã®å Žã§ããã¹ãŠãééã£ãŠããŸãã ããªãã¯éªæªãªéººã®ã³ãŒãã«æ··ä¹±ããŠããŠãããªãã¯æãïŒäœãåé¡ãªã®ããäœãèµ·ãã£ãŠããã®ãïŒ...
åŸã ã«ããã©ãŠã¶éã®ã¿ã€ã¿ããã¯ãã¬ãŒããåæãå§ããŸããã XMLHttpRequestã¯ã©ãã«ã§ãç»å Žããããã³ããæ確ã«åé¢ãããåçãªWEBã®å€¢ãçŸå®ã«ãªããŸããã
ãã¡ãããç§ã¯æµè¡ã®ç ç²ã«ãªããŸããã æã«å ¥ãããã®ãã¹ãŠãç 究ããæ®éã®ã¹ããªãŒãããŒãã¡ãŒã Webéçºçšã®åäžèšèªã«ã€ããŠã®ã¢ã€ãã¢ã空äžã«ãããŸããã åŸ ã£ãŠãããªãã¯æ°ããè£ ãã§ãããã®å€åãèŠãã§ããããç·ã
-Node.jsãèŠãŠã¿ãŸãããã
-äœïŒ ããïŒ
ãããã§æ¢ããããšã¯ã§ããŸãããã ããã¯å€ªã£ãäžéã§ãã
-座ã£ãŠã
ã©ã®ãããªãã³ã»ã³ã¹ãããããŠããŸãããããã³ããšã³ããããã«ãšã³ããããã¯ãšã³ãã®é¡äŒŒæ§ãèŠã€ããããã«JavaScriptã§ã©ãã ãæžãå¿ èŠãããã®ãââããããŸãããïŒ ããã¯è¯ãéžæè¢ã§ã¯ãããŸããã éžæããã¿ãŒã²ããã«ã¯åãããŸãã
ããããç§ã¯ãã®ãããªèããæ®ããŸããã ãã©ã€ããŒã§éãæã€ããšãã§ããããšãç解ããããã«ãªããŸããããæã ãã³ããŒã«æãå·®ã䌞ã¹ããšãããã»ã¹ãå€§å¹ ã«å éããŸãã
ç§ã¯å šäœã®ç¶æ³ã«å¯ŸããŠæãããæè°ãæããŸããã
PostgreSQLãªã©ã®DBMSããããçµã¿èŸŒã¿é¢æ°ã䜿çšããŠä¿¡ããããªãã»ã©ããŒã¿ãæäœã§ããŸãã ããŒã¹å ã®ããžãã¹ããžãã¯ïŒ å®éã®ããã¯ãšã³ãã DBMSã®ããžãã¹ããžãã¯ãæ°ã«å ¥ãããããã«å±ããŠããŸãããïŒ ãã®ãããªçŽæ¥ããŒã¿ã¹ããªãŒã ã奜ãã§ããïŒ

å«ç è ã®ãçŽæ¥çãªãæµãã«é¢ããããŒã¿ã®åä»ãªåããææ¡ããŠã¿ãŸãããã
æåã«ééããã®ã¯ãäœããã®çç±ã§ããŒã¿ãéäžã§çµ¶ããèžçãããããšã§ãã ããã«ããã®ããŒã¿ã¯æçµçãªãã®ã§ã¯ãªããåŸç¶ã®ãªã¯ãšã¹ãã®èšç®ã«ã®ã¿å¿ èŠã§ãã ããŒã¿åŠçã«ã¯ãµã€ã¯ã«ã䜿çšãããŸãã æç¶ããµã€ã¯ã«-ãã«ãã¹ã¬ããçšã«æé©åãããŠããŸããã
DBMSãžã®1ã€ã®ã»ãã·ã§ã³ã§ã®ã¯ãšãªã®å€æ§æ§ã¯ãé床ã®çµmiseãšããé¿ããããªã仮説ã«ã€ãªãããŸã-ããŒã¿ããŒã¹ããŒãã«ã®ãã«ããã¹ã

ãããã®èŠå ãæé€ããã«ã¯ãããžãã¯ãããŒã¿ã«è¿ã¥ããå¿ èŠããããŸãã DBMSã§ïŒ
ãããŠãããã¯é床ãæ°ãã䟡å€ã«ããããæãæé©ãªæ¹æ³ã§ãïŒ
ã¢ã€ãã¢ã®åœ¢æ
æéã®çµéãšãšãã«ããã©ãŠã¶ã¯ã€ã³ã¿ãŒãã§ã€ã¹ã®å®å šãªåççæãåŠç¿ããŸããã ããŒã¿ãšãã¬ãŒã³ããŒã·ã§ã³ã®é¢ã§æ確ãªåé¢ãéæãããŸããã äž»ã«ãµãŒããŒããã¯ã©ã€ã¢ã³ãã«ããŒã¿ãéä¿¡ããæ¬æ Œçãªæ©äŒããããŸããã 質åã¯1ã€ã ãã§ãããäžéå±€ã§äœããããã§ãã ãµãŒããŒåŽã§ã³ã¬ã¯ã·ã§ã³ã®ãªã¯ãšã¹ããåçŽã«ã«ãŒãã£ã³ã°ããèŠçŽ ã䜿çšããŠããã©ã³ã¹ããŒãæ©èœã®ã¿ã«ãããæå°åããæ¹æ³ã
ãããã®çŽ æŽãªéçºè ã¯ãå€ãããã«ã®æ ç¹ã®1ã€ãç 究ããããšã§ãå®å¿ãšç解ãåŸããããšä¿¡ããŠããŸããããã®çµæãITæ¥çã®äž»èŠãªãå€ãäžçã®ééããç解ããŠããªãã£ãåãã¬ã€ã€ãŒãçæãããŸããã 誰ããŸãã¯äœããèŽåœçãªæ¬ é¥ãæã£ãŠãããããããªããšãã信念ã倱ããŸãã
ãã®æãŸã§ã«ãnginxã¯æ©èœãå§ããææ¡ãããæèãæºåããããã®è³ªåã¯ãããããŸããã§ããã ããã¯ãã¯ãèãã§ã¯ãããŸããã§ããã ä»ã§ã¯æ programmerãªããã°ã©ããŒã³ã³ãã¹ãã§ããã apacheãä»ããŠäŒçµ±çãªæ¹æ³ã§ã¢ãŒããã¯ãã£ãäœããã®åœ¢ã§èª¬æããããšãããšããã¢ã€ãã¢èªäœã¯ãã°ãããŠããããã«èŠããŸããã
2010幎ã«ã ngx_postgresã¢ãžã¥ãŒã«ãgithubã«å°çããŸããã èšå®ãã¡ã€ã«ã§ãªã¯ãšã¹ããæå®ããJSON / CSV / WELLã§çºè¡ããŸãã
æ§æã«ã¯ãåçŽãªSQLã³ãŒãã§ååã§ããã è€åäœãé¢æ°ã«ã©ããããæ§æããåŒã³åºãããšãã§ããŸãã
ãããããã®ã¢ãžã¥ãŒã«ã¯ãhttpèŠæ±ã®æ¬æãDBMSã«ããŒãã§ããŸããã§ããã ãµãŒããŒã«éä¿¡ãããããŒã¿ã«é倧ãªå¶éã課ãããŸããã URLã¯æããã«ããªã¯ãšã¹ãã®ãã£ã«ã¿ãªã³ã°ã«ã®ã¿é©ããŠããŸããã
åºåããŒã¿ã®ã·ãªã¢ã«åã¯ãã¢ãžã¥ãŒã«èªäœã䜿çšããŠå®è¡ãããŸããã ããã¯ãç§ã®ãœãã¡ã®é«ããããRAMã®ç¡æå³ãªç¿»èš³ã®ããã«æãã-PostgreSQLãã·ãªã¢ã©ã€ãºã§ããã
ä¿®æ£ãæžãæãããšããã¢ã€ãã¢ããããŸããã ç§ã¯ãã®ã¢ãžã¥ãŒã«ã®ã³ãŒããæãå§ããŸããã
ç ãã¬å€ãæ¢ããåŸãngx_postgresã¯å€ãã®äººã«ãšã£ãŠååã§ãããã ãã£ãšåŒ·åãªãã®ãå¿ èŠã§ããã
ããã ããµãŒããã€ããŒããã®ä»äœã§ã ... ... ngx_pgcopyãä¿æãããªãã·ã§ã³ããããŸãã

NGX_PGCOPY
å®éšã®å®éšãšåæã®åæã®åŸãå®çšçãªãã¹ãŠããŒãããæžãçŽããšããã¢ã€ãã¢ãçãŸããŸããã ããŒããé«éåããããã«ã COPYã¯ãšãªãéžæãããŸãããããã¯ãæ¿å ¥ããã1æ¡é«éã«ããŒã¿ãããŒã¿ããŒã¹ã«è»¢éããç¬èªã®ããŒãµãŒãå«ã¿ãŸãã æ®å¿µãªããããã®ã¿ã€ãã®ã¯ãšãªã®èšè¿°ãäžè¶³ããŠããããããã®ã¡ãœããã®ç¹ã«å€§èŠæš¡ãªåŒã³åºãäžã«DBMSãã©ã®ããã«å®è¡ããããèšãã®ã¯å°é£ã§ãã
äžçã¯ããããæ¹åã«çã£ãŠããŠããã€ã§ãããªãã¯çµ¶ããããã«åºããããŸãã ããããç§ãã¡ããããã¹ãŠã®ããšã®æ£ç¢ºãã«ã€ããŠãé©ãã»ã©æ®éçãªæèŠããããŸããã
COPYãªã¯ãšã¹ããšäžç·ã«ãCSVã§åæ¹åã®ã·ãªã¢ã«åãèªåçã«åä¿¡ãããããããŒã¿å€æã®æžå¿µããªããªããŸããã
URLã§CSVã®ããŒãã«å šäœãéåä¿¡ããããªããã£ãããå§ããŸãããã
http://some.server/csv/some_table
CSVããŒãimport.export.nginx.conf
pgcopy_server db_pub "host=127.0.0.1 dbname=testdb user=testuser password=123"; location ~/csv/(?<table>[0-9A-Za-z_]+) { pgcopy_query PUT db_pub "COPY $table FROM STDIN WITH DELIMITER as ';' null as '';"; pgcopy_query GET db_pub "COPY $table TO STDOUT WITH DELIMITER ';';"; }

PostgreSQLã¯çŸåšãCOPY STDINãä»ããŠJSONããã³XMLãäœæã§ããŸããã 象ã®ã³ãŒãã¹ã¿ã€ã«ã®ã¿ãã䜿çšããè¬èãªæ¥ãæ¥ãŠãç§ããŸãã¯èª°ãã®ã¹ã¬ãããæéãèŠã€ããŠããã®æ©èœãCOPYã¡ãœããã«ãã蟌ãã§ãããããšãé¡ã£ãŠããŸãã ããã«ããããã®åœ¢åŒã®åŠçã¯ãã§ã«DBMSã«ååšããŸãã
ãããïŒ ããã§ãä»ã§ãããã䜿çšããæ¹æ³ããããŸãïŒ æ¬¡ã«ãªã¯ãšã¹ãã§å€æ°$ request_body_fileã䜿çšããŠpg_read_binary_fileé¢æ°ã«æž¡ãããšã§ãnginxãclient_body_in_file_onlyã«èšå®ããŸã...
ãã¡ããã次ã®ããã«COPYã¡ãœããã§ãããã©ããããå¿ èŠããããŸã ngx_postgresã®body_rejectaãå®å šã§ãããããã¢ãããã§ã®ã¿æ©èœããŸãã ç§ã¯ãŸã ä»ã®ã¢ãããã«äŒã£ãŠããªãããngx_pgcopyã¯è¿œå æ©èœã®ããã«ãŸã æçããŠããªãã
import.export.nginx.confã§json / xmlãã©ã®ããã«èŠãããèŠãŠã¿ãŸããã
client_body_in_file_only on; client_body_temp_path /var/lib/postgresql/9.6/main/import; location ~/json/(?<table>[0-9A-Za-z_]+) { pgcopy_query PUT db_pub "COPY (SELECT * FROM import_json_to_simple_data('$request_body_file')) TO STDOUT;"; pgcopy_query GET db_pub "COPY (SELECT '['||array_to_string(array_agg(row_to_json(simple_data)), ',')||']' FROM simple_data) TO STDOUT;"; } location ~/xml/(?<table>[0-9A-Za-z_]+) { pgcopy_query PUT db_pub "COPY (SELECT import_xml_to_simple_data('$request_body_file') TO STDOUT;"; pgcopy_query GET db_pub "COPY (SELECT table_to_xml('$table', false, false, '')) TO STDOUT;"; }
ã¯ããclient_body_temp_pathãããŒã¿ããŒã¹ãã£ã¬ã¯ããªã«èšå®ããå¿ èŠãããããŠãŒã¶ãŒã«ã¯ALTER SUPERUSERãäžããå¿ èŠããããŸãã ããã§ãªããã°ãPostgresã¯ç§ãã¡ã®æ¬²æãå°å¹³ç·ãè¶ââããŠéããŸãã
GETã¡ãœããã§æäŸããããšã¯ã¹ããŒãã¯ãæšæºã®Postgresããã±ãŒãžã«å«ãŸããŠããçµã¿èŸŒã¿é¢æ°ã䜿çšããŸãã ãããã®ã¢ã¯ã·ã§ã³ã®çµæãã¯ã©ã€ã¢ã³ãã«éç¥ããå Žåã«åããŠããã¹ãŠã®COPYãSTDOUTã«è¡šç€ºãããŸãã åºå®ããŒãã«ïŒsimple_dataïŒãžã®ã€ã³ããŒãã¯ãšã¯ã¹ããŒããããå°ã倧ããèŠããããããŠãŒã¶ãŒå®çŸ©ã®DBMSããã·ãŒãžã£ã§åé€ãããŸãã
åºå®ããŒãã«ãžã®ã€ã³ããŒãçšã®1.import.export.sqlã®äžéš
CREATE OR REPLACE FUNCTION import_json_to_simple_data(filename TEXT) RETURNS void AS $$ BEGIN INSERT INTO simple_data SELECT * FROM json_populate_recordset(null::simple_data, convert_from(pg_read_binary_file(filename), 'UTF-8')::json); END; $$ LANGUAGE plpgsql; CREATE OR REPLACE FUNCTION import_xml_to_simple_data(filename TEXT) RETURNS void AS $$ BEGIN INSERT INTO simple_data SELECT (xpath('//s_id/text()', myTempTable.myXmlColumn))[1]::text::integer AS s_id, (xpath('//data0/text()', myTempTable.myXmlColumn))[1]::text AS data0 FROM unnest(xpath('/*/*', XMLPARSE(DOCUMENT convert_from(pg_read_binary_file(filename), 'UTF-8')))) AS myTempTable(myXmlColumn); END; $$ LANGUAGE plpgsql;
JSONã®æè»ãªããŒãã«éžæã䜿çšããã€ã³ããŒãæ©èœã¯ãäžèšãšç¹ã«éãã¯ãããŸããã ããããXMLã®ãã®ãããªæè»æ§ã«ããããã倧ããªå ±æãçæãããŸãã
ä»»æã®ããŒãã«ã«ã€ã³ããŒãããããã®1.import.export.sqlã®äžéš
CREATE OR REPLACE FUNCTION import_vt_json(filename TEXT, target_table TEXT) RETURNS void AS $$ BEGIN EXECUTE format( 'INSERT INTO %I SELECT * FROM json_populate_recordset(null::%I, convert_from(pg_read_binary_file(%L), ''UTF-8'')::json)', target_table, target_table, filename); END; $$ LANGUAGE plpgsql; CREATE OR REPLACE FUNCTION import_vt_xml(filename TEXT, target_table TEXT) RETURNS void AS $$ DECLARE columns_name TEXT; BEGIN columns_name := ( WITH xml_file AS ( SELECT * FROM unnest(xpath( '/*/*', XMLPARSE(DOCUMENT convert_from(pg_read_binary_file(filename), 'UTF-8')))) --read tags from file ), columns_name AS ( SELECT DISTINCT ( xpath('name()', unnest(xpath('//*/*', myTempTable.myXmlColumn))))[1]::text AS cn FROM xml_file AS myTempTable(myXmlColumn) --get target table cols name and type ), target_table_cols AS ( -- SELECT a.attname, t.typname, a.attnum, cn.cn FROM pg_attribute a LEFT JOIN pg_class c ON c.oid = a.attrelid LEFT JOIN pg_type t ON t.oid = a.atttypid LEFT JOIN columns_name AS cn ON cn.cn=a.attname WHERE a.attnum > 0 AND c.relname = target_table --'log_data' ORDER BY a.attnum --prepare cols to output from xpath ), xpath_type_str AS ( SELECT CASE WHEN ttca.cn IS NULL THEN 'NULL AS '||ttca.attname ELSE '((xpath(''/*/'||attname||'/text()'', myTempTable.myXmlColumn))[1]::text)::' ||typname||' AS '||attname END AS xsc FROM target_table_cols AS ttca ) SELECT array_to_string(array_agg(xsc), ',') FROM xpath_type_str ); EXECUTE format('INSERT INTO %s SELECT %s FROM unnest(xpath( ''/*/*'', XMLPARSE(DOCUMENT convert_from(pg_read_binary_file(%L), ''UTF-8'')))) AS myTempTable(myXmlColumn)', target_table, columns_name, filename); END; $$ LANGUAGE plpgsql;
äžèšã®äŸã§ã¯ãã€ã³ããŒãããããã¡ã€ã«ã®ååtable_nameã¯ãnginxã§æå®ãããã¿ãŒã²ããå®å ããŒãã«ã«åœ±é¿ããŸããã table_name / rows / colsããã¥ã¡ã³ãã®xmléå±€ã®äœ¿çšã¯ãçµã¿èŸŒã¿ã®table_to_xmlé¢æ°ãšã®å¯Ÿç§°æ§ã®ã¿ã«èµ·å ããŸãã
ããŒã¿ã»ããèªäœ...
simple_data_table.sql
CREATE TABLE simple_data ( s_id SERIAL, data0 TEXT );
data.csv
0;zero
1;one
data.json
[ {"s_id": 5, "data0": "five"}, {"s_id": 6, "data0": "six"} ]
data.xml
<simple_data xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <row> <s_id>3</s_id> <data0>three</data0> </row> <row> <s_id>4</s_id> <data0>four</data0> </row> </simple_data>
ããã«ç§»åããã®ã§ãçŽç²ãªCOPYã®ã«ãŒãã«æ»ããŸã...
ããã£ã ãããããããå¯äžã®æ¹æ³ã§ãã ãã¹ãŠãæ£ããç解ããããšã確èªããŸãããã ãµãŒããŒãšã¯ã©ã€ã¢ã³ãéã§åŠçããã«ããŒã¿ãéä¿¡ããããããããŒãã«ã«å ¥åããŸããïŒ

ç§ã¯ææãæãããšæããŸãã
ãã³ã»ã³ã¹ã ããã«ãŠã§ã¢ã®å€¢ãèŠã€ãã«æ¥ãŸããã
ãããŠä»ãç§ãã¡ã¯åœŒå¥³ã®æ颚ã®äžã«ããã®ã§ãããªãã¯å»ãããã§ããïŒ
ããªãã¯ç解ããå¿ èŠããããŸããç§ãã¡ã¯äž»ãªç¥çµãèŠã€ããŸããã
ã¯ããããã¯ã»ãšãã©ãã®ãããªãã®ã§ãïŒ ããã¯CRUDã®æåŠã§ãã
ãã¡ãããããã€ãã®æã®ããã¿ã€ããã«ãªãã©ã«ãã¢ã®å¿ã®ä»äºã®çµæãæ¶ãã麻è¬äžæ¯è ã®å¯Ÿè©±ã®ããã®çãèšäºãæ§åŒåããã®ã§ãå€ãã¯manyããŸãã ãã ãããã¹ãŠã倱ãããããã§ã¯ãããŸããã ããŒã¿èªäœãšãšãã«ããŒã¿ä¿®é£Ÿåãæž¡ããªãã·ã§ã³ããããŸãã ããã¯ä»ã§ãããªãã¿ã®RESTfulã¢ãŒããã¯ãã£ããé¢ããŠããŸãã
ããã«ãæã«ã¯ããããŠããé »ç¹ã«ãçè«çç 究ãçŸå®ã®å²©ç³ã«äŸµå ¥ããŸãã ãã®ãããªå²©ã¯åãäžå¹žãªãã«ããã¹ã§ãã å®éããŠãŒã¶ãŒããã¥ã¡ã³ãã®å€æ°ã®äœçœ®ã®å€æŽãèš±å¯ããå Žåããããã®å€æŽã«ã¯ããã€ãã®ã¿ã€ãã®ã¡ãœãããå«ãŸããå¯èœæ§ããããŸãã ãã®çµæã1ã€ã®ããã¥ã¡ã³ããããŒã¿ããŒã¹ã«éä¿¡ããã«ã¯ãããã€ãã®åå¥ã®httpèŠæ±ãäœæããå¿ èŠããããŸãã ãŸããåHTTPãªã¯ãšã¹ãã¯ãç¬èªã®ããŒã¹å€æŽãšããŒãã«ã®ééãçæããŸãã ãããã£ãŠãå®æ§çãªãã¬ãŒã¯ã¹ã«ãŒã«ã¯ãCRUDã¡ãœããã®å€å žçãªç解ãæŸæ£ããéã®æ ¹æ¬çãªå€æŽãå¿ èŠã§ãã é²æ©ã«ã¯ç ç²ãå¿ èŠã§ãã
ããã§ãããèå³æ·±ã解決çãèŠã€ãããšçã£ãŠããŸããã ããªãã¯ã¡ãã£ãšå®éšããŠèããå¿ èŠããããŸã...
ãšã³ããªãŒãã€ã³ã
ãã®è³ªåãããé ã«ã¯ã
圌ã«çããããšãã§ãã人ã¯ãŸã è¿ãã«ããŸããã§ããã
ã¯ããã¯ããç§ã¯åã³å§ããŠããŸã...
äžéå±€ã«ããŒã¿ãéä¿¡ããäžéå±€ã¯åŠçããã«ããŒã¿ããŒã¹ã«éä¿¡ããŸãã
DBMSã¯ãããã解æãããã°/ãã°ãšããŠæ©èœããããŒãã«ã«é 眮ããŸãã ãã¹ãŠã®å ¥åããŒã¿ã®ç»é²ã
éèŠãªç¬éãããã«ãããŸãïŒ ãã®ã³ã°/ãã®ã³ã°ããŒã¿ã®æµãã¯ãã®ãŸãŸã§ïŒ ãããŠãããã¯ããªã¬ãŒæ¬¡ç¬¬ã§ãã ãããã§ã¯ãããžãã¹ããžãã¯ã«åºã¥ããŠãæŽæ°ãè¿œå ããŸãã¯ä»ã®äœããè¡ããŸãã ããŒã¿ä¿®é£Ÿåã®ãã蟌ã¿ã¯ãªãã·ã§ã³ã§ãããçŽ æŽãããããŒãã¹ã«ãªãå ŽåããããŸãã
ããã«ãããHTTP GETã¡ãœãããšPUTã¡ãœããã䜿çšããããšã§ååã«ãªããŸãã ãããé©çšããæ¹æ³ãã·ãã¥ã¬ãŒãããŠã¿ãŸãããã ãŸãããã°ãšãã°ã®éããå€æããŸãã å€æŽã®ã«ãŒãã®å€ãšæçµå€ã®éã®åªå é äœã«ããéèŠãªéãã匷調ããŸãã æåã®åºæºããã°ã«å²ãåœãŠã2çªç®ã®åºæºããã°ã«å²ãåœãŠãŸãã
éèªã®æçµç®æšã®åªå é äœã«ãããããããã«ãŒãã¯ãŸã å¿ èŠã§ãã ãã®çµæããã®ãããªããŒãã«ã¯ãçµæãšãžã£ãŒãã«èªäœã®2ã€ã®éšåã«åå²ãããŸãã

äœãåŒãåºãããšãã§ããŸããïŒ ãã°ïŒè»ã®ã«ãŒãã移åããçŽ æè³ç£ãªã© ãã°ïŒåšåº«æ®é«ãæåŸã®ã³ã¡ã³ããããã³ãã®ä»ã®æè¿ã®ã€ã³ã¹ã¿ã³ãããŒã¿ã®ç¶æ ã
2.jrl.log.sqlã®ã³ãŒãïŒ
ããŒãã«
CREATE TABLE rst_data ( --Output/result table 1/2 s_id SERIAL, data0 TEXT, --Operating Data data1 TEXT, --Operating Data ); --Service variable with prefix s_, ingoring input value, it will be setting from trigers CREATE TABLE jrl_data ( --Input/journal table 2/2 s_id SERIAL, --Service variable, Current ID of record s_cusr TEXT, --Service variable, User name who created the record s_tmc TEXT, --Service variable, Time when the record was created p_trid INTEGER, --Service variable, Target ID/Parent in RST_(result) table, -- if exists for modification data0 TEXT, data1 TEXT, ); CREATE TABLE log_data ( --Input/output log table 1/1 s_id SERIAL, s_cusr TEXT, s_tmc TEXT, pc_trid INTEGER, --Service variable, Target ID(ParentIN/ChilrdenSAVE) -- in CURRENT table, if exists for modification data0 TEXT, data1 TEXT, );
ãã¬ãžã³ããªã¬ãŒ
CREATE OR REPLACE FUNCTION trg_4_jrl() RETURNS trigger AS $$ DECLARE update_result INTEGER := NULL; target_tb TEXT :='rst_'||substring(TG_TABLE_NAME from 5); BEGIN --key::text,value::text DROP TABLE IF EXISTS not_null_values; CREATE TEMP TABLE not_null_values AS SELECT key,value from each(hstore(NEW)) AS tmp0 INNER JOIN information_schema.columns ON information_schema.columns.column_name=tmp0.key WHERE tmp0.key NOT LIKE 's_%' AND tmp0.key <> 'p_trid' AND tmp0.value IS NOT NULL AND information_schema.columns.table_schema = TG_TABLE_SCHEMA AND information_schema.columns.table_name = TG_TABLE_NAME; IF NEW.p_trid IS NOT NULL THEN EXECUTE (WITH keys AS ( SELECT ( string_agg((select key||'=$1.'||key from not_null_values), ',')) AS key) SELECT format('UPDATE %s SET %s WHERE %s.s_id=$1.p_trid', target_tb, keys.key, target_tb) FROM keys) USING NEW; END IF; GET DIAGNOSTICS update_result = ROW_COUNT; IF NEW.p_trid IS NULL OR update_result=0 THEN IF NEW.p_trid IS NOT NULL AND update_result=0 THEN NEW.p_trid=NULL; END IF; EXECUTE format('INSERT INTO %s (%s) VALUES (%s) RETURNING s_id', target_tb, (SELECT string_agg(key, ',') from not_null_values), (SELECT string_agg('$1.'||key, ',') from not_null_values)) USING NEW; END IF; RETURN NEW; END; $$ LANGUAGE plpgsql;
ãã°ããªã¬ãŒ
CREATE OR REPLACE FUNCTION trg_4_log() RETURNS trigger AS $$ BEGIN IF NEW.pc_trid IS NOT NULL THEN EXECUTE ( WITH str_arg AS ( SELECT key AS key, CASE WHEN value IS NOT NULL OR key LIKE 's_%' THEN key ELSE NULL END AS ekey, CASE WHEN value IS NOT NULL OR key LIKE 's_%' THEN 't.'||key ELSE TG_TABLE_NAME||'.'||key END AS tkey, CASE WHEN value IS NOT NULL OR key LIKE 's_%' THEN '$1.'||key ELSE NULL END AS value, isc.ordinal_position FROM each(hstore(NEW)) AS tmp0 INNER JOIN information_schema.columns AS isc ON isc.column_name=tmp0.key WHERE isc.table_schema = TG_TABLE_SCHEMA AND isc.table_name = TG_TABLE_NAME ORDER BY isc.ordinal_position) SELECT format('WITH upd AS (UPDATE %s SET pc_trid=%L WHERE s_id=%L) SELECT %s FROM (VALUES(%s)) AS t(%s) LEFT JOIN %s ON t.pc_trid=%s.s_id', TG_TABLE_NAME, NEW.s_id, NEW.pc_trid, string_agg(tkey, ','), string_agg(value, ','), string_agg(ekey, ','), TG_TABLE_NAME, TG_TABLE_NAME) FROM str_arg ) INTO NEW USING NEW; NEW.pc_trid=NULL; END IF; RETURN NEW; END; $$ LANGUAGE plpgsql;
äžèšã®äŸã§ã¯ãã»ã«ããããã«ããæ¹æ³ãããããŸããã ãããè¡ãã«ã¯ããµãŒãã¹å€ãåºå®ããŸãã ãããŠããããã¯ã€ã³ããŒãã®æ¹æ³ã«å€§ããäŸåããŠããŸãã å Žåã«ãã£ãŠã¯ã絶察ã«ä»»æã®ã³ã³ãã³ããæã€ä»»æã®ã¿ã€ãã䜿çšã§ããŸãã ãã®ä»ã®å Žåãç¯å²å€ã®å¯èœæ§ãé«ã笊å·ãæã€ã¿ãŒã²ããåã®ã¿ã€ãã®ã¿ã
ããªã¬ãŒã¯ãååã«ããããã¹ãã®ãœãŒãé ã§åŒã³åºãããŸã ã trg_N_ãã¬ãã£ãã¯ã¹ã䜿çšããããšããå§ãããŸãã trg_0ããtrg_4ãŸã§ãå ±éããžãã¯ãšçä¿¡ãã£ã«ã¿ãªã³ã°ã®æŽåæ§ã®ã¿ãæäŸãããµãŒãã¹ãæ€èšããŠãã ããã ãŸãã5ãã9ãé©çšããèšç®ã«äœ¿çšããŸãã ããªã¬ãŒã¯ 9ã€ããã°ååã§ã ïŒ
ãŸããBEFORE INSERTã«ã€ã³ã¹ããŒã«ããå¿ èŠãããããšãèšã䟡å€ããããŸãã c AFTERã®å Žåãããªã¬ãŒã«ããå€æŽã®åã«NEWãµãŒãã¹å€æ°ãããŒãã«ã«å ¥ããããããã§ãã ååãšããŠãæŽåæ§ãããçšåºŠéèŠã§ãªãå Žåããã®ãããªãœãªã¥ãŒã·ã§ã³ã¯ããã°ãééãããŠãŒã¶ãŒã¯ãšãªã®åªããã¢ã¯ã»ã©ã¬ãŒã¿ã«ãªããŸãã ããã¯ãçµæã®ããŒãã«ã®å€ã«ã¯åœ±é¿ããŸããã
ãŸããAFTERã§ã¯ããŠãŒã¶ãŒãå€æŽããæš©å©ãæã£ãŠããªãå Žåããšã©ãŒãè¿ãããšã¯ã§ããŸããã ãã ããæ£ããFrondEndã¯ããµãŒããŒã«ãã£ãŠçŠæ¢ãããŠããæäœãå®è¡ããªãã§ãã ããã ãããã£ãŠããã®ãããªåäœã¯ãããã³ã°ã®ç¹åŸŽã§ããå¯èœæ§ãé«ãããžã£ãŒãã«ã«å¹³åçã«èšé²ãããŸãã
ããã®ãã£ã«ã¿ãªã³ã°ãšã«ãŒãã£ã³ã°

æšæºã®nginxããŒã«ã䜿çšããŠURLãã«ãŒãã£ã³ã°ããŸãã åæ§ã«ããªã¯ãšã¹ããã€ã³ãžã§ã¯ã·ã§ã³ãããã£ã«ã¿ãªã³ã°ããŸãã åé¡ã2åã«ããåŸãé察称æå·åã®çµæã«äŒŒãã³ãŒããmap nginx.confãã£ã¬ã¯ãã£ãã«ã³ãŒãã£ã³ã°ããŠãæ¶åå¯èœã§å®å šãªSQLã¯ãšãªãååŸããŸãã å°æ¥çã«ã¯ãããŒã¿ããã£ã«ã¿ãªã³ã°ããŸãã
ããã€ãã®å°é£ããããŸãã ããã¯ã sed s / bad / good / gåãè€æ°çœ®æããããã®nginxã®éåžžã®æ§æã®äžè¶³ãåå ã§ãã ãã®çµæãæã ...
ç§ãã¡ã¯ãã®ã¯ãœãã©ãªãŠã ã®åããšããã«ããå ¥ããŸãã ãããŠãçµå±ã®ãšããããããã®ããŸããŸããè¡šçŸãæžãå¿ããããŸãïŒ ããå°ããããšã圌ãã¯è³ã现æããŸãã
æ倧4ã€ã®URLç䟡ãã£ã«ã¿ãŒ
http://some.server/csv/table_name/*?col1=value&col2=value&col3=value&col4=value
filters.nginx.confã®Horrowshowéšå
# SQL map $args $fst0 { default ""; "~*(?<tmp00>[a-zA-Z0-9_]+=)(?<tmp01>[a-zA-Z0-9_+-.,:]+)(:?&(?<tmp10>[a-zA-Z0-9_]+=)(?<tmp11>[a-zA-Z0-9_+-.,:]+))?(:?&(?<tmp20>[a-zA-Z0-9_]+=)(?<tmp21>[a-zA-Z0-9_+-.,:]+))?(:?&(?<tmp30>[a-zA-Z0-9_]+=)(?<tmp31>[a-zA-Z0-9_+-.,:]+))?(:?&(?<tmp40>[a-zA-Z0-9_]+=)(?<tmp41>[a-zA-Z0-9_+-.,:]+))?" "$tmp00'$tmp01' AND $tmp10'$tmp11' AND $tmp20'$tmp21' AND $tmp30'$tmp31' AND $tmp40'$tmp41'"; } # map $fst0 $fst1 { default ""; "~(?<tmp0>(:?[a-zA-Z0-9_]+='[a-zA-Z0-9_+-.,:]+'(?: AND )?)+)(:?( AND '')++)?" "$tmp0"; } map $fst1 $fst2 { default ""; "~(?<tmp0>[a-zA-Z0-9_+-=,.'' ]+)(?= AND *$)" "$tmp0"; } # , WHERE map $fst2 $fst3 { default ""; "~(?<tmp>.+)" "WHERE $tmp"; } server { location ~/csv/(?<table>result_[a-z0-9]*)/(?<columns>\*|[a-zA-Z0-9,_]+) { pgcopy_query GET db_pub "COPY (select $columns FROM $table $fst3) TO STDOUT WITH DELIMITER ';';"; } }
URLã§ã®ããªã«ãã£ã«ã¿ãŒåŠçã§ã¯ãnginxã®èšå®ãä»ããŠããã¹ãŠãã¹ã ãŒãºã«è¡ãããããšããããŸãããbase64ããå¥ã®å€æ°ãžã®äººéãèªããããã¹ãã䜿çšãããã€ãã£ãå€æãå¿ èŠã§ãã çŸæç¹ã§ã¯ããã®ãããªãã£ã¬ã¯ãã£ãã¯ãããŸããã nginxã®ãœãŒã¹ã«ã¯ããã©ã³ã¹ã³ãŒãã£ã³ã°æ©èœãååšãããããããã¯éåžžã«å¥åŠã§ãã
ã¹ã¬ãããšããŠãnginx incããŒã ãããã解決ããªããã°ãééããªãæèãéããŠããã®çç¥ãšsedã®åé¡ãæé€ããŸãã
çŽæ¥é¢æ°åŒã³åºããŸãã¯ããŒãã«ãã°ã®ããªã¬ãŒã§åçã¯ãšãªãå éšçæããããã«ãURLã«DBMSãžã®åŒæ°ãæã€æååãäžããããšãã§ããŸãã ãããããã®ãããªããŒã¿ã¯ãã§ã«nginx-access.logã«èšé²ãããŠããããããããã®åãçµã¿ã¯åé·ã§ãã ãŸãããã®ãããªã¢ã¯ã·ã§ã³ã¯ããŒã¹ãã©ã³ããŒã®è² è·ãå¢å€§ãããå¯èœæ§ããããšããäºå®ãèæ ®ãããšãããããæ害ã§ãã
SM oke all FAQ
-nginxã®äžã®ã¢ãžã¥ãŒã«ã¯é·ãéæ£åžžã«æžã蟌ãŸããŠããŸãã ãã¡ã³ãã¡ãŒã¬ã¯ã©ãã§ããïŒ
æ¢åã®ã¢ããã°ã®ã»ãšãã©ã¯ãéåžžã«å°éçãªãœãªã¥ãŒã·ã§ã³ã§ãã ãã®èšäºã§ã¯ãé床ãšæè»æ§ã®åŠ¥åœãªåŠ¥åæ¡ãæ瀺ããŸãïŒ
-ãã£ã¹ã¯ãåŠçããŸãïŒclient_body_in_file_onlyïŒ-ãã£ããïŒ
RAMãã©ã€ããšãã®é èšè ã§ãããã¡ã€ã«ã·ã¹ãã ãã£ãã·ã¥ãããªããšå ±ã«æ¥ãŸãããã«ã
-ãŠãŒã¶ãŒã®æš©å©ã¯ã©ãã§ããïŒ
åçŽãªhttpã䜿çšããæ¿èªã¯postgresã«è»¢éãããŸãã ããã§ãçµã¿èŸŒã¿ããŒã«ã䜿çšããŠè§£æ±ºããŠããŸãã äžè¬çã«ãå®å šãªããã¯ãšã³ãã
-æå·åã¯ã©ãã§ããïŒ
nginx configãä»ããSslã¢ãžã¥ãŒã«ã çŸåšã®æ®µéã§ã¯ãngx_pgcopyã³ãŒãã®æ¹¿æ°ã®ããã«é¢éžã§ããªãå ŽåããããŸãã
ãµãŒããŒã®å€æ§æ§ãåããnginxãšpostgresã®æ¥ç¶ã¯ãåå·ççã«sshãæããããšãã§ããŸãã
-åœåãã¡ã¬ãã®åå°ã«JSã·ã³ãã«ãå«ãŸããŠããã®ã¯ãªãã§ããïŒ javascriptã¯ã©ãã«ãããŸããïŒ
JSã¯ããã³ããšã³ãã«è¡ããŸãã ãããŠãããã¯å®å šã«ç°ãªãæ ç»ã§ãã
-JSãç¡å¹ã«ãªã£ãŠããã¯ã©ã€ã¢ã³ãã«çåœã¯ãããŸããïŒ
ãããã以åã«æ°ä»ããããã«ãäŸã§ã¯ãPostgresã¯xmlã§ã§ããŸãã ã€ãŸã HTMLåºåã®æºåã¯åé¡ãããŸããã ã¹ãã²ããã£ã³ãŒãã®äœ¿çšãšxslã¹ããŒã ã®äž¡æ¹ã
ããã¯ã²ã©ãã§ãã ããã«ããããããããã¹ãŠãããŸããããŸãã ããªãã¯ãã¹ãŠæ£ããããšãããŠããŸãã
-åçã®ãµã€ãºãå€æŽããã¢ãŒã«ã€ããããã¯ããGPUäžã®ã¬ããã³ã®ãã¹ãèªã¿åãæ¹æ³

ãããŠãããç°¡åã«ã
ãã¶ãç§ã¯ãã®ç·ãšãã£ããããæ¹ããããšæã£ãã
FastCGIã«è¡ããªãã§ãã ããïŒ
圌ãã¯ç§ãã¡ã«ãããæåŸ ããã ãã§ãã
ãã®ããã¯ã¹ã«èªã£ãŠãã ãã
å°äžã«éããŸãã ãããã
ngixclient_body_in_file_only onãèšããã³ãã³ãã©ã€ã³ã«ã¢ã¯ã»ã¹ããŠãè ãã£ã±ãã®$ request_body_fileãšplperluãåã蟌ã¿ãŸãã ãããŠãã®ã¹ã¬ããã以äžããé©å¿ãããŸãïŒ
CREATE OR REPLACE FUNCTION foo(filename TEXT) RETURNS TEXT AS $$ return `/bin/echo -n "hello world!"`; $$ LANGUAGE plperlu;
-CGIã®ããã«èŠããŸãã ãããŠãCGIã¯å®å šã§ã¯ãããŸããïŒ
ã»ãã¥ãªãã£ã¯ããã¯ãããžãŒããããªãã©ã·ãŒã«äŸåããŠããŸãã ã¯ã ç°å¢å€æ°ããã蟌ãã åŸãCGIãšäºææ§ããããŸãã ããã«ãããã¯ãã¹ã¯ãªããã®æå°éã®åæ§ç¯ã§CGIããã®ãœãã移è¡ã«é©çšã§ããŸãã ãããã£ãŠããã®æ¹æ³ã¯ã»ãšãã©ã®PHPãœãªã¥ãŒã·ã§ã³ããã®é¿é£ã«é©ããŠããŸãã
åæ£ã³ã³ãã¥ãŒãã£ã³ã°ïŒPostgreSQLã¯ã©ã¹ã¿ãªã³ã°ã®ãããïŒã®ãããã¯ãšãéåæãžã®ã¢ãããŒããéžæããèªç±ã«ã€ããŠã®å€¢ãèŠãããšãã§ããŸãã ãããããããè¡ãããã«ããã¡ããç§ã¯ããŸããã
åç §è³æ
â ngx_pgcopy
â PostgreSQL COPYãªã¯ãšã¹ã
â slim_middle_samples ïŒ èšäºã®ãµã³ãã« +ãã¢ã¢ã»ã³ããªïŒ
èŠå
ã¢ãžã¥ãŒã«ã¯ãŸã éçºäžã§ãããããå®å®æ§ã®åé¡ãçºçããå¯èœæ§ããããŸãã ç§ããŸã ããã¯ãšã³ãã®æ¹åã«å®è£ ããŠããªãããŒãã¢ã©ã€ãæ¥ç¶ãèæ ®ãããšããã®äœæã¯ãåœåã®éãäŸç¶ãšããŠè¶ é³éæŠéæ©ã«é©ããŠããŸãã èªãããã®READMEã¢ãžã¥ãŒã«ã
PSã å®éãCRUDã¯ã¹ãã¢ãããã·ãŒãžã£ãä»ããŠåé¡ãªãå®è£ ãããããã¡ãœããããšã®ãã°ã«åŸã£ãŠããã°ã«ã¯é©çšãããŸããã ãŸããã¢ãžã¥ãŒã«ã«DELETEã¡ãœãããè¿œå ããã®ãå¿ããŸããã
ãã®èšäºã§ã¯ã1998幎ã®æ ç»ãFear and Loathing in Las Vegasãã®æ åãšåŒçšã䜿çšããŸããã ãããã®è³æã¯ãéå¶å©ç®çããã³ç€ŸäŒã®æåçãæè²çãç§åŠççºå±ãåºæ¿ããæ çµã¿ã§ã®ã¿äœ¿çšãããŸãã