├── .gitignore ├── AUTHORS ├── Changes ├── LICENSE ├── MANIFEST ├── MANIFEST.SKIP ├── META.yml ├── Makefile.PL ├── README ├── TODO ├── TODO.QA ├── bin ├── compile-views ├── export-model.pl ├── fetch-font.pl ├── httpresty.pl ├── import-model.pl ├── install-deps.sh ├── old-openresty ├── prettyjson ├── reindex ├── releng ├── repeat ├── restore-metamodel.pl ├── revision.pl ├── save-metamodel.pl ├── tab2json.pl └── test-memcached.pl ├── clients ├── js │ ├── JSON.js │ ├── dojo.openresty.js │ ├── md5.js │ └── openresty.js └── perl │ └── README ├── debian ├── conffiles ├── control ├── postinst └── rules ├── demo ├── Admin │ ├── Makefile │ ├── README │ ├── css │ │ ├── admin.css │ │ ├── fonts.css │ │ └── login.css │ ├── image │ │ ├── lower-left.gif │ │ ├── lower-right.gif │ │ ├── upper-left.gif │ │ └── upper-right.gif │ ├── js │ │ ├── admin.js │ │ ├── login.js │ │ └── thirdparty │ │ │ ├── jquery.cookie.pack.js │ │ │ ├── jquery.jeditable.pack.js │ │ │ └── jquery.js │ └── template │ │ ├── banner.tt │ │ ├── elem │ │ ├── action.tt │ │ ├── column-inputs.tt │ │ ├── console.tt │ │ ├── create-action.tt │ │ ├── create-bulk-row.tt │ │ ├── create-feed.tt │ │ ├── create-model.tt │ │ ├── create-role.tt │ │ ├── create-row.tt │ │ ├── create-view.tt │ │ ├── feed.tt │ │ ├── menu.tt │ │ ├── model-dump-res.tt │ │ ├── model-rows.tt │ │ ├── model.tt │ │ ├── object-list.tt │ │ ├── pager.tt │ │ ├── param-inputs.tt │ │ ├── role-rules.tt │ │ ├── role.tt │ │ └── view.tt │ │ ├── footer.tt │ │ ├── header.tt │ │ ├── index.tt │ │ ├── js │ │ ├── dispatcher.tt │ │ └── handlers.tt │ │ └── login.tt ├── Blog │ ├── Makefile │ ├── README │ ├── TODO │ ├── css │ │ ├── blog.css │ │ ├── styles.css │ │ └── themes │ │ │ ├── common │ │ │ ├── base-weblog.css │ │ │ ├── print.css │ │ │ ├── print.css.1 │ │ │ └── tipjar.css │ │ │ └── lilia │ │ │ ├── theme-bluecrush.css │ │ │ └── theme-bluecrush │ │ │ ├── banner-bg.gif │ │ │ ├── colitem-header-bg.gif │ │ │ ├── column-left-bg.gif │ │ │ ├── container-bg.gif │ │ │ ├── li-bg.gif │ │ │ └── thumbnailed-bg.gif │ ├── doc │ │ ├── blog_site.png │ │ └── graphviz.mk │ ├── image │ │ ├── loading.gif │ │ └── me.jpg │ ├── js │ │ ├── blog.js │ │ └── thirdparty │ │ │ └── jquery.js │ ├── script │ │ ├── init.pl │ │ └── reset.mk │ └── template │ │ ├── banner.tt │ │ ├── elem │ │ ├── archive-list.tt │ │ ├── archive-nav.tt │ │ ├── calendar.tt │ │ ├── comments.tt │ │ ├── nav.tt │ │ ├── pager.tt │ │ ├── post-list.tt │ │ ├── post-page.tt │ │ ├── post.tt │ │ ├── recent-comments.tt │ │ └── recent-posts.tt │ │ ├── footer.tt │ │ ├── header.tt │ │ ├── index.tt │ │ └── sidebar.tt ├── Blog2 │ ├── Makefile │ ├── README │ ├── TODO │ ├── css │ │ ├── blog.css │ │ ├── styles.css │ │ └── themes │ │ │ ├── common │ │ │ ├── base-weblog.css │ │ │ ├── print.css │ │ │ ├── print.css.1 │ │ │ └── tipjar.css │ │ │ └── lilia │ │ │ ├── theme-bluecrush.css │ │ │ └── theme-bluecrush │ │ │ ├── 4ebg.gif │ │ │ ├── banner-bg.gif │ │ │ ├── colitem-header-bg.gif │ │ │ ├── column-left-bg.gif │ │ │ ├── container-bg.gif │ │ │ ├── li-bg.gif │ │ │ ├── tbg.gif │ │ │ ├── tbgr.gif │ │ │ ├── thumbnailed-bg.gif │ │ │ ├── tit.gif │ │ │ └── titl.gif │ └── script │ │ ├── blogadmin.pl │ │ └── reset.mk ├── BlogAdmin │ ├── Makefile │ ├── README │ ├── css │ │ ├── blogadmin.css │ │ ├── fonts.css │ │ └── login.css │ ├── js │ │ ├── blogadmin.js │ │ ├── login.js │ │ ├── thirdparty │ │ │ └── wymeditor │ │ │ │ ├── iframe │ │ │ │ └── default │ │ │ │ │ ├── lbl-blockquote.png │ │ │ │ │ ├── lbl-h1.png │ │ │ │ │ ├── lbl-h2.png │ │ │ │ │ ├── lbl-h3.png │ │ │ │ │ ├── lbl-h4.png │ │ │ │ │ ├── lbl-h5.png │ │ │ │ │ ├── lbl-h6.png │ │ │ │ │ ├── lbl-p.png │ │ │ │ │ ├── lbl-pre.png │ │ │ │ │ ├── wymiframe.css │ │ │ │ │ └── wymiframe.html │ │ │ │ ├── jquery.wymeditor.js │ │ │ │ ├── jquery.wymeditor.pack.js │ │ │ │ ├── lang │ │ │ │ ├── ca.js │ │ │ │ ├── de.js │ │ │ │ ├── en.js │ │ │ │ ├── es.js │ │ │ │ ├── fa.js │ │ │ │ ├── fr.js │ │ │ │ ├── hu.js │ │ │ │ ├── it.js │ │ │ │ ├── nl.js │ │ │ │ ├── pl.js │ │ │ │ ├── pt.js │ │ │ │ ├── ru.js │ │ │ │ ├── sv.js │ │ │ │ └── zh_cn.js │ │ │ │ ├── plugins │ │ │ │ ├── hovertools │ │ │ │ │ └── jquery.wymeditor.hovertools.js │ │ │ │ └── tidy │ │ │ │ │ ├── README │ │ │ │ │ ├── jquery.wymeditor.tidy.js │ │ │ │ │ ├── tidy.php │ │ │ │ │ └── wand.png │ │ │ │ └── skins │ │ │ │ ├── default │ │ │ │ ├── icons.png │ │ │ │ ├── skin.css │ │ │ │ └── skin.js │ │ │ │ ├── minimal │ │ │ │ ├── skin.css │ │ │ │ └── skin.js │ │ │ │ └── wymeditor_icon.png │ │ └── vars.js │ └── template │ │ ├── ajax │ │ ├── edit.tt │ │ └── posts.tt │ │ ├── footer.tt │ │ ├── index.tt │ │ └── login.tt ├── Click4honor │ ├── Makefile │ ├── click4honor_fullview.js │ ├── index.html │ ├── init.pl │ └── jsont.js ├── Onccf │ ├── Makefile │ ├── README │ ├── css │ │ ├── global.css │ │ ├── layout.css │ │ ├── onccf.css │ │ ├── slideshow.css │ │ └── theme.css │ ├── image │ │ ├── background.gif │ │ ├── bar.gif │ │ ├── gate.jpg │ │ ├── hd.gif │ │ └── logo.png │ ├── js │ │ ├── onccf.js │ │ └── pod2html.js │ ├── script │ │ ├── init.pl │ │ └── reset.mk │ ├── t │ │ ├── 01-pod2html.t │ │ └── TestJS.pm │ └── template │ │ ├── ajax │ │ ├── login.tt │ │ ├── menu.tt │ │ └── submenu.tt │ │ ├── header.tt │ │ └── index.tt ├── RestyCheck │ ├── Makefile │ ├── index.html │ ├── restycheck.css │ └── restycheck.js ├── Springbot │ ├── README │ ├── SpringBot.pm │ ├── log │ │ ├── import.pl │ │ └── init.pl │ ├── springbot │ └── staff │ │ ├── Makefile │ │ ├── csv2resty.pl │ │ ├── html2txt.pl │ │ ├── init.pl │ │ ├── pinyin.txt │ │ ├── sql2txt.pl │ │ └── txt2csv.pl └── YisouComments │ ├── dojo.yisoucomments.js │ ├── lightbox3.js │ ├── loading.gif │ ├── post.html │ ├── post.js │ ├── storage.js │ └── style3.css ├── dev.mk ├── etc └── openresty.conf ├── filter ├── grammar ├── restyscript-view.yp ├── validator.grammar └── view-upgrade.yp ├── haskell ├── Makefile ├── README ├── TODO ├── bin │ └── rand-sql.pl ├── src │ ├── Main.hs │ ├── OpenResty.hs │ ├── OpenResty │ │ ├── Request.hs │ │ └── Response.hs │ └── RestyScript │ │ ├── AST.hs │ │ ├── Emitter │ │ ├── Fragments.hs │ │ ├── RenameVar.hs │ │ ├── RestyScript.hs │ │ └── Stats.hs │ │ ├── Parser.hs │ │ ├── Parser │ │ ├── Action.hs │ │ └── View.hs │ │ └── Util.hs └── t │ ├── action │ ├── emit-frags.t │ ├── emit-rs.t │ ├── emit-stats.t │ └── rename-var.t │ └── view │ ├── emit-frags.t │ ├── emit-rs.t │ ├── emit-stats.t │ ├── prefix-support-frags.t │ ├── prefix-support-rs.t │ └── rename-var.t ├── inc ├── Module │ ├── AutoInstall.pm │ ├── Install.pm │ └── Install │ │ ├── AutoInstall.pm │ │ ├── Base.pm │ │ ├── Can.pm │ │ ├── Fetch.pm │ │ ├── Include.pm │ │ ├── Makefile.pm │ │ ├── Metadata.pm │ │ ├── Scripts.pm │ │ ├── Share.pm │ │ ├── TestBase.pm │ │ ├── Win32.pm │ │ └── WriteAll.pm ├── Spiffy.pm └── Test │ ├── Base.pm │ ├── Base │ └── Filter.pm │ ├── Builder.pm │ ├── Builder │ └── Module.pm │ └── More.pm ├── lib ├── OpenResty.pm ├── OpenResty │ ├── Backend.pm │ ├── Backend │ │ ├── Base.pm │ │ ├── Empty.pm │ │ ├── PLPerl.pm │ │ ├── Pg.pm │ │ ├── PgFarm.pm │ │ ├── PgMocked.pm │ │ └── Prophet.pm │ ├── Cache.pm │ ├── CheatSheet.pod │ ├── Config.pm │ ├── Dispatcher.pm │ ├── FastCGI.pm │ ├── FeedWriter │ │ └── RSS.pm │ ├── Handler │ │ ├── Action.pm │ │ ├── Base.pm │ │ ├── Captcha.pm │ │ ├── CompiledAction.pm │ │ ├── CompiledView.pm │ │ ├── Feed.pm │ │ ├── LastResponse.pm │ │ ├── Login.pm │ │ ├── Logout.pm │ │ ├── Model.pm │ │ ├── ProphetModel.pm │ │ ├── Role.pm │ │ ├── Shell.pm │ │ ├── Unsafe.pm │ │ ├── Version.pm │ │ └── View.pm │ ├── Inlined.pm │ ├── Limits.pm │ ├── QuasiQuote │ │ ├── SQL.pm │ │ ├── Validator.pm │ │ └── Validator │ │ │ └── Compiler.pm │ ├── RestyScript.pm │ ├── RestyScript │ │ ├── View.pm │ │ └── ViewUpgrade.pm │ ├── SQL │ │ ├── Insert.pm │ │ ├── Select.pm │ │ ├── Statement.pm │ │ └── Update.pm │ ├── Script │ │ ├── Compile.pm │ │ └── Upgrade.pm │ ├── Server.pm │ ├── Shell.pm │ ├── Shell │ │ └── History.pm │ ├── Spec │ │ ├── AccountAdmin.pod │ │ ├── Arch_cn.pod │ │ ├── Captcha_cn.pod │ │ ├── Install.pod │ │ ├── Install │ │ │ ├── Apache.pod │ │ │ ├── Binary_cn.pod │ │ │ └── Lighttpd.pod │ │ ├── MetaModel.pod │ │ ├── Overview.pod │ │ ├── REST.pod │ │ ├── REST_cn.pod │ │ ├── TestSuite.pod │ │ └── Upgrading.pod │ ├── Tutorial │ │ ├── GettingStarted │ │ │ └── Perl.pod │ │ ├── GettingStarted_cn.pod │ │ └── RunTestsOnWin32_cn.pod │ └── Util.pm └── WWW │ └── OpenResty │ └── Embedded.pm ├── misc ├── plperl.sql └── restylog │ ├── Makefile │ ├── import.pl │ ├── matrix.tt │ ├── perl.css │ └── stats.tt ├── obsolete └── minisql │ ├── lib │ └── OpenAPI │ │ ├── .~ko-4.1.1-perllint~c │ │ ├── miniSQL.pm │ │ └── miniSQL │ │ └── Compile.pm │ ├── t │ ├── 01-literal.t │ ├── 02-symbol.t │ ├── 03-condition.t │ ├── 04-statements.t │ └── miniSQL.pm │ └── test.pl ├── share └── README ├── t ├── 00-prereq.t ├── 01-sanity.t ├── 02-carrie.t ├── 02-chuanwen.t ├── 03-model.t ├── 04-model-col.t ├── 05-model-row.t ├── 06-charset.t ├── 07-bug.t ├── 09-sql-insert.t ├── 09-sql-select.t ├── 09-sql-update.t ├── 10-order-by.t ├── 11-limits.t ├── 12-offset.t ├── 13-count.t ├── 14-unsafe.t ├── 15-default.t ├── 16-action-runaction.t ├── 16-action-runview.t ├── 17-restyscript-action.t ├── 17-restyscript-view.t ├── 18-url-params.t ├── 19-view.t ├── 20-role.t ├── 20-view.t ├── 21-captcha.t ├── 22-version.t ├── 23-sanity-callback.t ├── 24-session.t ├── 25-filter.t ├── 26-types.t ├── 27-transaction.t ├── 28-feed.t ├── 29-cache.t ├── 29-feed-writer-rss.t ├── 30-action.t ├── 31-action.t ├── 32-view-upgrade.t ├── 33-duplicate-def.t ├── 34-unique.t ├── 35-model-order-by.t ├── 36-subquery.t ├── 37-validator.t ├── 38-global-search.t ├── 39-model-col-bug.t ├── 40-role-acl-bug.t ├── 41-action-proxy.t ├── 42-action-bug.t ├── 43-view-bug.t ├── 49-view-builtin-vars.t ├── 50-action-builtin-vars.t ├── 51_model_row_contents_op.t ├── 52_bits_contain_builtin.t ├── 53_compiled_actions.t ├── 54_role_ip_validation.t ├── 55-login-by-captchapassword.t ├── 56-shell.t ├── 57-encoded-slashes.t ├── 99-pod-coverage.t ├── 99-pod.t ├── OpenResty.pm ├── OpenResty │ └── Util.pm ├── TODO ├── col-not-null │ ├── 01.t │ ├── 02.t │ ├── 03.t │ ├── 04.t │ ├── 05.t │ ├── 06.t │ ├── 07.t │ ├── 08.t │ ├── 09.t │ ├── 10.t │ └── 11.t ├── col-references │ ├── 01.t_ │ ├── 02.t_ │ ├── 03.t_ │ ├── 04.t_ │ ├── 05.t_ │ ├── 06.t_ │ ├── 07.t_ │ ├── 08.t_ │ ├── 09.t_ │ ├── 10.t_ │ └── 11.t_ ├── col-unique │ ├── 01.t │ ├── 02.t │ ├── 03.t │ ├── 04.t │ ├── 05.t │ ├── 06.t │ ├── 07.t │ ├── 08.t │ ├── 09.t │ ├── 10.t │ ├── 11.t │ ├── 12.t │ ├── 13.t │ ├── 14.t │ ├── 15.t │ ├── 16.t │ ├── 17.t │ ├── 18.t │ ├── 19.t │ └── 20.t ├── pg-farm │ ├── 01-sanity.t │ └── 02-user-dist.t ├── pg │ └── sanity.t └── pgmock-data │ ├── 00-prereq.t.json │ ├── 01-sanity.t.json │ ├── 02-carrie.t.json │ ├── 02-chuanwen.t.json │ ├── 03-model.t.json │ ├── 04-model-col.t.json │ ├── 05-model-row.t.json │ ├── 06-charset.t.json │ ├── 07-bug.t.json │ ├── 10-order-by.t.json │ ├── 11-limits.t.json │ ├── 12-offset.t.json │ ├── 13-count.t.json │ ├── 14-unsafe.t.json │ ├── 15-default.t.json │ ├── 16-action-runaction.t.json │ ├── 16-action-runview.t.json │ ├── 18-url-params.t.json │ ├── 19-view.t.json │ ├── 20-role.t.json │ ├── 20-view.t.json │ ├── 21-captcha.t.json │ ├── 22-version.t.json │ ├── 23-sanity-callback.t.json │ ├── 24-session.t.json │ ├── 25-filter.t.json │ ├── 26-types.t.json │ ├── 27-transaction.t.json │ ├── 28-feed.t.json │ ├── 29-cache.t.json │ ├── 30-action.t.json │ ├── 31-action.t.json │ ├── 33-duplicate-def.t.json │ ├── 34-unique.t.json │ ├── 35-model-order-by.t.json │ ├── 36-subquery.t.json │ ├── 38-global-search.t.json │ ├── 39-model-col-bug.t.json │ ├── 40-role-acl-bug.t.json │ ├── 41-action-proxy.t.json │ ├── 42-action-bug.t.json │ ├── 43-view-bug.t.json │ ├── 49-view-builtin-vars.t.json │ ├── 50-action-builtin-vars.t.json │ ├── 51_model_row_contents_op.t.json │ ├── 52_bits_contain_builtin.t.json │ ├── 53_compiled_actions.t.json │ ├── 54_role_ip_validation.t.json │ ├── 55-login-by-captchapassword.t.json │ ├── 56-shell.t.json │ ├── 57-encoded-slashes.t.json │ ├── col-not-null │ ├── 01.t.json │ ├── 02.t.json │ ├── 03.t.json │ ├── 04.t.json │ ├── 05.t.json │ ├── 06.t.json │ ├── 07.t.json │ ├── 08.t.json │ ├── 09.t.json │ ├── 10.t.json │ └── 11.t.json │ ├── col-unique │ ├── 01.t.json │ ├── 02.t.json │ ├── 03.t.json │ ├── 04.t.json │ ├── 05.t.json │ ├── 06.t.json │ ├── 07.t.json │ ├── 08.t.json │ ├── 09.t.json │ ├── 10.t.json │ ├── 11.t.json │ ├── 12.t.json │ ├── 13.t.json │ ├── 14.t.json │ ├── 15.t.json │ ├── 16.t.json │ ├── 17.t.json │ ├── 18.t.json │ ├── 19.t.json │ └── 20.t.json │ ├── pg │ └── sanity.t.json │ └── sanity.t.json ├── test └── util └── push_pkg /.gitignore: -------------------------------------------------------------------------------- 1 | .rsync 2 | bin/openresty.fcgi 3 | demo/Admin/.rsync 4 | *~ 5 | *.json 6 | *.o 7 | *.hi 8 | haskell/bin/openhesty 9 | haskell/openhesty.txt 10 | !*.t.json 11 | cover_db 12 | Makefile 13 | bin/test-account.sh 14 | blib 15 | haskell/big.sql 16 | demo/Springbot/staff/update.sh 17 | demo/*/out 18 | demo/Blog2/js 19 | demo/Blog2/template 20 | demo/Springbot/staff/import 21 | demo/*/script/import-localhost 22 | *.old 23 | *.swp 24 | bin/.openresty.shell.hist 25 | demo/Springbot/staff/staff.* 26 | pm_to_blib 27 | demo/Springbot/staff/staff.html 28 | demo/Blog2/script/init.pl 29 | share/openresty_revision 30 | etc/site_openresty.conf 31 | share/font 32 | haskell/bin/restyscript 33 | t/*.dat 34 | *.tar.gz 35 | demo/Blog2/script/upload 36 | demo/Blog/script/upload 37 | demo/Springbot/staff/*.sql 38 | demo/Click4honor/JSON.js 39 | demo/Click4honor/jquery.js 40 | demo/Click4honor/openresty.js 41 | demo/RestyCheck/JSON.js 42 | demo/RestyCheck/jquery.js 43 | demo/RestyCheck/openresty.js 44 | demo/RestyCheck/upload 45 | demo/*/script/upload 46 | metamodel 47 | demo/Onccf/pack_out 48 | log.txt 49 | TODO1 50 | demo/Onccf/out1 51 | demo/Onccf/out2 52 | demo/Onccf/out3 53 | demo/Onccf/out4 54 | demo/Onccf/out5 55 | demo/Onccf/out6 56 | demo/Onccf/out7 57 | demo/Onccf/out8 58 | diff.txt 59 | etc/compiled.actions 60 | etc/taobao_vip.conf 61 | lib/OpenResty/Handler/YLogin.pm 62 | 63 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | Agent Zhang 章亦春 agentzh{{{}}}yahoo.cn 2 | Laye Suen 孙磊 layesuen{{{}}}gmail.com 3 | cnhackTNT 王晖 cnhacktnt{{{}}}gmail.com 4 | shangerdi 尚尔迪 shangerdi{{{}}}yahoo.com.cn 5 | laser weiping laserhenry{{{}}}gmail.com 6 | Sal Zhong 仲伟祥 zhongxiang721{{{}}}gmail.com 7 | chaoslawful 王晓哲 chaoslawful{{{}}}gmail.com 8 | Xunxin Wan 万珣新 wanxunxin{{{}}}gmail.com 9 | Jiang Xia 姜霞 10 | Jingjing Zhu 朱静静 11 | ------ 12 | Please replace {{{}}} with @. 13 | 14 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2007-2008, Yahoo! China EEEE Works, Alibaba Inc. 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 5 | 6 | * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 7 | * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 8 | * Neither the name of the Yahoo! China EEEE Works, Alibaba Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 9 | 10 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 11 | -------------------------------------------------------------------------------- /TODO.QA: -------------------------------------------------------------------------------- 1 | Coverage testing TODOs: 2 | 3 | 4 | Old TODOs: 5 | * add column hits limit. 6 | * /=/model.json?var=foo 7 | * t/p3p-cookie.t for cross-site cookie support and the cookie_site url param 8 | * view description should be mandatory 9 | * [bug] when view name is duplicate (POST/PUT) 10 | * [bug] when view definition is duplicate (POST/PUT) 11 | * [bug] reject updating the names of the builtin roles. 12 | * add the sorting capability (i.e. the order_by url param) to model/view/role lists 13 | * [bug] PUT an empty label. 14 | * [bug] PUT /=/role/Foo/id/32 does not work as expected. 15 | * order in ACL rule listing 16 | 17 | 1、 18 | action 的参数值为 0 时会有错误。。。 19 | agent.zhang: 1. action 参数用于 URL 拼接 20 | agent.zhang: 2. action 参数用于 SQL 语句比如 where col > $value 中的 value 参数 21 | 22 | 2、 23 | agent.zhang: 1. 递归调用 action (分直接递归和间接递归两种) 24 | 25 | 3、 26 | agent.zhang: 创建一个带参数的 action 27 | agent.zhang: 然后在调用它时,参数提供一个带汉字的值 28 | agent.zhang: 目前的(错误的)实现是会引入乱码 -------------------------------------------------------------------------------- /bin/compile-views: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | bin/openresty compile '/=/view/getquery/spell/q.yml?_user=yquestion.Public' '/=/view/t/a/水煮鱼?c=北京&_user=lifecai.s&t=50' 4 | 5 | -------------------------------------------------------------------------------- /bin/fetch-font.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | 3 | use strict; 4 | use warnings; 5 | 6 | use LWP::UserAgent; 7 | 8 | my $url = 'http://agentzh.org/misc/wqy-zenhei.ttf'; 9 | my $ua = LWP::UserAgent->new; 10 | $ua->timeout(10); 11 | $ua->env_proxy; 12 | 13 | mkdir 'share/font' unless -d 'share/font'; 14 | my $file = 'share/font/wqy-zenhei.ttf'; 15 | unless (-f $file and -s $file > 13000000) { 16 | warn "Fetching $url...\n"; 17 | $ua->mirror($url, $file); 18 | } 19 | 20 | -------------------------------------------------------------------------------- /bin/httpresty.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | 3 | use strict; 4 | use warnings; 5 | 6 | use lib '../../lib'; 7 | use utf8; 8 | use JSON::XS; 9 | use YAML 'Dump'; 10 | use WWW::OpenResty::Simple; 11 | #use Date::Manip; 12 | use Getopt::Std; 13 | use Encode qw(encode decode from_to); 14 | 15 | #$JSON::Syck::ImplicitUnicode = 1; 16 | #$YAML::Syck::ImplicitUnicode = 1; 17 | my $json_xs = JSON::XS->new->utf8->allow_nonref; 18 | 19 | my %opts; 20 | getopts('u:s:p:c:h', \%opts); 21 | if ($opts{h}) { 22 | die "Usage: $0 -c -u -p -s \n"; 23 | } 24 | my $user = $opts{u} or 25 | die "No OpenResty account name specified via option -u\n"; 26 | my $password = $opts{p} or 27 | die "No OpenResty account's Admin password specified via option -p\n"; 28 | my $server = $opts{s} || 'http://api.openresty.org'; 29 | 30 | my $resty = WWW::OpenResty::Simple->new( { server => $server } ); 31 | $resty->login($user, $password); 32 | 33 | my $meth = shift or 34 | die "No method specified.\n"; 35 | $meth = lc($meth); 36 | 37 | my $url = shift or 38 | die "No url spcified.\n"; 39 | if ($opts{c}) { 40 | from_to($url, $opts{c}, 'utf8'); 41 | } 42 | 43 | if (!$resty->can($meth)) { 44 | die "Method $meth not found.\n"; 45 | } 46 | 47 | my $res = $resty->$meth($url); 48 | my $out = Dump($res); 49 | if ($opts{c}) { 50 | $out = encode($opts{c}, $out); 51 | } 52 | print $out, "\n"; 53 | 54 | -------------------------------------------------------------------------------- /bin/install-deps.sh: -------------------------------------------------------------------------------- 1 | #/bin/sh 2 | 3 | #sudo cpan -f Term::ReadLine::Gnu 4 | sudo cpan Jemplate Template YAML GD CGI::Cookie::XS FCGI CGI::Simple \ 5 | YAML::Syck \ 6 | List::Util \ 7 | DBI Clone Params::Util Parse::Yapp DBD::Pg Data::UUID \ 8 | GD::SecurityImage Cache::Memcached::libmemcached Hash::Merge \ 9 | Config::Simple Encode::Guess List::MoreUtils JSON::XS \ 10 | Data::Structure::Util DateTime::Format::Pg \ 11 | DateTime::Format::Strptime Digest::MD5 File::ShareDir \ 12 | Compress::Zlib Crypt::CBC Crypt::Rijndael IPC::Run3 IPC::Run \ 13 | Time::HiRes Filter::QuasiQuote Parse::RecDescent Benchmark::Timer \ 14 | HTTP::Server::Simple Text::Diff Text::Table \ 15 | Term::ReadLine::Perl Term::ReadLine::Gnu Term::ReadKey \ 16 | CGI Cache::Cache Class::Prototyped Test::LongString \ 17 | HTTP::Response WWW::OpenResty LWP::UserAgent 18 | 19 | -------------------------------------------------------------------------------- /bin/prettyjson: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | 3 | use strict; 4 | use warnings; 5 | 6 | use JSON::XS (); 7 | use YAML::Syck (); 8 | 9 | my $json_xs = JSON::XS->new->utf8->pretty; 10 | my $infile = shift or die "No input file specified.\n"; 11 | open my $in, $infile or die "Cannot open input file $infile for reading: $!"; 12 | my $json = do { local $/; <$in> }; 13 | my $data = $json_xs->decode($json); 14 | print $json_xs->encode($data); 15 | 16 | -------------------------------------------------------------------------------- /bin/reindex: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | 3 | die <<'_EOC_'; 4 | This tool is obsolete! 5 | Please use the reindex script in the openresty/lua-nginx-module 6 | GitHub repository instead: 7 | 8 | https://github.com/openresty/openresty-devel-utils/blob/master/reindex 9 | _EOC_ 10 | -------------------------------------------------------------------------------- /bin/repeat: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | 3 | use strict; 4 | use warnings; 5 | use File::Slurp; 6 | 7 | my $infile = shift or die "No input .t file specified.\n"; 8 | my $code = read_file($infile) ; 9 | $code =~ s/\brun_tests\b/while (1) { run_tests; warn "\n====== PID: $$\n"; }/s; 10 | mkdir 'tmp' if !-d 'tmp'; 11 | write_file("tmp/tmp.t", $code); 12 | system('prove', 'tmp/tmp.t'); 13 | 14 | -------------------------------------------------------------------------------- /bin/test-memcached.pl: -------------------------------------------------------------------------------- 1 | use strict; 2 | use warnings; 3 | use Test::More; 4 | 5 | use Cache::Memcached::libmemcached; 6 | my @servers = map glob, @ARGV; 7 | if (!@servers) { die "No server specified.\n"; } 8 | 9 | plan tests => 2 * @servers; 10 | 11 | for my $server (@servers) { 12 | my $obj = Cache::Memcached::libmemcached->new({ 13 | servers => [$server], 14 | }); 15 | 16 | ok $obj, "$server - memcached obj ok"; 17 | $obj->delete('foo'); 18 | $obj->set(foo => $server, 3); 19 | my $value = $obj->get('foo'); 20 | is $value, $server, "$server - successfully set and get the key foo"; 21 | } 22 | 23 | -------------------------------------------------------------------------------- /clients/perl/README: -------------------------------------------------------------------------------- 1 | See the WWW::OpenResty and WWW::OpenResty::Simple modules on CPAN for the Perl version of the OpenAPI client-side library: 2 | 3 | http://search.cpan.org/dist/WWW-OpenResty 4 | 5 | -------------------------------------------------------------------------------- /debian/conffiles: -------------------------------------------------------------------------------- 1 | /etc/openresty/openresty.conf 2 | /etc/openresty/site_openresty.conf 3 | -------------------------------------------------------------------------------- /debian/control: -------------------------------------------------------------------------------- 1 | Source: libopenresty-perl 2 | Section: web 3 | Priority: optional 4 | Build-Depends: debhelper (>= 5.0.0) 5 | Build-Depends-Indep: perl (>= 5.8.8-12) 6 | Maintainer: Agent Zhang 7 | Standards-Version: 3.7.2 8 | Homepage: http://search.cpan.org/dist/OpenResty/ 9 | 10 | Package: libopenresty-perl 11 | Architecture: i386 12 | Depends: ${perl:Depends}, libcookie-xs-perl, libfcgi-perl, libdbi-perl, libdbd-pg-perl, libcgi-simple-perl, libyaml-syck-perl, libclone-perl, libparams-util-perl, libparse-yapp-perl, libdata-uuid-perl, libgd-securityimage-perl, libcache-memcached-fast-perl, libhash-merge-perl, libconfig-simple-perl, liblist-moreutils-perl, libjson-xs-perl, libdata-structure-util-perl, libdatetime-format-strptime-perl, libdatetime-format-pg-perl, libdigest-md5-perl, libfile-sharedir-perl, libcrypt-cbc-perl, libcrypt-rijndael-perl, libipc-run3-perl, libipc-run-perl, libbenchmark-timer-perl, libhttp-server-simple-perl, libtext-diff-perl, libtext-table-perl, libterm-readline-gnu-perl, libterm-readkey-perl, libcgi-perl, libcache-cache-perl, libclass-prototyped-perl, libtest-longstring-perl, libwww-openresty-perl, libwww-perl 13 | Description: General-purpose web service platform for web applications 14 | General-purpose web service platform for web applications 15 | . 16 | OpenResty 17 | 18 | -------------------------------------------------------------------------------- /debian/postinst: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | echo "!!!!!!! Remember to configure your OpenResty backend in /etc/openresty/site_openresty.conf !!!!!!!!" 4 | 5 | -------------------------------------------------------------------------------- /demo/Admin/README: -------------------------------------------------------------------------------- 1 | This is the source code for the site http://openresty.org/admin/ . 2 | 3 | It requires the CPAN packages Jemplate and Template. Please install them like this: 4 | 5 | $ sudo cpan Jemplate Template 6 | 7 | To build the site: 8 | 9 | $ make 10 | 11 | Then out/ will hold the binary site ready for deployment. 12 | 13 | Note that you need the whole OpenResty source tree to build this site. 14 | Because some of the .js files are copied over from ../../clients/js/ 15 | and somewhere else :) 16 | 17 | -------------------------------------------------------------------------------- /demo/Admin/css/fonts.css: -------------------------------------------------------------------------------- 1 | /** 2 | * 84.5% for !IE, keywords for IE 3 | * Percents could work for IE, but for backCompat purposes, we are using keywords. 4 | * x-small is for IE < 6 and IE6 quirks mode. 5 | * 6 | */ 7 | body {font:13px arial,helvetica,clean,sans-serif;*font-size:small;*font:x-small;} 8 | table {font-size:inherit;font:100%;} 9 | 10 | /** 11 | * 99% for safari; 100% is too large 12 | */ 13 | select, input, textarea {font:99% arial,helvetica,clean,sans-serif;} 14 | 15 | /** 16 | * Bump up !IE to get to 13px equivalent 17 | */ 18 | pre, code {font:115% monospace;*font-size:100%;} 19 | 20 | /** 21 | * Default line-height based on font-size rather than "computed-value" 22 | * see: http://www.w3.org/TR/CSS21/visudet.html#line-height 23 | */ 24 | body * {line-height:1.22em;} 25 | -------------------------------------------------------------------------------- /demo/Admin/image/lower-left.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agentzh/old-openresty/53dad17e84dc6d2a0dffddb119851c50c0ca3a8d/demo/Admin/image/lower-left.gif -------------------------------------------------------------------------------- /demo/Admin/image/lower-right.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agentzh/old-openresty/53dad17e84dc6d2a0dffddb119851c50c0ca3a8d/demo/Admin/image/lower-right.gif -------------------------------------------------------------------------------- /demo/Admin/image/upper-left.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agentzh/old-openresty/53dad17e84dc6d2a0dffddb119851c50c0ca3a8d/demo/Admin/image/upper-left.gif -------------------------------------------------------------------------------- /demo/Admin/image/upper-right.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agentzh/old-openresty/53dad17e84dc6d2a0dffddb119851c50c0ca3a8d/demo/Admin/image/upper-right.gif -------------------------------------------------------------------------------- /demo/Admin/js/thirdparty/jquery.cookie.pack.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Cookie plugin 3 | * 4 | * Copyright (c) 2006 Klaus Hartl (stilbuero.de) 5 | * Dual licensed under the MIT and GPL licenses: 6 | * http://www.opensource.org/licenses/mit-license.php 7 | * http://www.gnu.org/licenses/gpl.html 8 | * 9 | */ 10 | eval(function(p,a,c,k,e,r){e=function(c){return(c35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('r.5=w(k,d,a){4(m d!=\'H\'){a=a||{};4(d===p){d=\'\';a.3=-1}2 g=\'\';4(a.3&&(m a.3==\'n\'||a.3.u)){2 f;4(m a.3==\'n\'){f=G E();f.C(f.B()+(a.3*z*s*s*v))}o{f=a.3}g=\'; 3=\'+f.u()}2 b=a.7?\'; 7=\'+(a.7):\'\';2 e=a.9?\'; 9=\'+(a.9):\'\';2 l=a.t?\'; t\':\'\';6.5=[k,\'=\',K(d),g,b,e,l].I(\'\')}o{2 h=p;4(6.5&&6.5!=\'\'){2 c=6.5.F(\';\');D(2 i=0;i 2 | 3 |   Loading...  4 | 5 | 6 |
7 | 8 | 9 | 16 | 19 | 20 | 22 | 23 | 24 |
25 | 26 | -------------------------------------------------------------------------------- /demo/Admin/template/elem/column-inputs.tt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | not null 7 | 8 | -------------------------------------------------------------------------------- /demo/Admin/template/elem/create-action.tt: -------------------------------------------------------------------------------- 1 |
2 | 3 | New action 4 | 5 |
6 | 7 |
8 |
9 | 10 |

11 | 12 | 13 |

14 |

15 | 16 | 17 |

18 | 19 |

20 |

21 | Add a parameter 22 |

23 |

24 | 25 |

26 |

27 | 28 |

29 | 30 |

31 | 32 |

33 | 34 |
35 |
36 | 37 | -------------------------------------------------------------------------------- /demo/Admin/template/elem/create-bulk-row.tt: -------------------------------------------------------------------------------- 1 | [%# DEFAULT 2 | model = "Foo" 3 | %] 4 |
5 | 6 | New model rows 7 | 8 |
9 |
10 | 11 |
12 | 13 |

Example:

14 |
15 |         {"title":"This time I won!","author":"agentzh"}
16 |         {"title":"Yahoo! wows","author":"laser"}
17 |         {"title":"Perl is here","author":"chromatic"}
18 |     
19 | 20 |

21 |   Ignore "id" values 22 | 23 |

24 |

25 |   Lines per request (step) 26 | 27 |

28 |

29 | 30 |

31 |
32 |
33 | 34 | -------------------------------------------------------------------------------- /demo/Admin/template/elem/create-feed.tt: -------------------------------------------------------------------------------- 1 |
2 | 3 | New feed 4 | 5 |
6 | 7 |
8 |
9 | 10 |

11 | 12 | 13 |

14 |

15 | 16 | 17 |

18 | 19 |

20 | 21 | 22 |

23 |

24 | 25 | 26 |

27 |

28 | 29 | 30 |

31 |

32 | 33 | 34 |

35 |

36 | 37 | 38 |

39 |

40 | 41 | 42 |

43 | 44 |

45 | 46 | 47 |

48 | 49 |

50 | 51 |

52 |
53 |
54 | 55 | -------------------------------------------------------------------------------- /demo/Admin/template/elem/create-model.tt: -------------------------------------------------------------------------------- 1 |
2 | 3 | New model 4 | 5 |
6 | 7 |
8 |
9 | 10 |

11 | 12 | 13 |

14 |

15 | 16 | 17 |

18 | 19 |

20 |

21 | Add a column 22 |

23 |

24 | 25 |

26 | 27 |
28 |
29 | 30 | -------------------------------------------------------------------------------- /demo/Admin/template/elem/create-role.tt: -------------------------------------------------------------------------------- 1 |
2 | 3 | New role 4 | 5 |
6 | 7 |
8 |
9 | 10 |

11 | 12 | 13 |

14 |

15 | 16 | 17 |

18 |

19 | 20 | 25 |

26 |

27 | 28 | 29 |

30 | 31 |

32 | 33 |

34 | 35 |
36 |
37 | 38 | -------------------------------------------------------------------------------- /demo/Admin/template/elem/create-row.tt: -------------------------------------------------------------------------------- 1 | [%# DEFAULT 2 | model = { 3 | name => "Foo", 4 | columns => [ 5 | { name => 'name', type => 'text' } 6 | ] 7 | } 8 | %] 9 |
10 | 11 | New model row 12 | 13 |
14 |
15 |
16 | [%- cols = {} %] 17 | [%- FOREACH col = model.columns %] 18 | [%- NEXT IF col.name == 'id' %] 19 | [%- name = col.name %] 20 | [%- cols.$name = col %] 21 | [%- END %] 22 | [%- FOREACH name IN cols.keys.sort %] 23 | [%- col = cols.$name %] 24 | 25 | [%- IF col.type == "text" %] 26 | 27 | [%- ELSE %] 28 | 29 | [%- END %] 30 |
31 | [%- END %] 32 |

33 | 34 |

35 |
36 |
37 | 38 | -------------------------------------------------------------------------------- /demo/Admin/template/elem/create-view.tt: -------------------------------------------------------------------------------- 1 |
2 | 3 | New view 4 | 5 |
6 | 7 |
8 |
9 | 10 |

11 | 12 | 13 |

14 |

15 | 16 | 17 |

18 |

19 | 20 |

21 |

22 | 23 |

24 | 25 |

26 | 27 |

28 | 29 |
30 |
31 | 32 | -------------------------------------------------------------------------------- /demo/Admin/template/elem/feed.tt: -------------------------------------------------------------------------------- 1 | [% BLOCK editable_feed_value -%] 2 | [% value | html %] 3 | [% END -%] 4 | 5 | 6 |
7 | [% feed.name %] 8 |
9 | 10 |
11 |
    12 |
  • Name: [% feed.name | html %]
  • 13 |
  • Description: [% INCLUDE editable_feed_value key="description", value=feed.description %]
  • 14 |
  • View: [% INCLUDE editable_feed_value key="view", value=feed.view %]
  • 15 |
  • Title: [% INCLUDE editable_feed_value key="title", value=feed.title %]
  • 16 |
  • Copyright: [% INCLUDE editable_feed_value key="copyright", value=feed.copyright %]
  • 17 |
  • Author: [% INCLUDE editable_feed_value key="author", value=feed.author %]
  • 18 |
  • Link: [% INCLUDE editable_feed_value key="link", value=feed.link %]
  • 19 |
  • Logo image URL: [% INCLUDE editable_feed_value key="logo", value=feed.logo %]
  • 20 |
  • Language: [% INCLUDE editable_feed_value key="language", value=feed.language %]
  • 21 |
  • 22 | Delete this feed 23 |
  • 24 |
25 | 26 |
27 |
28 | 29 | 30 | -------------------------------------------------------------------------------- /demo/Admin/template/elem/menu.tt: -------------------------------------------------------------------------------- 1 | [% DEFAULT 2 | menu = [ 3 | 'Models', 4 | 'Views', 5 | 'Feeds', 6 | 'Actions', 7 | 'Roles', 8 | 'Consoles', 9 | ], 10 | active_item = 'Views', 11 | submenu = [ 12 | { 13 | description => 'Blog post', 14 | name => 'Post', 15 | src => '/=/model/Post', 16 | }, 17 | { 18 | description => 'Blog comment', 19 | name => 'Comment', 20 | src => '/=/model/Comment', 21 | }, 22 | { 23 | description => 'Yahoo! China Staff', 24 | name => 'YahooStaff', 25 | src => '/=/model/YahooStaff' 26 | }, 27 | { 28 | description => 'IRC Log', 29 | name => 'IrcLog', 30 | src => '/=/model/IrcLog', 31 | } 32 | ]; 33 | -%] 34 | 35 | [%- prefix = active_item.replace('s$', '') %] 36 | 37 | Logout 38 | 39 |
40 |
    41 | 42 | [%- i = 0 %] 43 | [%- FOREACH item IN menu %] 44 | 45 |
  • 46 | 47 | [% item %] 48 | 49 |
  • 50 | 51 | [%- i = i + 1 %] 52 | [%- END %] 53 | 54 |
55 |
56 | 57 | 64 | 65 | -------------------------------------------------------------------------------- /demo/Admin/template/elem/model-dump-res.tt: -------------------------------------------------------------------------------- 1 | 2 | Cancel 3 |
4 |
5 | 6 | 7 | -------------------------------------------------------------------------------- /demo/Admin/template/elem/pager.tt: -------------------------------------------------------------------------------- 1 | [% DEFAULT 2 | page = 1, 3 | page_count = undef, 4 | title = 'Pages', 5 | prefix = 'post-list/', 6 | suffix = '' 7 | -%] 8 | 9 | [% IF page_count <= 10; 10 | from = 1; 11 | to = page_count; 12 | ELSE; 13 | from = page - 10 >= 1 ? page - 10 : 1 14 | to = page + 9 >= page_count ? page_count : page + 9; 15 | END -%] 16 | 17 |
18 | 19 | 20 | 23 | 30 | 31 | [%- i = from; %] 32 | [%- WHILE i <= to %] 33 | [%- IF i == page %] 34 | 35 | [%- ELSE %] 36 | 37 | [%- END %] 38 | [%- i = i + 1 %] 39 | [%- END %] 40 | 41 | 48 | 49 |
21 | [% title %]:    22 | 24 | [%- IF page > 1 %] 25 | 26 | Previous 27 | 28 | [%- END %] 29 | [% i %][% i %] 42 | [%- IF page < page_count %] 43 | 44 | Next 45 | 46 | [%- END %] 47 |
50 |
51 |
52 | -------------------------------------------------------------------------------- /demo/Admin/template/elem/param-inputs.tt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /demo/Admin/template/elem/view.tt: -------------------------------------------------------------------------------- 1 | [% DEFAULT 2 | view = { 3 | definition => "select id, title, date_part('day', created) as day\n from Post\n where date_part('year', created) = $year and\n date_part('month', created) = $month\n order by created asc\n", 4 | description => undef, 5 | name => "PostsByMonth", 6 | }; 7 | %] 8 | 9 | [% BLOCK editable_view_value -%] 10 | [% value | html %] 11 | [% END -%] 12 | 13 | 14 |
15 | [% view.name %] 16 |
17 | 18 |
19 |
    20 |
  • Name: [% view.name | html %]
  • 21 |
  • Description: [% INCLUDE editable_view_value key="description", value=view.description %]
  • 22 |
  • Definition: 23 |
    24 |
    [% INCLUDE editable_view_value key="definition", value=view.definition %]
  • 25 |
  • 26 | Delete this view 27 |
  • 28 |
29 | 30 |
31 |
32 | 33 | 34 | -------------------------------------------------------------------------------- /demo/Admin/template/footer.tt: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 |
5 | 6 | 10 | 13 | 14 | 15 | 19 | 20 | 23 |
7 | Google Groups 9 |
11 | Subscribe to openresty 12 |
16 | Email: 17 | 18 |
21 | Visit this group 22 |
24 | 25 |
26 |

27 | This site can be downloaded from here (.tar.gz) and its Git repository has anonymous access to all. 28 |

29 |
30 |
31 |

Powered by OpenResty and your web browser.

32 |
33 | 35 |

Copyright © 2008 Yahoo! China EEEE Works, Alibaba Inc.

36 |
37 | 38 |
39 | 40 | -------------------------------------------------------------------------------- /demo/Admin/template/header.tt: -------------------------------------------------------------------------------- 1 | [%- IF ! pack_js; 2 | js_files = [ 3 | 'dojo.openresty.js', 4 | 'openresty.js', 5 | 'md5.js', 6 | 'jquery.js', 7 | 'jquery.jeditable.pack.js', 8 | 'jquery.cookie.pack.js', 9 | 'admin-jemplate.js', 10 | 'model.js', 11 | 'view.js', 12 | 'role.js', 13 | 'feed.js', 14 | 'action.js', 15 | 'dispatcher.js', 16 | 'admin.js', 17 | ]; 18 | ELSE; 19 | js_files = [ 20 | 'jquery-min.js', 21 | 'admin-min.js' 22 | ]; 23 | END; 24 | %] 25 | OpenResty Admin 26 | 27 | 28 | 29 | [%- FOR file IN js_files %] 30 | 31 | [%- END -%] 32 | 33 | -------------------------------------------------------------------------------- /demo/Admin/template/index.tt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | [%- PROCESS 'header.tt' %] 5 | 6 | 7 | 8 | 9 | 10 | [%- PROCESS 'banner.tt' %] 11 | 12 | 13 |
14 | 16 | 17 |
18 |
19 | 20 | [%- PROCESS 'footer.tt' %] 21 |
22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /demo/Blog/README: -------------------------------------------------------------------------------- 1 | This is the source for the blog site http://blog.agentzh.org . 2 | 3 | How to setup the site: 4 | 5 | * First of all, ask agentzh for an OpenAPI account by writing to agentzh@yahoo.cn 6 | 7 | * cd into this directory and enter the following commands: 8 | 9 | $ sudo cpan Jemplate WWW::OpenResty YAML Template 10 | $ script/init.pl -u your_account -p your_password -s your_server 11 | $ vim js/blog.js # change "agentzh" to your account name 12 | $ vim Makefile # change blog_name and blog_desc to your own 13 | $ make 14 | $ firefox out/index.html & 15 | 16 | Note that you need the whole OpenResty source tree to build this site. 17 | Because some of the .js files are copied over from ../../clients/js/ 18 | and somewhere else :) 19 | 20 | -------------------------------------------------------------------------------- /demo/Blog/TODO: -------------------------------------------------------------------------------- 1 | * Tags and category support. 2 | * Full-text search within the blog (for both comments and posts). 3 | * Captcha image in the comment form. 4 | * Use custom action PostComment rather than chained POST and PUT. 5 | * Blog admin interface 6 | 7 | -------------------------------------------------------------------------------- /demo/Blog/css/blog.css: -------------------------------------------------------------------------------- 1 | .entry-header b { 2 | color: #cc0022; 3 | } 4 | 5 | #beta-inner.pkg b { 6 | color: #cc0022; 7 | font-weight: normal; 8 | } 9 | 10 | input#searchbox { 11 | margin-top: 5px; 12 | margin-bottom: 5px; 13 | color:#369; 14 | background:#fff; 15 | width: 180px; 16 | } 17 | 18 | div#wait-message { 19 | color: red !important; 20 | background: white !important; 21 | font-size: 18px !important; 22 | float: right; 23 | position: fixed; 24 | top: 2px; 25 | right: 30px; 26 | padding: 4px; 27 | border-width: 2px; 28 | border-style: outset; 29 | border-color: white; 30 | display: block; 31 | } 32 | 33 | td.today-cell { 34 | background: #fff; 35 | } 36 | 37 | td.highlight { 38 | font-weight: bold; 39 | color:#A90A08; 40 | } 41 | 42 | input.required { 43 | background: #ffa; 44 | } 45 | 46 | ins.item-body { 47 | text-decoration: none; 48 | } 49 | 50 | a.nav-arrow { 51 | font-size: 10pt; 52 | font-weight: bold; 53 | } 54 | 55 | ins { 56 | font-style: normal; 57 | } 58 | 59 | table.paging { 60 | border: 0; 61 | width: 1%; 62 | } 63 | 64 | table.paging td { 65 | font-size: 90%; 66 | white-space: nowrap; 67 | } 68 | 69 | .prev-page { 70 | text-align: right; 71 | font-size: 12pt; 72 | color: #00c; 73 | font-weight: bold; 74 | } 75 | 76 | .next-page { 77 | text-align: left; 78 | font-size: 12pt; 79 | color: #00c; 80 | font-weight: bold; 81 | } 82 | 83 | -------------------------------------------------------------------------------- /demo/Blog/css/styles.css: -------------------------------------------------------------------------------- 1 | /* Base */ 2 | @import url(themes/common/base-weblog.css); 3 | 4 | /* Tip Jar */ 5 | @import url(themes/common/tipjar.css); 6 | 7 | /* Portal */ 8 | 9 | 10 | /* Theme */ 11 | @import url(themes/lilia/theme-bluecrush.css); 12 | 13 | /* Custom */ 14 | body 15 | { 16 | font-family: 'Corbel', 'Cambria', 'trebuchet ms', helvetica, arial, sans-serif; 17 | font-size: 15px; 18 | color: black; 19 | } 20 | 21 | tt 22 | { 23 | font-family: 'Consolas', 'Courier New', 'FreeMono', monospace; 24 | } 25 | 26 | h1, h2, h3, h4, h5, h6 27 | { 28 | font-family: 'Cambria', 'Corbel', 'Candara', 'trebuchet ms', helvetica, arial, sans-serif; 29 | font-weight: bold; 30 | } 31 | 32 | a { color: #009; text-decoration: underline; } 33 | a:visited { color: #306 } 34 | 35 | .entry h2 { 36 | color: #930; 37 | font-size: 18px; 38 | border-bottom: 1px dotted #930; 39 | margin-bottom: 15px; 40 | font-weight: bold; 41 | } 42 | 43 | h3 { 44 | color: #000; 45 | font-size: 15px; 46 | margin-bottom: 10px; 47 | } 48 | 49 | 50 | -------------------------------------------------------------------------------- /demo/Blog/css/themes/lilia/theme-bluecrush/banner-bg.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agentzh/old-openresty/53dad17e84dc6d2a0dffddb119851c50c0ca3a8d/demo/Blog/css/themes/lilia/theme-bluecrush/banner-bg.gif -------------------------------------------------------------------------------- /demo/Blog/css/themes/lilia/theme-bluecrush/colitem-header-bg.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agentzh/old-openresty/53dad17e84dc6d2a0dffddb119851c50c0ca3a8d/demo/Blog/css/themes/lilia/theme-bluecrush/colitem-header-bg.gif -------------------------------------------------------------------------------- /demo/Blog/css/themes/lilia/theme-bluecrush/column-left-bg.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agentzh/old-openresty/53dad17e84dc6d2a0dffddb119851c50c0ca3a8d/demo/Blog/css/themes/lilia/theme-bluecrush/column-left-bg.gif -------------------------------------------------------------------------------- /demo/Blog/css/themes/lilia/theme-bluecrush/container-bg.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agentzh/old-openresty/53dad17e84dc6d2a0dffddb119851c50c0ca3a8d/demo/Blog/css/themes/lilia/theme-bluecrush/container-bg.gif -------------------------------------------------------------------------------- /demo/Blog/css/themes/lilia/theme-bluecrush/li-bg.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agentzh/old-openresty/53dad17e84dc6d2a0dffddb119851c50c0ca3a8d/demo/Blog/css/themes/lilia/theme-bluecrush/li-bg.gif -------------------------------------------------------------------------------- /demo/Blog/css/themes/lilia/theme-bluecrush/thumbnailed-bg.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agentzh/old-openresty/53dad17e84dc6d2a0dffddb119851c50c0ca3a8d/demo/Blog/css/themes/lilia/theme-bluecrush/thumbnailed-bg.gif -------------------------------------------------------------------------------- /demo/Blog/doc/blog_site.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agentzh/old-openresty/53dad17e84dc6d2a0dffddb119851c50c0ca3a8d/demo/Blog/doc/blog_site.png -------------------------------------------------------------------------------- /demo/Blog/doc/graphviz.mk: -------------------------------------------------------------------------------- 1 | blog.agentzh.org: index.html blog.js jquery.js JSON.js openresty.js jemplates.js 2 | 3 | index.html: header.tt index.tt footer.tt sidebar.tt 4 | tpage $| > $@ 5 | 6 | jemplates.js: pager.tt nav.tt calendar.tt post.tt comments.tt archive-list.tt post-list.tt 7 | jemplate --compile 8 | 9 | -------------------------------------------------------------------------------- /demo/Blog/image/loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agentzh/old-openresty/53dad17e84dc6d2a0dffddb119851c50c0ca3a8d/demo/Blog/image/loading.gif -------------------------------------------------------------------------------- /demo/Blog/image/me.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agentzh/old-openresty/53dad17e84dc6d2a0dffddb119851c50c0ca3a8d/demo/Blog/image/me.jpg -------------------------------------------------------------------------------- /demo/Blog/script/reset.mk: -------------------------------------------------------------------------------- 1 | password= 2 | server= 3 | user= 4 | 5 | export: 6 | -mkdir backup 7 | -cp *.json backup 8 | ../../bin/export-model.pl --user $(user) --model Comment --server $(server) --out Comment.json 9 | ../../bin/export-model.pl --step 10 --user $(user) --model Post --server $(server) --out Post.json 10 | 11 | import: 12 | script/init.pl -u $(user) -p $(password) -s $(server) 13 | ../../bin/import-model.pl --reset --step 1 --user $(user) --password $(password) --model Post --server $(server) Post.json 14 | ../../bin/import-model.pl --reset --user $(user) --password $(password) --model Comment --server $(server) Comment.json 15 | 16 | # create or replace function to_fti(text, text) returns tsvector as $$ select setweight(to_tsvector('chinesecfg', $1), 'A') || to_tsvector('chinesecfg', $2) $$ language sql immutable; 17 | # select title, ts_headline('chinesecfg', content, q) as headline from "Post", to_tsquery('chinesecfg', 'OpenResty|Google') as q where to_fti(title, content) @@ q order by ts_rank(to_fti(title, content), q) desc; 18 | # 19 | 20 | -------------------------------------------------------------------------------- /demo/Blog/template/banner.tt: -------------------------------------------------------------------------------- 1 | [% DEFAULT 2 | blog_name = 'Foo\'s blog', 3 | blog_desc = 'This is my blog' 4 | -%] 5 | 17 | 18 | -------------------------------------------------------------------------------- /demo/Blog/template/elem/archive-list.tt: -------------------------------------------------------------------------------- 1 | 9 | 10 |

11 | 12 | [% IF offset > 0 %] 13 | << 14 | [% END %] 15 |     16 |     17 |     18 |     19 |     20 | [% IF archives.size == count %] 21 | 22 | Next... 23 | 24 | [% END %] 25 | 26 |

27 | 28 | -------------------------------------------------------------------------------- /demo/Blog/template/elem/archive-nav.tt: -------------------------------------------------------------------------------- 1 | [% IF next %] 2 | [%- index = next.month %] 3 | 4 | « [% months.$index %] [% next.year %] 5 | 6 | [% END %] 7 | | 8 | Main 9 | | 10 | [% IF prev %] 11 | [%- index = prev.month %] 12 | 13 | [% months.$index %] [% prev.year %] » 14 | 15 | [% END %] 16 | 17 | -------------------------------------------------------------------------------- /demo/Blog/template/elem/comments.tt: -------------------------------------------------------------------------------- 1 | [%- FOREACH comment IN comments -%] 2 | 3 |
4 |
5 | [%- IF comment.body %] 6 | [%- comment.body.replace('&', '&') 7 | .replace('<', '<') 8 | .replace('>', '>') 9 | .replace('\n', '
') 10 | .replace(' ', '  ') 11 | .replace('(http://(?:\%[A-Fa-f0-9]{2}|[-A-Za-z./0-9~_])+)', '$1') %] 12 | [%- END %] 13 |
14 | 27 |
28 | [%- END %] 29 | 30 | -------------------------------------------------------------------------------- /demo/Blog/template/elem/nav.tt: -------------------------------------------------------------------------------- 1 | [% 2 | SET prev_post = undef; 3 | SET next_post = undef; 4 | FOREACH post IN posts; 5 | IF post.id < current; 6 | prev_post = post; 7 | ELSE; 8 | next_post = post; 9 | END; 10 | END -%] 11 | [% IF next_post %] 12 | 13 | « [% next_post.title %] 14 | 15 | [% END %] 16 | | 17 | Main 18 | | 19 | [% IF prev_post %] 20 | 21 | [% prev_post.title %] » 22 | 23 | [% END %] 24 | 25 | -------------------------------------------------------------------------------- /demo/Blog/template/elem/pager.tt: -------------------------------------------------------------------------------- 1 | [% DEFAULT 2 | page = 1, 3 | page_count = undef, 4 | title = 'Pages', 5 | prefix = 'post-list/', 6 | suffix = '' 7 | -%] 8 | 9 | [% IF page_count <= 10; 10 | from = 1; 11 | to = page_count; 12 | ELSE; 13 | from = page - 10 >= 1 ? page - 10 : 1 14 | to = page + 9 >= page_count ? page_count : page + 9; 15 | END -%] 16 | 17 |
18 | 19 | 20 | 23 | 30 | 31 | [%- i = from; %] 32 | [%- WHILE i <= to %] 33 | [%- IF i == page %] 34 | 35 | [%- ELSE %] 36 | 37 | [%- END %] 38 | [%- i = i + 1 %] 39 | [%- END %] 40 | 41 | 48 | 49 |
21 | [% title %]:    22 | 24 | [%- IF page > 1 %] 25 | 26 | Previous 27 | 28 | [%- END %] 29 | [% i %][% i %] 42 | [%- IF page < page_count %] 43 | 44 | Next 45 | 46 | [%- END %] 47 |
50 |
51 |
52 | -------------------------------------------------------------------------------- /demo/Blog/template/elem/post-list.tt: -------------------------------------------------------------------------------- 1 |
2 | [% FOREACH post IN post_list %] 3 | [% PROCESS 'post.tt' %] 4 | [% END %] 5 | 6 | -------------------------------------------------------------------------------- /demo/Blog/template/elem/post.tt: -------------------------------------------------------------------------------- 1 |

[% post.created %]

2 |
3 |

4 | 5 | [%- post.title -%] 6 | 7 |

8 |
9 |
10 | [%- post.content -%] 11 |

12 |

13 |
14 | 31 |
32 | 33 | -------------------------------------------------------------------------------- /demo/Blog/template/elem/recent-comments.tt: -------------------------------------------------------------------------------- 1 | 12 | 13 |

14 | 15 | [% IF offset > 0 %] 16 | << 17 | [% END %] 18 |     19 |     20 |     21 |     22 |     23 | [% IF last_id > 1 && comments.size == count %] 24 | 25 | Next... 26 | 27 | [% END %] 28 | 29 |

30 | 31 | -------------------------------------------------------------------------------- /demo/Blog/template/elem/recent-posts.tt: -------------------------------------------------------------------------------- 1 |
    2 | [% last_id %] 3 | [% FOREACH post IN posts -%] 4 |
  • 5 | [% post.title %] 6 |
  • 7 | [%- last_id = post.id %] 8 | [% END -%] 9 |
10 | 11 |

12 | 13 | [% IF offset > 0 %] 14 | << 15 | [% END %] 16 |     17 |     18 |     19 |     20 |     21 | [% IF last_id > 1 && posts.size == count %] 22 | 23 | Next... 24 | 25 | [% END %] 26 | 27 |

28 | 29 | -------------------------------------------------------------------------------- /demo/Blog/template/footer.tt: -------------------------------------------------------------------------------- 1 | 11 | 12 | -------------------------------------------------------------------------------- /demo/Blog/template/header.tt: -------------------------------------------------------------------------------- 1 | [% DEFAULT 2 | blog_name = 'Foo\'s blog', 3 | blog_desc = 'This is my blog'; 4 | -%] 5 | [% IF NOT pack_js; 6 | js_files = [ 7 | 'jquery.js', 8 | 'blog-jemplate.js', 9 | 'openresty.js', 10 | 'dojo.openresty.js', 11 | 'blog.js', 12 | ]; 13 | ELSE; 14 | js_files = ['jquery-dojo.js', 'blog_min.js']; 15 | END; 16 | -%] 17 | 18 | [% blog_name | html %] 19 | 20 | 21 | 22 | 23 | 24 | [%- FOREACH js_file IN js_files %] 25 | 26 | [%- END %] 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /demo/Blog/template/index.tt: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | [%- PROCESS 'header.tt' -%] 6 | 7 | 8 | 9 | 10 |
11 |
12 | 13 | 14 | [%- PROCESS 'banner.tt' %] 15 | 16 |
17 |
18 |
19 |
20 | 21 | 22 | [%- PROCESS 'sidebar.tt' %] 23 | 24 |
25 |
26 |
27 |
28 |
29 | 30 |
31 |
32 |
33 |
34 |
35 |
36 | [%- PROCESS 'footer.tt' %] 37 |
38 |
39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /demo/Blog2/README: -------------------------------------------------------------------------------- 1 | This is the source for the blog site http://blog.agentzh.org . 2 | 3 | How to setup the site: 4 | 5 | * First of all, ask agentzh for an OpenAPI account by writing to agentzh@yahoo.cn 6 | 7 | * cd into this directory and enter the following commands: 8 | 9 | $ sudo cpan Jemplate Date::Manip WWW::OpenResty 10 | $ script/init.pl -u your_account -p your_password 11 | $ vim js/blog.js # change "agentzh" to your account name 12 | $ vim Makefile # change blog_name and blog_desc to your own 13 | $ make 14 | $ firefox out/index.html & 15 | 16 | ../../bin/export-model.pl --user eeee --password $password --model Comment --server api.eeeeworks.org --out Comment.json 17 | ../../bin/export-model.pl --user eeee --password $password --model Post --server api.eeeeworks.org --out Post.json 18 | script/init.pl -u eeee -p $password -s api.eeeeworks.org 19 | ../../bin/import-model.pl --reset --no-id --user eeee --password $password --model Post --server api.eeeeworks.org Post.json 20 | ../../bin/import-model.pl --reset --no-id --user eeee --password $password --model Comment --server api.eeeeworks.org Comment.json 21 | 22 | -------------------------------------------------------------------------------- /demo/Blog2/TODO: -------------------------------------------------------------------------------- 1 | * Tags and category support. 2 | * The archives module. 3 | * true RSS/Atom support. 4 | * Full-text search within the blog (for both comments and posts). 5 | * Captcha image in the comment form. 6 | * Use custom action PostComment rather than chained POST and PUT. 7 | * Blog admin interface 8 | 9 | -------------------------------------------------------------------------------- /demo/Blog2/css/blog.css: -------------------------------------------------------------------------------- 1 | .entry-header b { 2 | color: #cc0022; 3 | } 4 | 5 | #beta-inner.pkg b { 6 | color: #cc0022; 7 | font-weight: normal; 8 | } 9 | 10 | input#searchbox { 11 | margin-top: 5px; 12 | margin-bottom: 5px; 13 | color:#369; 14 | background:#fff; 15 | width: 180px; 16 | } 17 | 18 | div#wait-message { 19 | color: red !important; 20 | background: white !important; 21 | font-size: 18px !important; 22 | float: right; 23 | position: fixed; 24 | top: 2px; 25 | right: 30px; 26 | padding: 4px; 27 | border-width: 2px; 28 | border-style: outset; 29 | border-color: white; 30 | display: block; 31 | } 32 | 33 | td.today-cell { 34 | background: #eee; 35 | } 36 | 37 | td.highlight { 38 | font-weight: bold; 39 | color:#A90A08; 40 | } 41 | 42 | input.required { 43 | background: #ffa; 44 | } 45 | 46 | ins.item-body { 47 | text-decoration: none; 48 | } 49 | 50 | a.nav-arrow { 51 | font-size: 10pt; 52 | font-weight: bold; 53 | } 54 | 55 | ins { 56 | font-style: normal; 57 | } 58 | 59 | table.paging { 60 | border: 0; 61 | width: 1%; 62 | } 63 | 64 | table.paging td { 65 | font-size: 90%; 66 | white-space: nowrap; 67 | } 68 | 69 | .prev-page { 70 | text-align: right; 71 | font-size: 12pt; 72 | color: #00c; 73 | font-weight: bold; 74 | } 75 | 76 | .next-page { 77 | text-align: left; 78 | font-size: 12pt; 79 | color: #00c; 80 | font-weight: bold; 81 | } 82 | 83 | -------------------------------------------------------------------------------- /demo/Blog2/css/styles.css: -------------------------------------------------------------------------------- 1 | /* Base */ 2 | @import url(themes/common/base-weblog.css); 3 | 4 | /* Tip Jar */ 5 | @import url(themes/common/tipjar.css); 6 | 7 | /* Portal */ 8 | 9 | 10 | /* Theme */ 11 | @import url(themes/lilia/theme-bluecrush.css); 12 | 13 | /* Custom */ 14 | body 15 | { 16 | font-family: 'Corbel', 'Cambria', 'trebuchet ms', helvetica, arial, sans-serif; 17 | font-size: 15px; 18 | color: black; 19 | } 20 | 21 | tt 22 | { 23 | font-family: 'Consolas', 'Courier New', 'FreeMono', monospace; 24 | } 25 | 26 | h1, h2, h3, h4, h5, h6 27 | { 28 | font-family: 'Cambria', 'Corbel', 'Candara', 'trebuchet ms', helvetica, arial, sans-serif; 29 | font-weight: bold; 30 | } 31 | 32 | a { color: #009; text-decoration: underline; } 33 | a:visited { color: #306 } 34 | 35 | .entry h2 { 36 | color: #930; 37 | font-size: 18px; 38 | border-bottom: 1px dotted #930; 39 | margin-bottom: 15px; 40 | font-weight: bold; 41 | } 42 | 43 | h3 { 44 | color: #000; 45 | font-size: 15px; 46 | margin-bottom: 10px; 47 | } 48 | 49 | 50 | -------------------------------------------------------------------------------- /demo/Blog2/css/themes/lilia/theme-bluecrush/4ebg.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agentzh/old-openresty/53dad17e84dc6d2a0dffddb119851c50c0ca3a8d/demo/Blog2/css/themes/lilia/theme-bluecrush/4ebg.gif -------------------------------------------------------------------------------- /demo/Blog2/css/themes/lilia/theme-bluecrush/banner-bg.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agentzh/old-openresty/53dad17e84dc6d2a0dffddb119851c50c0ca3a8d/demo/Blog2/css/themes/lilia/theme-bluecrush/banner-bg.gif -------------------------------------------------------------------------------- /demo/Blog2/css/themes/lilia/theme-bluecrush/colitem-header-bg.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agentzh/old-openresty/53dad17e84dc6d2a0dffddb119851c50c0ca3a8d/demo/Blog2/css/themes/lilia/theme-bluecrush/colitem-header-bg.gif -------------------------------------------------------------------------------- /demo/Blog2/css/themes/lilia/theme-bluecrush/column-left-bg.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agentzh/old-openresty/53dad17e84dc6d2a0dffddb119851c50c0ca3a8d/demo/Blog2/css/themes/lilia/theme-bluecrush/column-left-bg.gif -------------------------------------------------------------------------------- /demo/Blog2/css/themes/lilia/theme-bluecrush/container-bg.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agentzh/old-openresty/53dad17e84dc6d2a0dffddb119851c50c0ca3a8d/demo/Blog2/css/themes/lilia/theme-bluecrush/container-bg.gif -------------------------------------------------------------------------------- /demo/Blog2/css/themes/lilia/theme-bluecrush/li-bg.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agentzh/old-openresty/53dad17e84dc6d2a0dffddb119851c50c0ca3a8d/demo/Blog2/css/themes/lilia/theme-bluecrush/li-bg.gif -------------------------------------------------------------------------------- /demo/Blog2/css/themes/lilia/theme-bluecrush/tbg.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agentzh/old-openresty/53dad17e84dc6d2a0dffddb119851c50c0ca3a8d/demo/Blog2/css/themes/lilia/theme-bluecrush/tbg.gif -------------------------------------------------------------------------------- /demo/Blog2/css/themes/lilia/theme-bluecrush/tbgr.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agentzh/old-openresty/53dad17e84dc6d2a0dffddb119851c50c0ca3a8d/demo/Blog2/css/themes/lilia/theme-bluecrush/tbgr.gif -------------------------------------------------------------------------------- /demo/Blog2/css/themes/lilia/theme-bluecrush/thumbnailed-bg.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agentzh/old-openresty/53dad17e84dc6d2a0dffddb119851c50c0ca3a8d/demo/Blog2/css/themes/lilia/theme-bluecrush/thumbnailed-bg.gif -------------------------------------------------------------------------------- /demo/Blog2/css/themes/lilia/theme-bluecrush/tit.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agentzh/old-openresty/53dad17e84dc6d2a0dffddb119851c50c0ca3a8d/demo/Blog2/css/themes/lilia/theme-bluecrush/tit.gif -------------------------------------------------------------------------------- /demo/Blog2/css/themes/lilia/theme-bluecrush/titl.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agentzh/old-openresty/53dad17e84dc6d2a0dffddb119851c50c0ca3a8d/demo/Blog2/css/themes/lilia/theme-bluecrush/titl.gif -------------------------------------------------------------------------------- /demo/Blog2/script/reset.mk: -------------------------------------------------------------------------------- 1 | password= 2 | server= 3 | user= 4 | 5 | export: 6 | -mkdir backup 7 | -cp *.json backup 8 | ../../bin/export-model.pl --user $(user) --model Comment --server $(server) --out Comment.json 9 | ../../bin/export-model.pl --step 10 --user $(user) --model Post --server $(server) --out Post.json 10 | 11 | import: 12 | script/init.pl -u $(user) -p $(password) -s $(server) 13 | ../../bin/import-model.pl --reset --step 1 --user $(user) --password $(password) --model Post --server $(server) Post.json 14 | ../../bin/import-model.pl --reset --user $(user) --password $(password) --model Comment --server $(server) Comment.json 15 | 16 | # create or replace function to_fti(text, text) returns tsvector as $$ select setweight(to_tsvector('chinesecfg', $1), 'A') || to_tsvector('chinesecfg', $2) $$ language sql immutable; 17 | # select title, ts_headline('chinesecfg', content, q) as headline from "Post", to_tsquery('chinesecfg', 'OpenResty|Google') as q where to_fti(title, content) @@ q order by ts_rank(to_fti(title, content), q) desc; 18 | # 19 | 20 | -------------------------------------------------------------------------------- /demo/BlogAdmin/README: -------------------------------------------------------------------------------- 1 | This is the source for the blog administration site http://openresty.org/blogadmin/ 2 | 3 | How to setup the site: 4 | 5 | $ sudo cpan Jemplate Template 6 | $ make 7 | $ firefox out/index.html & 8 | 9 | Note that you need the whole OpenResty source tree to build this site. 10 | Because some of the .js files are copied over from ../../clients/js/ 11 | and somewhere else :) 12 | 13 | Note that, this BlogAdmin site is only supposed to work with the blog app under ../Blog/ 14 | -------------------------------------------------------------------------------- /demo/BlogAdmin/css/blogadmin.css: -------------------------------------------------------------------------------- 1 | div#wait-message { 2 | color: red !important; 3 | background: white !important; 4 | font-size: 18px !important; 5 | float: right; 6 | position: fixed; 7 | top: 2px; 8 | right: 30px; 9 | padding: 4px; 10 | border-width: 2px; 11 | border-style: outset; 12 | border-color: white; 13 | display: none; 14 | } 15 | 16 | 17 | -------------------------------------------------------------------------------- /demo/BlogAdmin/css/fonts.css: -------------------------------------------------------------------------------- 1 | /** 2 | * 84.5% for !IE, keywords for IE 3 | * Percents could work for IE, but for backCompat purposes, we are using keywords. 4 | * x-small is for IE < 6 and IE6 quirks mode. 5 | * 6 | */ 7 | body {font:13px arial,helvetica,clean,sans-serif;*font-size:small;*font:x-small;} 8 | table {font-size:inherit;font:100%;} 9 | 10 | /** 11 | * 99% for safari; 100% is too large 12 | */ 13 | select, input, textarea {font:99% arial,helvetica,clean,sans-serif;} 14 | 15 | /** 16 | * Bump up !IE to get to 13px equivalent 17 | */ 18 | pre, code {font:115% monospace;*font-size:100%;} 19 | 20 | /** 21 | * Default line-height based on font-size rather than "computed-value" 22 | * see: http://www.w3.org/TR/CSS21/visudet.html#line-height 23 | */ 24 | body * {line-height:1.22em;} 25 | -------------------------------------------------------------------------------- /demo/BlogAdmin/js/thirdparty/wymeditor/iframe/default/lbl-blockquote.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agentzh/old-openresty/53dad17e84dc6d2a0dffddb119851c50c0ca3a8d/demo/BlogAdmin/js/thirdparty/wymeditor/iframe/default/lbl-blockquote.png -------------------------------------------------------------------------------- /demo/BlogAdmin/js/thirdparty/wymeditor/iframe/default/lbl-h1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agentzh/old-openresty/53dad17e84dc6d2a0dffddb119851c50c0ca3a8d/demo/BlogAdmin/js/thirdparty/wymeditor/iframe/default/lbl-h1.png -------------------------------------------------------------------------------- /demo/BlogAdmin/js/thirdparty/wymeditor/iframe/default/lbl-h2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agentzh/old-openresty/53dad17e84dc6d2a0dffddb119851c50c0ca3a8d/demo/BlogAdmin/js/thirdparty/wymeditor/iframe/default/lbl-h2.png -------------------------------------------------------------------------------- /demo/BlogAdmin/js/thirdparty/wymeditor/iframe/default/lbl-h3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agentzh/old-openresty/53dad17e84dc6d2a0dffddb119851c50c0ca3a8d/demo/BlogAdmin/js/thirdparty/wymeditor/iframe/default/lbl-h3.png -------------------------------------------------------------------------------- /demo/BlogAdmin/js/thirdparty/wymeditor/iframe/default/lbl-h4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agentzh/old-openresty/53dad17e84dc6d2a0dffddb119851c50c0ca3a8d/demo/BlogAdmin/js/thirdparty/wymeditor/iframe/default/lbl-h4.png -------------------------------------------------------------------------------- /demo/BlogAdmin/js/thirdparty/wymeditor/iframe/default/lbl-h5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agentzh/old-openresty/53dad17e84dc6d2a0dffddb119851c50c0ca3a8d/demo/BlogAdmin/js/thirdparty/wymeditor/iframe/default/lbl-h5.png -------------------------------------------------------------------------------- /demo/BlogAdmin/js/thirdparty/wymeditor/iframe/default/lbl-h6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agentzh/old-openresty/53dad17e84dc6d2a0dffddb119851c50c0ca3a8d/demo/BlogAdmin/js/thirdparty/wymeditor/iframe/default/lbl-h6.png -------------------------------------------------------------------------------- /demo/BlogAdmin/js/thirdparty/wymeditor/iframe/default/lbl-p.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agentzh/old-openresty/53dad17e84dc6d2a0dffddb119851c50c0ca3a8d/demo/BlogAdmin/js/thirdparty/wymeditor/iframe/default/lbl-p.png -------------------------------------------------------------------------------- /demo/BlogAdmin/js/thirdparty/wymeditor/iframe/default/lbl-pre.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agentzh/old-openresty/53dad17e84dc6d2a0dffddb119851c50c0ca3a8d/demo/BlogAdmin/js/thirdparty/wymeditor/iframe/default/lbl-pre.png -------------------------------------------------------------------------------- /demo/BlogAdmin/js/thirdparty/wymeditor/iframe/default/wymiframe.html: -------------------------------------------------------------------------------- 1 | 2 | 19 | 20 | 21 | WYMeditor iframe 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /demo/BlogAdmin/js/thirdparty/wymeditor/lang/ca.js: -------------------------------------------------------------------------------- 1 | WYMeditor.STRINGS['ca'] = { 2 | Strong: 'Ressaltar', 3 | Emphasis: 'Emfatitzar', 4 | Superscript: 'Superindex', 5 | Subscript: 'Subindex', 6 | Ordered_List: 'Llistat ordenat', 7 | Unordered_List: 'Llistat sense ordenar', 8 | Indent: 'Indentat', 9 | Outdent: 'Sense indentar', 10 | Undo: 'Desfer', 11 | Redo: 'Refer', 12 | Link: 'Enllaçar', 13 | Unlink: 'Eliminar enllaç', 14 | Image: 'Imatge', 15 | Table: 'Taula', 16 | HTML: 'HTML', 17 | Paragraph: 'Paràgraf', 18 | Heading_1: 'Capçalera 1', 19 | Heading_2: 'Capçalera 2', 20 | Heading_3: 'Capçalera 3', 21 | Heading_4: 'Capçalera 4', 22 | Heading_5: 'Capçalera 5', 23 | Heading_6: 'Capçalera 6', 24 | Preformatted: 'Pre-formatejat', 25 | Blockquote: 'Cita', 26 | Table_Header: 'Capçalera de la taula', 27 | URL: 'URL', 28 | Title: 'Títol', 29 | Alternative_Text: 'Text alternatiu', 30 | Caption: 'Llegenda', 31 | Number_Of_Rows: 'Nombre de files', 32 | Number_Of_Cols: 'Nombre de columnes', 33 | Submit: 'Enviar', 34 | Cancel: 'Cancel·lar', 35 | Choose: 'Triar', 36 | Preview: 'Vista prèvia', 37 | Paste_From_Word: 'Pegar des de Word', 38 | Tools: 'Eines', 39 | Containers: 'Contenidors', 40 | Classes: 'Classes', 41 | Status: 'Estat', 42 | Source_Code: 'Codi font' 43 | }; 44 | 45 | -------------------------------------------------------------------------------- /demo/BlogAdmin/js/thirdparty/wymeditor/lang/de.js: -------------------------------------------------------------------------------- 1 | WYMeditor.STRINGS['de'] = { 2 | Strong: 'Fett', 3 | Emphasis: 'Kursiv', 4 | Superscript: 'Text hochstellen', 5 | Subscript: 'Text tiefstellen', 6 | Ordered_List: 'Geordnete Liste einfügen', 7 | Unordered_List: 'Ungeordnete Liste einfügen', 8 | Indent: 'Einzug erhöhen', 9 | Outdent: 'Einzug vermindern', 10 | Undo: 'Befehle rückgängig machen', 11 | Redo: 'Befehle wiederherstellen', 12 | Link: 'Hyperlink einfügen', 13 | Unlink: 'Hyperlink entfernen', 14 | Image: 'Bild einfügen', 15 | Table: 'Tabelle einfügen', 16 | HTML: 'HTML anzeigen/verstecken', 17 | Paragraph: 'Absatz', 18 | Heading_1: 'Überschrift 1', 19 | Heading_2: 'Überschrift 2', 20 | Heading_3: 'Überschrift 3', 21 | Heading_4: 'Überschrift 4', 22 | Heading_5: 'Überschrift 5', 23 | Heading_6: 'Überschrift 6', 24 | Preformatted: 'Vorformatiert', 25 | Blockquote: 'Zitat', 26 | Table_Header: 'Tabellenüberschrift', 27 | URL: 'URL', 28 | Title: 'Titel', 29 | Alternative_Text: 'Alternativer Text', 30 | Caption: 'Tabellenüberschrift', 31 | Number_Of_Rows: 'Anzahl Zeilen', 32 | Number_Of_Cols: 'Anzahl Spalten', 33 | Submit: 'Absenden', 34 | Cancel: 'Abbrechen', 35 | Choose: 'Auswählen', 36 | Preview: 'Vorschau', 37 | Paste_From_Word: 'Aus Word einfügen', 38 | Tools: 'Werkzeuge', 39 | Containers: 'Inhaltstyp', 40 | Classes: 'Klassen', 41 | Status: 'Status', 42 | Source_Code: 'Quellcode' 43 | }; 44 | 45 | -------------------------------------------------------------------------------- /demo/BlogAdmin/js/thirdparty/wymeditor/lang/en.js: -------------------------------------------------------------------------------- 1 | WYMeditor.STRINGS['en'] = { 2 | Strong: 'Strong', 3 | Emphasis: 'Emphasis', 4 | Superscript: 'Superscript', 5 | Subscript: 'Subscript', 6 | Ordered_List: 'Ordered List', 7 | Unordered_List: 'Unordered List', 8 | Indent: 'Indent', 9 | Outdent: 'Outdent', 10 | Undo: 'Undo', 11 | Redo: 'Redo', 12 | Link: 'Link', 13 | Unlink: 'Unlink', 14 | Image: 'Image', 15 | Table: 'Table', 16 | HTML: 'HTML', 17 | Paragraph: 'Paragraph', 18 | Heading_1: 'Heading 1', 19 | Heading_2: 'Heading 2', 20 | Heading_3: 'Heading 3', 21 | Heading_4: 'Heading 4', 22 | Heading_5: 'Heading 5', 23 | Heading_6: 'Heading 6', 24 | Preformatted: 'Preformatted', 25 | Blockquote: 'Blockquote', 26 | Table_Header: 'Table Header', 27 | URL: 'URL', 28 | Title: 'Title', 29 | Alternative_Text: 'Alternative text', 30 | Caption: 'Caption', 31 | Number_Of_Rows: 'Number of rows', 32 | Number_Of_Cols: 'Number of cols', 33 | Submit: 'Submit', 34 | Cancel: 'Cancel', 35 | Choose: 'Choose', 36 | Preview: 'Preview', 37 | Paste_From_Word: 'Paste from Word', 38 | Tools: 'Tools', 39 | Containers: 'Containers', 40 | Classes: 'Classes', 41 | Status: 'Status', 42 | Source_Code: 'Source code' 43 | }; 44 | 45 | -------------------------------------------------------------------------------- /demo/BlogAdmin/js/thirdparty/wymeditor/lang/es.js: -------------------------------------------------------------------------------- 1 | WYMeditor.STRINGS['es'] = { 2 | Strong: 'Resaltar', 3 | Emphasis: 'Enfatizar', 4 | Superscript: 'Superindice', 5 | Subscript: 'Subindice', 6 | Ordered_List: 'Lista ordenada', 7 | Unordered_List: 'Lista sin ordenar', 8 | Indent: 'Indentado', 9 | Outdent: 'Sin indentar', 10 | Undo: 'Deshacer', 11 | Redo: 'Rehacer', 12 | Link: 'Enlazar', 13 | Unlink: 'Eliminar enlace', 14 | Image: 'Imagen', 15 | Table: 'Tabla', 16 | HTML: 'HTML', 17 | Paragraph: 'Párrafo', 18 | Heading_1: 'Cabecera 1', 19 | Heading_2: 'Cabecera 2', 20 | Heading_3: 'Cabecera 3', 21 | Heading_4: 'Cabecera 4', 22 | Heading_5: 'Cabecera 5', 23 | Heading_6: 'Cabecera 6', 24 | Preformatted: 'Preformateado', 25 | Blockquote: 'Cita', 26 | Table_Header: 'Cabecera de la tabla', 27 | URL: 'URL', 28 | Title: 'Título', 29 | Alternative_Text: 'Texto alternativo', 30 | Caption: 'Leyenda', 31 | Number_Of_Rows: 'Número de filas', 32 | Number_Of_Cols: 'Número de columnas', 33 | Submit: 'Enviar', 34 | Cancel: 'Cancelar', 35 | Choose: 'Seleccionar', 36 | Preview: 'Vista previa', 37 | Paste_From_Word: 'Pegar desde Word', 38 | Tools: 'Herramientas', 39 | Containers: 'Contenedores', 40 | Classes: 'Clases', 41 | Status: 'Estado', 42 | Source_Code: 'Código fuente' 43 | }; 44 | 45 | -------------------------------------------------------------------------------- /demo/BlogAdmin/js/thirdparty/wymeditor/lang/fr.js: -------------------------------------------------------------------------------- 1 | WYMeditor.STRINGS['fr'] = { 2 | Strong: 'Mise en évidence', 3 | Emphasis: 'Emphase', 4 | Superscript: 'Exposant', 5 | Subscript: 'Indice', 6 | Ordered_List: 'Liste Ordonnée', 7 | Unordered_List: 'Liste Non-Ordonnée', 8 | Indent: 'Imbriqué', 9 | Outdent: 'Non-imbriqué', 10 | Undo: 'Annuler', 11 | Redo: 'Rétablir', 12 | Link: 'Lien', 13 | Unlink: 'Supprimer le Lien', 14 | Image: 'Image', 15 | Table: 'Tableau', 16 | HTML: 'HTML', 17 | Paragraph: 'Paragraphe', 18 | Heading_1: 'Titre 1', 19 | Heading_2: 'Titre 2', 20 | Heading_3: 'Titre 3', 21 | Heading_4: 'Titre 4', 22 | Heading_5: 'Titre 5', 23 | Heading_6: 'Titre 6', 24 | Preformatted: 'Pré-formatté', 25 | Blockquote: 'Citation', 26 | Table_Header: 'Cellule de titre', 27 | URL: 'URL', 28 | Title: 'Titre', 29 | Alternative_Text: 'Texte alternatif', 30 | Caption: 'Légende', 31 | Number_Of_Rows: 'Nombre de lignes', 32 | Number_Of_Cols: 'Nombre de colonnes', 33 | Submit: 'Envoyer', 34 | Cancel: 'Annuler', 35 | Choose: 'Choisir', 36 | Preview: 'Prévisualisation', 37 | Paste_From_Word: 'Copier depuis Word', 38 | Tools: 'Outils', 39 | Containers: 'Type de texte', 40 | Classes: 'Type de contenu', 41 | Status: 'Infos', 42 | Source_Code: 'Code source' 43 | }; 44 | 45 | -------------------------------------------------------------------------------- /demo/BlogAdmin/js/thirdparty/wymeditor/lang/hu.js: -------------------------------------------------------------------------------- 1 | WYMeditor.STRINGS['hu'] = { 2 | Strong: 'Félkövér', 3 | Emphasis: 'Kiemelt', 4 | Superscript: 'Felső index', 5 | Subscript: 'Alsó index', 6 | Ordered_List: 'Rendezett lista', 7 | Unordered_List: 'Rendezetlen lista', 8 | Indent: 'Bekezdés', 9 | Outdent: 'Bekezdés törlése', 10 | Undo: 'Visszavon', 11 | Redo: 'Visszaállít', 12 | Link: 'Link', 13 | Unlink: 'Link törlése', 14 | Image: 'Kép', 15 | Table: 'Tábla', 16 | HTML: 'HTML', 17 | Paragraph: 'Bekezdés', 18 | Heading_1: 'Címsor 1', 19 | Heading_2: 'Címsor 2', 20 | Heading_3: 'Címsor 3', 21 | Heading_4: 'Címsor 4', 22 | Heading_5: 'Címsor 5', 23 | Heading_6: 'Címsor 6', 24 | Preformatted: 'Előformázott', 25 | Blockquote: 'Idézet', 26 | Table_Header: 'Tábla Fejléc', 27 | URL: 'Webcím', 28 | Title: 'Megnevezés', 29 | Alternative_Text: 'Alternatív szöveg', 30 | Caption: 'Fejléc', 31 | Number_Of_Rows: 'Sorok száma', 32 | Number_Of_Cols: 'Oszlopok száma', 33 | Submit: 'Elküld', 34 | Cancel: 'Mégsem', 35 | Choose: 'Választ', 36 | Preview: 'Előnézet', 37 | Paste_From_Word: 'Másolás Word-ból', 38 | Tools: 'Eszközök', 39 | Containers: 'Tartalmak', 40 | Classes: 'Osztályok', 41 | Status: 'Állapot', 42 | Source_Code: 'Forráskód' 43 | }; 44 | 45 | -------------------------------------------------------------------------------- /demo/BlogAdmin/js/thirdparty/wymeditor/lang/it.js: -------------------------------------------------------------------------------- 1 | WYMeditor.STRINGS['it'] = { 2 | Strong: 'Grassetto', 3 | Emphasis: 'Corsetto', 4 | Superscript: 'Apice', 5 | Subscript: 'Pedice', 6 | Ordered_List: 'Lista Ordinata', 7 | Unordered_List: 'Lista Puntata', 8 | Indent: 'Indenta', 9 | Outdent: 'Caccia', 10 | Undo: 'Indietro', 11 | Redo: 'Avanti', 12 | Link: 'Inserisci Link', 13 | Unlink: 'Togli Link', 14 | Image: 'Inserisci Immagine', 15 | Table: 'Inserisci Tabella', 16 | HTML: 'HTML', 17 | Paragraph: 'Paragrafo', 18 | Heading_1: 'Heading 1', 19 | Heading_2: 'Heading 2', 20 | Heading_3: 'Heading 3', 21 | Heading_4: 'Heading 4', 22 | Heading_5: 'Heading 5', 23 | Heading_6: 'Heading 6', 24 | Preformatted: 'Preformattato', 25 | Blockquote: 'Blockquote', 26 | Table_Header: 'Header Tabella', 27 | URL: 'Indirizzo', 28 | Title: 'Titolo', 29 | Alternative_Text: 'Testo Alternativo', 30 | Caption: 'Caption', 31 | Number_Of_Rows: 'Numero di Righe', 32 | Number_Of_Cols: 'Numero di Colonne', 33 | Submit: 'Invia', 34 | Cancel: 'Cancella', 35 | Choose: 'Scegli', 36 | Preview: 'Anteprima', 37 | Paste_From_Word: 'Incolla', 38 | Tools: 'Tools', 39 | Containers: 'Contenitori', 40 | Classes: 'Classi', 41 | Status: 'Stato', 42 | Source_Code: 'Codice Sorgente' 43 | }; 44 | 45 | -------------------------------------------------------------------------------- /demo/BlogAdmin/js/thirdparty/wymeditor/lang/nl.js: -------------------------------------------------------------------------------- 1 | WYMeditor.STRINGS['nl'] = { 2 | Strong: 'Sterk benadrukken', 3 | Emphasis: 'Benadrukken', 4 | Superscript: 'Bovenschrift', 5 | Subscript: 'Onderschrift', 6 | Ordered_List: 'Geordende lijst', 7 | Unordered_List: 'Ongeordende lijst', 8 | Indent: 'Inspringen', 9 | Outdent: 'Terugspringen', 10 | Undo: 'Ongedaan maken', 11 | Redo: 'Opnieuw uitvoeren', 12 | Link: 'Linken', 13 | Unlink: 'Ontlinken', 14 | Image: 'Afbeelding', 15 | Table: 'Tabel', 16 | HTML: 'HTML', 17 | Paragraph: 'Paragraaf', 18 | Heading_1: 'Hoofding 1', 19 | Heading_2: 'Hoofding 2', 20 | Heading_3: 'Hoofding 3', 21 | Heading_4: 'Hoofding 4', 22 | Heading_5: 'Hoofding 5', 23 | Heading_6: 'Hoofding 6', 24 | Preformatted: 'Voorgeformatteerd', 25 | Blockquote: 'Aanhaling', 26 | Table_Header: 'Tabel hoofding', 27 | URL: 'URL', 28 | Title: 'Titel', 29 | Alternative_Text: 'Alternatieve tekst', 30 | Caption: 'Bijschrift', 31 | Number_Of_Rows: 'Aantal rijen', 32 | Number_Of_Cols: 'Aantal kolommen', 33 | Submit: 'Versturen', 34 | Cancel: 'Annuleren', 35 | Choose: 'Kiezen', 36 | Preview: 'Voorbeeld bekijken', 37 | Paste_From_Word: 'Plakken uit Word', 38 | Tools: 'Tools', 39 | Containers: 'Containers', 40 | Classes: 'Classes', 41 | Status: 'Status', 42 | Source_Code: 'Broncode' 43 | }; 44 | 45 | -------------------------------------------------------------------------------- /demo/BlogAdmin/js/thirdparty/wymeditor/lang/pl.js: -------------------------------------------------------------------------------- 1 | WYMeditor.STRINGS['pl'] = { 2 | Strong: 'Nacisk', 3 | Emphasis: 'Emfaza', 4 | Superscript: 'Indeks górny', 5 | Subscript: 'Indeks dolny', 6 | Ordered_List: 'Lista numerowana', 7 | Unordered_List: 'Lista wypunktowana', 8 | Indent: 'Zwiększ wcięcie', 9 | Outdent: 'Zmniejsz wcięcie', 10 | Undo: 'Cofnij', 11 | Redo: 'Ponów', 12 | Link: 'Wstaw link', 13 | Unlink: 'Usuń link', 14 | Image: 'Obraz', 15 | Table: 'Tabela', 16 | HTML: 'Źródło HTML', 17 | Paragraph: 'Akapit', 18 | Heading_1: 'Nagłówek 1', 19 | Heading_2: 'Nagłówek 2', 20 | Heading_3: 'Nagłówek 3', 21 | Heading_4: 'Nagłówek 4', 22 | Heading_5: 'Nagłówek 5', 23 | Heading_6: 'Nagłówek 6', 24 | Preformatted: 'Preformatowany', 25 | Blockquote: 'Cytat blokowy', 26 | Table_Header: 'Nagłówek tabeli', 27 | URL: 'URL', 28 | Title: 'Tytuł', 29 | Alternative_Text: 'Tekst alternatywny', 30 | Caption: 'Tytuł tabeli', 31 | Number_Of_Rows: 'Liczba wierszy', 32 | Number_Of_Cols: 'Liczba kolumn', 33 | Submit: 'Wyślij', 34 | Cancel: 'Anuluj', 35 | Choose: 'Wybierz', 36 | Preview: 'Podgląd', 37 | Paste_From_Word: 'Wklej z Worda', 38 | Tools: 'Narzędzia', 39 | Containers: 'Format', 40 | Classes: 'Styl', 41 | Status: 'Status', 42 | Source_Code: 'Kod źródłowy' 43 | }; 44 | 45 | -------------------------------------------------------------------------------- /demo/BlogAdmin/js/thirdparty/wymeditor/lang/pt.js: -------------------------------------------------------------------------------- 1 | WYMeditor.STRINGS['pt'] = { 2 | Strong: 'Negrito', 3 | Emphasis: 'Itálico', 4 | Superscript: 'Sobrescrito', 5 | Subscript: 'Subsescrito', 6 | Ordered_List: 'Lista Numerada', 7 | Unordered_List: 'Lista Marcada', 8 | Indent: 'Aumentar Indentaçã', 9 | Outdent: 'Diminuir Indentaçã', 10 | Undo: 'Desfazer', 11 | Redo: 'Restaurar', 12 | Link: 'Link', 13 | Unlink: 'Tirar link', 14 | Image: 'Imagem', 15 | Table: 'Tabela', 16 | HTML: 'HTML', 17 | Paragraph: 'Parágrafo', 18 | Heading_1: 'Título 1', 19 | Heading_2: 'Título 2', 20 | Heading_3: 'Título 3', 21 | Heading_4: 'Título 4', 22 | Heading_5: 'Título 5', 23 | Heading_6: 'Título 6', 24 | Preformatted: 'Pré-formatado', 25 | Blockquote: 'Citação', 26 | Table_Header: 'Cabeçalho Tabela', 27 | URL: 'URL', 28 | Title: 'Título', 29 | Alternative_Text: 'Texto Alterativo', 30 | Caption: 'Título Tabela', 31 | Number_Of_Rows: 'Número de Linhas', 32 | Number_Of_Cols: 'Número de Colunas', 33 | Submit: 'Enviar', 34 | Cancel: 'Cancelar', 35 | Choose: 'Escolha', 36 | Preview: 'Prever', 37 | Paste_From_Word: 'Colar do Word', 38 | Tools: 'Ferramentas', 39 | Containers: 'Containers', 40 | Classes: 'Classes', 41 | Status: 'Status', 42 | Source_Code: 'Código Fonte' 43 | }; 44 | 45 | -------------------------------------------------------------------------------- /demo/BlogAdmin/js/thirdparty/wymeditor/lang/ru.js: -------------------------------------------------------------------------------- 1 | WYMeditor.STRINGS['ru'] = { 2 | Strong: 'Жирный', 3 | Emphasis: 'Наклонный', 4 | Superscript: 'Надстрочный', 5 | Subscript: 'Подстрочный', 6 | Ordered_List: 'Нумерованый список', 7 | Unordered_List: 'Ненумерованый список', 8 | Indent: 'Увеличить отступ', 9 | Outdent: 'Уменьшить отступ', 10 | Undo: 'Отменить', 11 | Redo: 'Повторить', 12 | Link: 'Ссылка', 13 | Unlink: 'Удалить ссылку', 14 | Image: 'Изображение', 15 | Table: 'Таблица', 16 | HTML: 'Править HTML', 17 | Paragraph: 'Параграф', 18 | Heading_1: 'Заголовок 1', 19 | Heading_2: 'Заголовок 2', 20 | Heading_3: 'Заголовок 3', 21 | Heading_4: 'Заголовок 4', 22 | Heading_5: 'Заголовок 5', 23 | Heading_6: 'Заголовок 6', 24 | Preformatted: 'Preformatted', 25 | Blockquote: 'Цитата', 26 | Table_Header: 'Заголовок таблицы', 27 | URL: 'URL', 28 | Title: 'Заголовок', 29 | Alternative_Text: 'Альтернативный текст', 30 | Caption: 'Надпись', 31 | Number_Of_Rows: 'Кол-во строк', 32 | Number_Of_Cols: 'Кол-во столбцов', 33 | Submit: 'Отправить', 34 | Cancel: 'Отмена', 35 | Choose: 'Выбор', 36 | Preview: 'Просмотр', 37 | Paste_From_Word: 'Вставить из Word', 38 | Tools: 'Инструменты', 39 | Containers: 'Контейнеры', 40 | Classes: 'Классы', 41 | Status: 'Статус', 42 | Source_Code: 'Исходный код' 43 | }; 44 | 45 | -------------------------------------------------------------------------------- /demo/BlogAdmin/js/thirdparty/wymeditor/lang/sv.js: -------------------------------------------------------------------------------- 1 | WYMeditor.STRINGS['sv'] = { 2 | Strong: 'Viktigt', 3 | Emphasis: 'Betoning', 4 | Superscript: 'Upphöjt', 5 | Subscript: 'Nedsänkt', 6 | Ordered_List: 'Nummerlista', 7 | Unordered_List: 'Punktlista', 8 | Indent: 'Indrag', 9 | Outdent: 'Utdrag', 10 | Undo: 'Ångra', 11 | Redo: 'Gör om', 12 | Link: 'Länk', 13 | Unlink: 'Ta bort länk', 14 | Image: 'Bild', 15 | Table: 'Tabell', 16 | HTML: 'HTML', 17 | Paragraph: 'Paragraf', 18 | Heading_1: 'Rubrik 1', 19 | Heading_2: 'Rubrik 2', 20 | Heading_3: 'Rubrik 3', 21 | Heading_4: 'Rubrik 4', 22 | Heading_5: 'Rubrik 5', 23 | Heading_6: 'Rubrik 6', 24 | Preformatted: 'Förformaterad', 25 | Blockquote: 'Blockcitat', 26 | Table_Header: 'Tabellrubrik', 27 | URL: 'URL', 28 | Title: 'Titel', 29 | Alternative_Text: 'Alternativ text', 30 | Caption: 'Överskrift', 31 | Number_Of_Rows: 'Antal rader', 32 | Number_Of_Cols: 'Antal kolumner', 33 | Submit: 'Skicka', 34 | Cancel: 'Avbryt', 35 | Choose: 'Välj', 36 | Preview: 'Förhandsgranska', 37 | Paste_From_Word: 'Klistra in från Word', 38 | Tools: 'Verktyg', 39 | Containers: 'Formatering', 40 | Classes: 'Klasser', 41 | Status: 'Status', 42 | Source_Code: 'Källkod' 43 | }; 44 | 45 | -------------------------------------------------------------------------------- /demo/BlogAdmin/js/thirdparty/wymeditor/lang/zh_cn.js: -------------------------------------------------------------------------------- 1 | WYMeditor.STRINGS['zh_cn'] = { 2 | Strong: '加粗', 3 | Emphasis: '斜体', 4 | Superscript: '上标', 5 | Subscript: '下标', 6 | Ordered_List: '有序列表', 7 | Unordered_List: '无序列表', 8 | Indent: '增加缩进', 9 | Outdent: '减少缩进', 10 | Undo: '撤消', 11 | Redo: '重做', 12 | Link: '链接', 13 | Unlink: '取消链接', 14 | Image: '图片', 15 | Table: '表格', 16 | HTML: 'HTML源代码', 17 | Paragraph: '段落', 18 | Heading_1: '标题 1', 19 | Heading_2: '标题 2', 20 | Heading_3: '标题 3', 21 | Heading_4: '标题 4', 22 | Heading_5: '标题 5', 23 | Heading_6: '标题 6', 24 | Preformatted: '原始文本', 25 | Blockquote: '引语', 26 | Table_Header: '表头', 27 | URL: '地址', 28 | Title: '提示文字', 29 | Alternative_Text: '失效文字', 30 | Caption: '标题', 31 | Number_Of_Rows: '行数', 32 | Number_Of_Cols: '列数', 33 | Submit: '提交', 34 | Cancel: '放弃', 35 | Choose: '选择', 36 | Preview: '预览', 37 | Paste_From_Word: '从Word粘贴纯文本', 38 | Tools: '工具', 39 | Containers: '容器', 40 | Classes: '预定义样式', 41 | Status: '状态', 42 | Source_Code: '源代码', 43 | Attachment: '附件', 44 | NewParagraph: '新段落' 45 | }; 46 | 47 | -------------------------------------------------------------------------------- /demo/BlogAdmin/js/thirdparty/wymeditor/plugins/tidy/README: -------------------------------------------------------------------------------- 1 | WYMeditor : what you see is What You Mean web-based editor 2 | Copyright (c) 2008 Jean-Francois Hovinne, http://www.wymeditor.org/ 3 | Dual licensed under the MIT (MIT-license.txt) 4 | and GPL (GPL-license.txt) licenses. 5 | 6 | For further information visit: 7 | http://www.wymeditor.org/ 8 | 9 | File Name: 10 | README - HTML Tidy plugin for WYMeditor 11 | 12 | File Authors: 13 | Jean-François Hovinne (jf.hovinne a-t wymeditor dotorg) 14 | 15 | Credits: 16 | 'HTML Tidy' by Dave Ragget - http://tidy.sourceforge.net/ 17 | Icon 'wand' by Mark James - http://famfamfam.com/ 18 | 19 | WYMeditor documentation is available online at http://www.wymeditor.org/ 20 | -------------------------------------------------------------------------------- /demo/BlogAdmin/js/thirdparty/wymeditor/plugins/tidy/tidy.php: -------------------------------------------------------------------------------- 1 | 0) { 7 | 8 | // Specify configuration 9 | $config = array( 10 | 'bare' => true, 11 | 'clean' => true, 12 | 'doctype' => 'strict', 13 | 'drop-empty-paras' => true, 14 | 'drop-font-tags' => true, 15 | 'drop-proprietary-attributes' => true, 16 | 'enclose-block-text' => true, 17 | 'indent' => false, 18 | 'join-classes' => true, 19 | 'join-styles' => true, 20 | 'logical-emphasis' => true, 21 | 'output-xhtml' => true, 22 | 'show-body-only' => true, 23 | 'wrap' => 0); 24 | 25 | // Tidy 26 | $tidy = new tidy; 27 | $tidy->parseString($html, $config, 'utf8'); 28 | $tidy->cleanRepair(); 29 | 30 | // Output 31 | echo $tidy; 32 | } else { 33 | 34 | echo ('0'); 35 | } 36 | ?> 37 | -------------------------------------------------------------------------------- /demo/BlogAdmin/js/thirdparty/wymeditor/plugins/tidy/wand.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agentzh/old-openresty/53dad17e84dc6d2a0dffddb119851c50c0ca3a8d/demo/BlogAdmin/js/thirdparty/wymeditor/plugins/tidy/wand.png -------------------------------------------------------------------------------- /demo/BlogAdmin/js/thirdparty/wymeditor/skins/default/icons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agentzh/old-openresty/53dad17e84dc6d2a0dffddb119851c50c0ca3a8d/demo/BlogAdmin/js/thirdparty/wymeditor/skins/default/icons.png -------------------------------------------------------------------------------- /demo/BlogAdmin/js/thirdparty/wymeditor/skins/default/skin.js: -------------------------------------------------------------------------------- 1 | WYMeditor.SKINS['default'] = { 2 | 3 | init: function(wym) { 4 | 5 | //render following sections as panels 6 | jQuery(wym._box).find(wym._options.classesSelector) 7 | .addClass("wym_panel"); 8 | 9 | //render following sections as buttons 10 | jQuery(wym._box).find(wym._options.toolsSelector) 11 | .addClass("wym_buttons"); 12 | 13 | //render following sections as dropdown menus 14 | jQuery(wym._box).find(wym._options.containersSelector) 15 | .addClass("wym_dropdown") 16 | .find(WYMeditor.H2) 17 | .append(" >"); 18 | 19 | // auto add some margin to the main area sides if left area 20 | // or right area are not empty (if they contain sections) 21 | jQuery(wym._box).find("div.wym_area_right ul") 22 | .parents("div.wym_area_right").show() 23 | .parents(wym._options.boxSelector) 24 | .find("div.wym_area_main") 25 | .css({"margin-right": "155px"}); 26 | 27 | jQuery(wym._box).find("div.wym_area_left ul") 28 | .parents("div.wym_area_left").show() 29 | .parents(wym._options.boxSelector) 30 | .find("div.wym_area_main") 31 | .css({"margin-left": "155px"}); 32 | 33 | //make hover work under IE < 7 34 | jQuery(wym._box).find(".wym_section").hover(function(){ 35 | jQuery(this).addClass("hover"); 36 | },function(){ 37 | jQuery(this).removeClass("hover"); 38 | }); 39 | } 40 | }; 41 | -------------------------------------------------------------------------------- /demo/BlogAdmin/js/thirdparty/wymeditor/skins/minimal/skin.css: -------------------------------------------------------------------------------- 1 | .wym_skin_minimal div.wym_iframe iframe { 2 | width: 90%; 3 | height: 200px; 4 | } 5 | 6 | .wym_skin_minimal div.wym_section ul { 7 | margin: 0; 8 | } 9 | 10 | .wym_skin_minimal div.wym_section ul li { 11 | float: left; 12 | list-style-type: none; 13 | margin-right: 5px; 14 | } 15 | 16 | .wym_skin_minimal h2 { 17 | margin: 0; 18 | clear: both; 19 | } -------------------------------------------------------------------------------- /demo/BlogAdmin/js/thirdparty/wymeditor/skins/minimal/skin.js: -------------------------------------------------------------------------------- 1 | WYMeditor.SKINS['minimal'] = { 2 | //placeholder for the skin JS, if needed 3 | 4 | //init the skin 5 | //wym is the WYMeditor.editor instance 6 | init: function(wym) { 7 | //do something 8 | } 9 | }; 10 | -------------------------------------------------------------------------------- /demo/BlogAdmin/js/thirdparty/wymeditor/skins/wymeditor_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agentzh/old-openresty/53dad17e84dc6d2a0dffddb119851c50c0ca3a8d/demo/BlogAdmin/js/thirdparty/wymeditor/skins/wymeditor_icon.png -------------------------------------------------------------------------------- /demo/BlogAdmin/js/vars.js: -------------------------------------------------------------------------------- 1 | sessionCookie = 'blogadmin_session'; 2 | serverCookie = 'blogadmin_server'; 3 | userCookie = 'blogadmin_user'; 4 | 5 | -------------------------------------------------------------------------------- /demo/BlogAdmin/template/ajax/edit.tt: -------------------------------------------------------------------------------- 1 | [% DEFAULT action = 'updatePost' -%] 2 |

[% title %]

3 | 4 |

5 |

6 | 7 | 8 |
9 |
10 | 11 |
12 | 13 | 14 |
15 | Edit content in HTML 16 | 17 |
18 | 19 |
20 | 21 |

22 |

Return to Post list

23 | 24 | -------------------------------------------------------------------------------- /demo/BlogAdmin/template/ajax/posts.tt: -------------------------------------------------------------------------------- 1 |

Post list

2 | 3 |

Create a new post

4 |
    5 | [% last_id %] 6 | [% FOREACH post IN posts -%] 7 |
  • 8 | [% post.title %]     Delete 9 |
  • 10 | [%- last_id = post.id %] 11 | [% END -%] 12 |
13 | 14 |

15 | 16 | [% IF offset > 0 %] 17 | Previous 18 | [% END %] 19 |     20 |     21 |     22 |     23 |     24 | [% IF last_id > 1 && posts.size == count %] 25 | 26 | Next 27 | 28 | [% END %] 29 |

30 | 31 | -------------------------------------------------------------------------------- /demo/BlogAdmin/template/footer.tt: -------------------------------------------------------------------------------- 1 |
2 |

3 | This site can be downloaded from here (.tar.gz) and its Subversion repository has anonymous access to all. 4 |

5 | 6 |
7 | 13 | 14 | -------------------------------------------------------------------------------- /demo/BlogAdmin/template/index.tt: -------------------------------------------------------------------------------- 1 | [%- IF ! pack_js; 2 | js_files = [ 3 | 'openresty.js', 4 | 'vars.js', 5 | 'jquery.js', 6 | 'jquery.cookie.pack.js', 7 | 'dojo.openresty.js', 8 | 'wymeditor/jquery.wymeditor.pack.js', 9 | 'blogadmin.js', 10 | 'blogadmin-jemplate.js', 11 | ]; 12 | ELSE; 13 | js_files = [ 14 | 'jquery-min.js', 15 | 'login-min.js' 16 | ]; 17 | END; 18 | -%] 19 | 21 | 22 | 23 | Blog Admin 24 | 25 | 26 | 27 | 28 | [%- FOR file IN js_files %] 29 | 30 | [%- END -%] 31 | 32 | 33 | 34 | 35 |
36 | 37 |   Loading...  38 |
39 | 40 |

41 |

Logout

42 |
43 |
44 |
45 | [%- PROCESS 'footer.tt' %] 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /demo/Click4honor/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | -cp ../../clients/js/openresty.js . 3 | -cp ../../clients/js/JSON.js . 4 | -cp ../Blog/js/thirdparty/jquery.js . 5 | 6 | -------------------------------------------------------------------------------- /demo/Onccf/README: -------------------------------------------------------------------------------- 1 | This is the source code for the site http://www.onccf.com . 2 | 3 | For now, a temporary instance of this site is running at 4 | 5 | http://agentzh.org/misc/onccf/out/#menu/home 6 | 7 | but it will soon be moved to the domain www.onccf.com when it's ready. 8 | 9 | To generate this site, you need a complete OpenResty source tree, perl, 10 | and the Jemplate module on CPAN. Then you can issue the following command: 11 | 12 | $ make 13 | 14 | The resulting site will be in the out/ directory ready for deployment :) 15 | 16 | There's also a small test suite for the JavaScript file js/pod2html.js. 17 | To run this test suite, simply enter the command 18 | 19 | $ prove -r t 20 | 21 | Note that you need perl and several other CPAN modules like Test::Base, 22 | JavaScript::SpiderMonkey, and JSON::XS. 23 | 24 | -------------------------------------------------------------------------------- /demo/Onccf/css/layout.css: -------------------------------------------------------------------------------- 1 | #pageName{display:block;width:420px;_width:395px;margin:0 0 30px 25px} 2 | #zA,#zB{float:left;width:415px;clear:left;margin-left:25px;display:inline} 3 | #zB,#zC{_height:1px;padding-top:20px} 4 | #zC{margin-left:40px} 5 | #zC,{float:right;width:175px;margin-left:0} 6 | .modWrap{padding-right:2px;_padding-right:0} 7 | #zC{margin-right:-2px;_margin-right:0} 8 | 9 | #zB, 10 | #zC { 11 | background-image: url(../bar.gif); 12 | background-repeat: repeat-x; 13 | } 14 | 15 | /* H3 Paragraph Title */ 16 | 17 | #body h3 { 18 | font-family: Verdana, sans-serif; 19 | font-size: 14px; 20 | font-weight: bold; 21 | color: #666666; 22 | } 23 | 24 | -------------------------------------------------------------------------------- /demo/Onccf/css/onccf.css: -------------------------------------------------------------------------------- 1 | #login-panel { 2 | width: 200px; 3 | padding-left: 3em; 4 | } 5 | 6 | p#login-error { 7 | color: red; 8 | font-weight: bold; 9 | padding-left: 3em; 10 | } 11 | 12 | div.wait-message { 13 | color: red !important; 14 | background: white !important; 15 | font-size: 18px !important; 16 | float: left; 17 | position: fixed; 18 | top: 20px; 19 | right: 30px; 20 | padding: 4px; 21 | border-width: 0; 22 | display: none; 23 | } 24 | 25 | dt { 26 | font-weight: bold; 27 | } 28 | 29 | pre { 30 | margin-bottom: 1em; 31 | } 32 | 33 | .page-content { 34 | font-size: 13px !important; 35 | } 36 | 37 | ul.submenu { 38 | display: block; 39 | } 40 | 41 | span.submenu-text { 42 | font-size: 17px !important; 43 | padding-left: 1.5em; 44 | } 45 | 46 | div#doc { 47 | text-align: left; 48 | } 49 | 50 | #zC { 51 | /* padding-left: 1em; */ 52 | /* margin-left: 10em; */ 53 | margin-right: 0px !important; 54 | floating: right; 55 | margin-left: 3px !important; 56 | /* padding-left: 10em; */ 57 | 58 | width:175px; 59 | } 60 | 61 | #contact-us { 62 | padding-left: 1em; 63 | } 64 | 65 | #zWrap { 66 | padding-right: 0; 67 | margin-right: 0; 68 | } 69 | 70 | #page-content { 71 | padding-right: 1em; 72 | } 73 | 74 | #bd { 75 | width: 625px; 76 | } 77 | 78 | /* 79 | #zC,{float:right;width:175px;margin-left:50px} 80 | #zC{margin-left:50px} 81 | #zC{margin-right:-2px;_margin-right:0} 82 | */ 83 | 84 | 85 | -------------------------------------------------------------------------------- /demo/Onccf/image/background.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agentzh/old-openresty/53dad17e84dc6d2a0dffddb119851c50c0ca3a8d/demo/Onccf/image/background.gif -------------------------------------------------------------------------------- /demo/Onccf/image/bar.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agentzh/old-openresty/53dad17e84dc6d2a0dffddb119851c50c0ca3a8d/demo/Onccf/image/bar.gif -------------------------------------------------------------------------------- /demo/Onccf/image/gate.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agentzh/old-openresty/53dad17e84dc6d2a0dffddb119851c50c0ca3a8d/demo/Onccf/image/gate.jpg -------------------------------------------------------------------------------- /demo/Onccf/image/hd.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agentzh/old-openresty/53dad17e84dc6d2a0dffddb119851c50c0ca3a8d/demo/Onccf/image/hd.gif -------------------------------------------------------------------------------- /demo/Onccf/image/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agentzh/old-openresty/53dad17e84dc6d2a0dffddb119851c50c0ca3a8d/demo/Onccf/image/logo.png -------------------------------------------------------------------------------- /demo/Onccf/script/reset.mk: -------------------------------------------------------------------------------- 1 | password= 2 | server= 3 | user= 4 | 5 | export: 6 | -mkdir backup 7 | -cp *.json backup 8 | ../../bin/export-model.pl --user $(user) --model Menu --server $(server) --out Menu.json --password $(password) 9 | 10 | import: 11 | script/init.pl -u $(user) -p $(password) -s $(server) 12 | ../../bin/import-model.pl --reset --step 1 --user $(user) --password $(password) --model Menu --server $(server) Menu.json 13 | 14 | # create or replace function to_fti(text, text) returns tsvector as $$ select setweight(to_tsvector('chinesecfg', $1), 'A') || to_tsvector('chinesecfg', $2) $$ language sql immutable; 15 | # select title, ts_headline('chinesecfg', content, q) as headline from "Post", to_tsquery('chinesecfg', 'OpenResty|Google') as q where to_fti(title, content) @@ q order by ts_rank(to_fti(title, content), q) desc; 16 | # 17 | 18 | -------------------------------------------------------------------------------- /demo/Onccf/template/ajax/login.tt: -------------------------------------------------------------------------------- 1 |

Authorized access is required for viewing this page.

2 |

Please sign in first.

3 | 4 |
5 |

6 | 7 |
8 |
9 |

10 |
11 | 12 | 13 |

14 |

15 |
16 | 17 |

18 |

19 | 20 |

21 |
22 |
23 | 24 | -------------------------------------------------------------------------------- /demo/Onccf/template/ajax/menu.tt: -------------------------------------------------------------------------------- 1 | [% FOREACH menu = menu_list %] 2 |
  • 3 | 4 | [% menu.label %] 5 | 6 | 8 |
  • 9 | [% END %] 10 | 11 | -------------------------------------------------------------------------------- /demo/Onccf/template/ajax/submenu.tt: -------------------------------------------------------------------------------- 1 | [% submenu_base = submenu.name.replace('^[^.]+\.', '') -%] 2 | 3 | 8 | 9 | -------------------------------------------------------------------------------- /demo/RestyCheck/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | -cp ../../clients/js/openresty.js . 3 | -cp ../../clients/js/JSON.js . 4 | -cp ../Blog/js/thirdparty/jquery.js . 5 | 6 | upload: all force 7 | ./upload 8 | 9 | force: 10 | 11 | -------------------------------------------------------------------------------- /demo/RestyCheck/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | RestyCheck 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |

    OpenResty Quick Health-Checking Page

    13 |
    14 | 15 | 16 |
    17 | 18 | 19 | 20 | 21 | 22 | 23 |
    StatusElapsedTypeSizeAccountLink
    24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /demo/RestyCheck/restycheck.css: -------------------------------------------------------------------------------- 1 | .error { 2 | color: red; 3 | font-weight: bold; 4 | } 5 | 6 | .success { 7 | color: green; 8 | font-weight: bold; 9 | } 10 | 11 | body { 12 | font: 1.2em/1.8em consolas, verdana, arial, sans-serif; 13 | background-color: #FFF; 14 | color: black; 15 | } 16 | 17 | table { 18 | table-layout:auto; 19 | } 20 | 21 | td { 22 | overflow: auto; 23 | /* word-break: break-all; */ 24 | word-wrap: break-word; 25 | white-space: normal; 26 | border: 2px solid #ccc; 27 | /* width:33%; */ 28 | vertical-align: top; 29 | padding: 0.6em; 30 | } 31 | 32 | -------------------------------------------------------------------------------- /demo/Springbot/README: -------------------------------------------------------------------------------- 1 | INSTALLATION: 2 | 3 | sudo cpan Bot::BasicBot File::Slurp DateTime DateTime::Format::Pg DateTime::Format::Duration 4 | 5 | Basic commands: 6 | 7 | springbot: baidu keyword 8 | employee keyword 9 | 10 | -------------------------------------------------------------------------------- /demo/Springbot/springbot: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | 3 | use strict; 4 | use warnings; 5 | 6 | use FindBin; 7 | use lib "$FindBin::Bin"; 8 | use Getopt::Long; 9 | use SpringBot; 10 | 11 | my $nick = 'chunbot'; 12 | my $channel = '#eeee'; 13 | my $charset = 'gbk'; 14 | my $server = '10.62.164.72'; 15 | 16 | my ($account, $password); 17 | 18 | GetOptions( 19 | 'nick=s' => \$nick, 20 | 'channel=s' => \$channel, 21 | 'charset=s' => \$charset, 22 | 'server=s' => \$server, 23 | 'account=s' => \$account, 24 | 'password=s' => \$password, 25 | ) or die "Usage: springbot --nick --channel --charset --server --account --password \n"; 26 | 27 | $channel = "#$channel" unless $channel =~ /^\#/; 28 | 29 | $account || die "No --account specified.\n"; 30 | $password || die "No --password specified.\n"; 31 | 32 | sub init { 33 | eval { 34 | my $bot = SpringBot->new( 35 | server => $server, 36 | #port => $port, 37 | channels => [$channel], 38 | nick => $nick, 39 | alt_nicks => [$nick, $nick.'_', $nick . '__'], 40 | username => "bot", 41 | name => "SpringBot powered by OpenResty", 42 | charset => $charset, 43 | resty_account => $account, 44 | resty_password => $password, 45 | ); 46 | $bot->run(); 47 | }; 48 | if ($@) { warn $@; init(); } 49 | } 50 | 51 | init(); 52 | 53 | # vim: ts=4 sw=4 expandtab 54 | 55 | -------------------------------------------------------------------------------- /demo/Springbot/staff/Makefile: -------------------------------------------------------------------------------- 1 | .PRECIOUS: staff.txt 2 | 3 | all: staff.csv 4 | 5 | %.csv: %.txt 6 | ./txt2csv.pl $< > $@ 7 | 8 | staff.txt: rolldata.sql 9 | ./sql2txt.pl $< > $@ 10 | 11 | #%.txt: %.html 12 | #./html2txt.pl $< > $@ 13 | 14 | -------------------------------------------------------------------------------- /demo/Springbot/staff/html2txt.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | 3 | use strict; 4 | use warnings; 5 | use Encode qw(from_to); 6 | 7 | my $html = do { local $/; <> }; 8 | from_to($html, 'gbk', 'utf8'); 9 | $html =~ s/\ / /gs; 10 | $html =~ s/\<//gs; 12 | $html =~ s/\&/\&/gs; 13 | $html =~ s{\s+}{ }gs; 14 | $html =~ s{}{|}gsi; 15 | $html =~ s{}{\n}sgi; 16 | $html =~ s{]+>}{}sg; 17 | $html =~ s{}{}sg; 18 | $html =~ s/ +//g; 19 | print $html; 20 | 21 | -------------------------------------------------------------------------------- /demo/Springbot/staff/sql2txt.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | 3 | use strict; 4 | use warnings; 5 | 6 | use encoding 'utf8'; 7 | use JSON::Syck qw(Dump); 8 | use Encode qw(decode encode); 9 | use Smart::Comments; 10 | 11 | print "姓名|工号|部门|邮箱|分机号|手机|雅虎通|职位|性别|工作地|序号|\n"; 12 | while (<>) { 13 | if (s/^INSERT INTO `rolldata` VALUES //) { 14 | #$_ = dtf8', $_); 15 | #warn "Found!"; 16 | my @rows = split /\),\(/, $_; 17 | #warn scalar(@rows); 18 | $rows[0] =~ s/^\(//; 19 | $rows[-1] =~ s/\)$//; 20 | for my $row (@rows) { 21 | my @vals = split /','/, $row; 22 | $vals[0] =~ s/^'//; 23 | $vals[-1] =~ s/'$//; 24 | #print "<<<< $row >>>>\n"; 25 | #warn Dump(\@vals), "\n"; 26 | my ($email, $name, $emp_id, $depart, $pos, $sex, $place) = @vals; 27 | my $yid = $vals[14]; 28 | my $phone = $vals[15]; 29 | my $cell= $vals[16]; 30 | $pos =~ s/高级|资深|首席//g; 31 | $pos = '' if $pos eq '总监'; 32 | my $order = 0; 33 | if ($depart =~ /雅虎/) { 34 | $order++; 35 | if ($depart =~ /搜索/) { 36 | $order++; 37 | } 38 | } 39 | if ($name =~ /张皛珏/) { 40 | $order = 2; 41 | } 42 | print "$name|$emp_id|$depart|$email|$phone|$cell|$yid|$pos|$sex|$place|$order\n"; 43 | } 44 | } 45 | } 46 | 47 | -------------------------------------------------------------------------------- /demo/Springbot/staff/txt2csv.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | 3 | use strict; 4 | use warnings; 5 | 6 | use Text::CSV; 7 | use Encode qw(encode decode); 8 | 9 | my %PinYin; 10 | my $pinyin_file = 'pinyin.txt'; 11 | open my $fh, $pinyin_file or 12 | die "Can't open $pinyin_file for reading: $!\n"; 13 | while (<$fh>) { 14 | my ($han, $pinyin) = split / /, $_; 15 | $pinyin =~ s/\W//g; 16 | $han = decode('utf8', $han); 17 | next if $PinYin{$han}; 18 | $PinYin{$han} = $pinyin; 19 | } 20 | close $fh; 21 | 22 | sub to_pinyin { 23 | my $s = shift; 24 | $s =~ s/^\s+|\s+$//g; 25 | $s = decode('utf8', $s); 26 | if ($s !~ /\p{Han}/) { 27 | return $s; 28 | } 29 | my $o; 30 | for my $h (split //, $s) { 31 | #die $h; 32 | $o .= $PinYin{$h} || ''; 33 | } 34 | $o; 35 | } 36 | 37 | my $csv = Text::CSV->new({binary => 1}); 38 | while (<>) { 39 | s/\s*\|\s*$/\n/g; 40 | my @cols = split /\|/; 41 | my $count = grep { $_ } @cols; 42 | next if !$cols[0] or !$cols[1] or $count < 4; 43 | my $name = $cols[0]; 44 | my $pinyin = to_pinyin($name); 45 | $pinyin =~ s/zhangpojue/zhangxiaojue/; 46 | unshift @cols, $pinyin; 47 | print join(",", @cols); 48 | } 49 | 50 | -------------------------------------------------------------------------------- /demo/YisouComments/loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agentzh/old-openresty/53dad17e84dc6d2a0dffddb119851c50c0ca3a8d/demo/YisouComments/loading.gif -------------------------------------------------------------------------------- /demo/YisouComments/style3.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agentzh/old-openresty/53dad17e84dc6d2a0dffddb119851c50c0ca3a8d/demo/YisouComments/style3.css -------------------------------------------------------------------------------- /etc/openresty.conf: -------------------------------------------------------------------------------- 1 | # Please edit etc/site_openresty.conf rather than etc/openresty.conf 2 | # etc/openresty.conf only serves as a fallback. 3 | 4 | [frontend] 5 | log=0 6 | debug=1 7 | bulk_insert_limit=40 8 | row_limit=200 9 | column_limit=40 10 | model_limit=40 11 | post_len_limit=100000 12 | test_mode=1 13 | stats_log_dir= 14 | # Account list (separated by spaces) that have access to the Unsafe API : 15 | unsafe= 16 | # Account list (separated by spaces) filtered by OpenResty::Filter::QP : 17 | filtered= 18 | # whether compress the HTTP response content using gzip : 19 | use_gzip=0 20 | handlers=Model View Feed Action Role Unsafe Login Captcha Version LastResponse 21 | # list of accounts (spaces separated) that are allowed to forward HTTP 22 | # requests to other sites in an Action object: 23 | allow_forwarding= 24 | 25 | [backend] 26 | recording=0 27 | # You should change the line below to type=Pg or type=PgFarm 28 | type=PgMocked 29 | host=localhost 30 | user=agentzh 31 | password=agentzh 32 | database=test 33 | 34 | [cache] 35 | type=filecache 36 | servers= 37 | 38 | [test_suite] 39 | use_http=0 40 | server=tester:password@localhost 41 | server2=tester2:password2@localhost 42 | # whether test the Unsafe API 43 | test_unsafe=0 44 | 45 | -------------------------------------------------------------------------------- /filter: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | egrep -v ' t::|WWW::OpenAPI|::BEGIN|Test::|CGI::Cookie|CGI::Util|Spiffy' 4 | 5 | -------------------------------------------------------------------------------- /haskell/TODO: -------------------------------------------------------------------------------- 1 | * prefix +/-/not 2 | * subselect statements as in 3 | select anchor from recommend where pid in ( 4 | select id from restaurant where id in ( 5 | select pid from categorie where anchor like '%川菜%' 6 | ) 7 | ) group by anchor order by sum(number) desc; 8 | 9 | -------------------------------------------------------------------------------- /haskell/bin/rand-sql.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | 3 | use strict; 4 | use warnings; 5 | use Parse::RandGen::Regexp; 6 | 7 | my $list_len = 10; 8 | my $cmp_a = 10; 9 | my $cmp_b = 10; 10 | my $symbol = qr/[A-Za-z]\w*/; 11 | my $ident = qr/"$symbol"|\$$symbol|\$foo/; 12 | my $ident_list = qr/$ident(\s*,\s*$ident){$list_len,}/; 13 | my $int = qr/[-+]?\d+/; 14 | my $float = qr/[-+]?(\d+\.(\d+)?|\.\d+)/; 15 | my $number = qr/$int|$float/; 16 | my $atom = qr/$number|$ident/; 17 | my $rel_op = qr/>|>=|<|<=|!=|<>| like /; 18 | my $cmp = qr/$atom\s*$rel_op\s*$atom/; 19 | my $logic_op = qr/and|or/; 20 | my $logic_exp = qr/$cmp\s+$logic_op\s+$cmp/; 21 | my $cond = qr/$logic_exp(\s+$logic_op\s+$logic_exp){$cmp_a,$cmp_b}/; 22 | my $gen = Parse::RandGen::Regexp->new(qr/select $ident_list from $ident_list where $cond/); 23 | print $gen->pick; 24 | 25 | -------------------------------------------------------------------------------- /haskell/src/OpenResty.hs: -------------------------------------------------------------------------------- 1 | {-# OPTIONS_GHC -XOverloadedStrings -funbox-strict-fields #-} 2 | module Main where 3 | 4 | import Network.FastCGI 5 | import Control.Exception 6 | 7 | import System.IO 8 | import Database.HSQL 9 | import Database.HSQL.PostgreSQL (connect) 10 | import Text.JSON 11 | import qualified OpenResty.Request as Req 12 | import qualified OpenResty.Response as Res 13 | import Debug.Trace (trace) 14 | import Data.Dynamic 15 | import Control.Monad.Trans 16 | import qualified Data.ByteString.Char8 as B 17 | 18 | main :: IO () 19 | main = do 20 | catchDyn initServer processInitError 21 | 22 | initServer :: IO () 23 | initServer = do 24 | cnn <- (connect "localhost" "test" "agentzh" "agentzh") 25 | runServer cnn 26 | 27 | runServer :: Connection -> IO () 28 | runServer = runFastCGI . handleErrors . processRequest 29 | 30 | processRequest :: Connection -> CGI CGIResult 31 | processRequest cnn = do 32 | catchCGI (Req.parseCGIEnv >>= output . (++"\n") . encode) handler 33 | where handler :: Exception -> CGI CGIResult 34 | handler error@(DynException dyn) = Res.emitError (trace ("Exception: " ++ e) e) 35 | where e = case fromDynamic dyn of 36 | Just v -> show (v :: Req.RestyError) 37 | Nothing -> show error 38 | handler v = output $ show v ++ "\n" 39 | --processRequest cnn = output $ trace "Showing hi" (show "hi") 40 | 41 | processInitError :: SqlError -> IO () 42 | processInitError = runFastCGI . Res.emitError . show 43 | 44 | -------------------------------------------------------------------------------- /haskell/src/OpenResty/Response.hs: -------------------------------------------------------------------------------- 1 | module OpenResty.Response ( 2 | emitError 3 | ) where 4 | 5 | import Text.JSON 6 | import Network.CGI 7 | 8 | emitError :: String -> CGI CGIResult 9 | emitError msg = output $ 10 | "{\"success\":false,\"error\":" ++ 11 | (encode msg) ++ "}\n" 12 | 13 | -------------------------------------------------------------------------------- /haskell/src/RestyScript/Emitter/RenameVar.hs: -------------------------------------------------------------------------------- 1 | module RestyScript.Emitter.RenameVar where 2 | 3 | import Text.ParserCombinators.Parsec.Pos ( 4 | SourcePos, incSourceColumn, 5 | updatePosChar, setSourceLine, setSourceColumn) 6 | import RestyScript.AST 7 | 8 | findVar :: String -> RSVal -> [SourcePos] 9 | findVar var node = 10 | case node of 11 | Variable pos name | name == var 12 | -> [pos] 13 | otherwise -> [] 14 | 15 | rename :: String -> SourcePos -> [SourcePos] -> Int -> String -> String 16 | rename src@(c:cs) pos varPos@(p:ps) varLen newVar 17 | | pos == p = newVar ++ 18 | rename (drop varLen src) (incSourceColumn pos varLen) ps varLen newVar 19 | | otherwise = c : rename cs (updatePosChar pos c) varPos varLen newVar 20 | rename [] _ _ _ _ = "" 21 | rename src _ [] _ _ = src 22 | 23 | emit :: RSVal -> String -> String -> String -> String 24 | emit ast input oldVar newVar = 25 | let varPos = traverse (findVar oldVar) (++) ast 26 | in if null varPos 27 | then input 28 | else rename input (newPos (head varPos) 1 1) varPos (length oldVar) newVar 29 | where newPos pos ln col = setSourceLine (setSourceColumn pos col) ln 30 | 31 | -------------------------------------------------------------------------------- /haskell/src/RestyScript/Util.hs: -------------------------------------------------------------------------------- 1 | module RestyScript.Util ( 2 | quoteLiteral, 3 | quoteIdent 4 | ) where 5 | 6 | escapes :: [(Char, String)] 7 | escapes = zipWith ch "\b\n\f\r\t" "bnfrt" 8 | where ch a b = (a, '\\':[b]) 9 | 10 | quote :: Char -> String -> String 11 | quote sep s = [sep] ++ quoteChars s ++ [sep] 12 | where quoteChars (x:xs) = 13 | if x == sep || x == '\\' 14 | then x : x : quoteChars xs 15 | else case lookup x escapes of 16 | Just r -> r ++ quoteChars xs 17 | Nothing -> x : quoteChars xs 18 | quoteChars [] = "" 19 | 20 | quoteLiteral :: String -> String 21 | quoteLiteral = quote '\'' 22 | 23 | quoteIdent :: String -> String 24 | quoteIdent = quote '"' 25 | 26 | -------------------------------------------------------------------------------- /haskell/t/action/emit-stats.t: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | # vi:filetype= 3 | 4 | use strict; 5 | use warnings; 6 | 7 | use IPC::Run3; 8 | use Test::Base; 9 | #use Test::LongString; 10 | 11 | plan tests => 2 * blocks(); 12 | 13 | run { 14 | my $block = shift; 15 | my $desc = $block->description; 16 | my ($stdout, $stderr); 17 | my $stdin = $block->in; 18 | run3 [qw< bin/restyscript action stats >], \$stdin, \$stdout, \$stderr; 19 | is $? >> 8, 0, "compiler returns 0 - $desc"; 20 | warn $stderr if $stderr; 21 | my $out = $block->out; 22 | is $stdout, $out, "Stat output ok - $desc"; 23 | }; 24 | 25 | __DATA__ 26 | 27 | === TEST 1: basic 28 | --- in 29 | update Comment set col=col+1 where date_part('day', created) > 3 and 2<3; 30 | delete from Post where foo(created) = 2; 31 | POST '/=/model/Post/~/~' { "foo": "bah" } 32 | --- out 33 | {"modelList":["Comment","Post"],"funcList":["date_part","foo"],"selectedMax":0,"joinedMax":0,"comparedCount":3,"queryCount":0} 34 | 35 | -------------------------------------------------------------------------------- /inc/Module/Install/AutoInstall.pm: -------------------------------------------------------------------------------- 1 | #line 1 2 | package Module::Install::AutoInstall; 3 | 4 | use strict; 5 | use Module::Install::Base (); 6 | 7 | use vars qw{$VERSION @ISA $ISCORE}; 8 | BEGIN { 9 | $VERSION = '0.91'; 10 | @ISA = 'Module::Install::Base'; 11 | $ISCORE = 1; 12 | } 13 | 14 | sub AutoInstall { $_[0] } 15 | 16 | sub run { 17 | my $self = shift; 18 | $self->auto_install_now(@_); 19 | } 20 | 21 | sub write { 22 | my $self = shift; 23 | $self->auto_install(@_); 24 | } 25 | 26 | sub auto_install { 27 | my $self = shift; 28 | return if $self->{done}++; 29 | 30 | # Flatten array of arrays into a single array 31 | my @core = map @$_, map @$_, grep ref, 32 | $self->build_requires, $self->requires; 33 | 34 | my @config = @_; 35 | 36 | # We'll need Module::AutoInstall 37 | $self->include('Module::AutoInstall'); 38 | require Module::AutoInstall; 39 | 40 | Module::AutoInstall->import( 41 | (@config ? (-config => \@config) : ()), 42 | (@core ? (-core => \@core) : ()), 43 | $self->features, 44 | ); 45 | 46 | $self->makemaker_args( Module::AutoInstall::_make_args() ); 47 | 48 | my $class = ref($self); 49 | $self->postamble( 50 | "# --- $class section:\n" . 51 | Module::AutoInstall::postamble() 52 | ); 53 | } 54 | 55 | sub auto_install_now { 56 | my $self = shift; 57 | $self->auto_install(@_); 58 | Module::AutoInstall::do_install(); 59 | } 60 | 61 | 1; 62 | -------------------------------------------------------------------------------- /inc/Module/Install/Base.pm: -------------------------------------------------------------------------------- 1 | #line 1 2 | package Module::Install::Base; 3 | 4 | use strict 'vars'; 5 | use vars qw{$VERSION}; 6 | BEGIN { 7 | $VERSION = '0.91'; 8 | } 9 | 10 | # Suspend handler for "redefined" warnings 11 | BEGIN { 12 | my $w = $SIG{__WARN__}; 13 | $SIG{__WARN__} = sub { $w }; 14 | } 15 | 16 | #line 42 17 | 18 | sub new { 19 | my $class = shift; 20 | unless ( defined &{"${class}::call"} ) { 21 | *{"${class}::call"} = sub { shift->_top->call(@_) }; 22 | } 23 | unless ( defined &{"${class}::load"} ) { 24 | *{"${class}::load"} = sub { shift->_top->load(@_) }; 25 | } 26 | bless { @_ }, $class; 27 | } 28 | 29 | #line 61 30 | 31 | sub AUTOLOAD { 32 | local $@; 33 | my $func = eval { shift->_top->autoload } or return; 34 | goto &$func; 35 | } 36 | 37 | #line 75 38 | 39 | sub _top { 40 | $_[0]->{_top}; 41 | } 42 | 43 | #line 90 44 | 45 | sub admin { 46 | $_[0]->_top->{admin} 47 | or 48 | Module::Install::Base::FakeAdmin->new; 49 | } 50 | 51 | #line 106 52 | 53 | sub is_admin { 54 | $_[0]->admin->VERSION; 55 | } 56 | 57 | sub DESTROY {} 58 | 59 | package Module::Install::Base::FakeAdmin; 60 | 61 | my $fake; 62 | 63 | sub new { 64 | $fake ||= bless(\@_, $_[0]); 65 | } 66 | 67 | sub AUTOLOAD {} 68 | 69 | sub DESTROY {} 70 | 71 | # Restore warning handler 72 | BEGIN { 73 | $SIG{__WARN__} = $SIG{__WARN__}->(); 74 | } 75 | 76 | 1; 77 | 78 | #line 154 79 | -------------------------------------------------------------------------------- /inc/Module/Install/Include.pm: -------------------------------------------------------------------------------- 1 | #line 1 2 | package Module::Install::Include; 3 | 4 | use strict; 5 | use Module::Install::Base (); 6 | 7 | use vars qw{$VERSION @ISA $ISCORE}; 8 | BEGIN { 9 | $VERSION = '0.91'; 10 | @ISA = 'Module::Install::Base'; 11 | $ISCORE = 1; 12 | } 13 | 14 | sub include { 15 | shift()->admin->include(@_); 16 | } 17 | 18 | sub include_deps { 19 | shift()->admin->include_deps(@_); 20 | } 21 | 22 | sub auto_include { 23 | shift()->admin->auto_include(@_); 24 | } 25 | 26 | sub auto_include_deps { 27 | shift()->admin->auto_include_deps(@_); 28 | } 29 | 30 | sub auto_include_dependent_dists { 31 | shift()->admin->auto_include_dependent_dists(@_); 32 | } 33 | 34 | 1; 35 | -------------------------------------------------------------------------------- /inc/Module/Install/Scripts.pm: -------------------------------------------------------------------------------- 1 | #line 1 2 | package Module::Install::Scripts; 3 | 4 | use strict 'vars'; 5 | use Module::Install::Base (); 6 | 7 | use vars qw{$VERSION @ISA $ISCORE}; 8 | BEGIN { 9 | $VERSION = '0.91'; 10 | @ISA = 'Module::Install::Base'; 11 | $ISCORE = 1; 12 | } 13 | 14 | sub install_script { 15 | my $self = shift; 16 | my $args = $self->makemaker_args; 17 | my $exe = $args->{EXE_FILES} ||= []; 18 | foreach ( @_ ) { 19 | if ( -f $_ ) { 20 | push @$exe, $_; 21 | } elsif ( -d 'script' and -f "script/$_" ) { 22 | push @$exe, "script/$_"; 23 | } else { 24 | die("Cannot find script '$_'"); 25 | } 26 | } 27 | } 28 | 29 | 1; 30 | -------------------------------------------------------------------------------- /inc/Module/Install/TestBase.pm: -------------------------------------------------------------------------------- 1 | #line 1 2 | package Module::Install::TestBase; 3 | use strict; 4 | use warnings; 5 | 6 | use Module::Install::Base; 7 | 8 | use vars qw($VERSION @ISA); 9 | BEGIN { 10 | $VERSION = '0.11'; 11 | @ISA = 'Module::Install::Base'; 12 | } 13 | 14 | sub use_test_base { 15 | my $self = shift; 16 | $self->include('Test::Base'); 17 | $self->include('Test::Base::Filter'); 18 | $self->include('Spiffy'); 19 | $self->include('Test::More'); 20 | $self->include('Test::Builder'); 21 | $self->include('Test::Builder::Module'); 22 | $self->requires('Filter::Util::Call'); 23 | } 24 | 25 | 1; 26 | 27 | =encoding utf8 28 | 29 | #line 70 30 | -------------------------------------------------------------------------------- /inc/Module/Install/WriteAll.pm: -------------------------------------------------------------------------------- 1 | #line 1 2 | package Module::Install::WriteAll; 3 | 4 | use strict; 5 | use Module::Install::Base (); 6 | 7 | use vars qw{$VERSION @ISA $ISCORE}; 8 | BEGIN { 9 | $VERSION = '0.91';; 10 | @ISA = qw{Module::Install::Base}; 11 | $ISCORE = 1; 12 | } 13 | 14 | sub WriteAll { 15 | my $self = shift; 16 | my %args = ( 17 | meta => 1, 18 | sign => 0, 19 | inline => 0, 20 | check_nmake => 1, 21 | @_, 22 | ); 23 | 24 | $self->sign(1) if $args{sign}; 25 | $self->admin->WriteAll(%args) if $self->is_admin; 26 | 27 | $self->check_nmake if $args{check_nmake}; 28 | unless ( $self->makemaker_args->{PL_FILES} ) { 29 | $self->makemaker_args( PL_FILES => {} ); 30 | } 31 | 32 | # Until ExtUtils::MakeMaker support MYMETA.yml, make sure 33 | # we clean it up properly ourself. 34 | $self->realclean_files('MYMETA.yml'); 35 | 36 | if ( $args{inline} ) { 37 | $self->Inline->write; 38 | } else { 39 | $self->Makefile->write; 40 | } 41 | 42 | # The Makefile write process adds a couple of dependencies, 43 | # so write the META.yml files after the Makefile. 44 | if ( $args{meta} ) { 45 | $self->Meta->write; 46 | } 47 | 48 | # Experimental support for MYMETA 49 | if ( $ENV{X_MYMETA} ) { 50 | if ( $ENV{X_MYMETA} eq 'JSON' ) { 51 | $self->Meta->write_mymeta_json; 52 | } else { 53 | $self->Meta->write_mymeta_yaml; 54 | } 55 | } 56 | 57 | return 1; 58 | } 59 | 60 | 1; 61 | -------------------------------------------------------------------------------- /inc/Test/Builder/Module.pm: -------------------------------------------------------------------------------- 1 | #line 1 2 | package Test::Builder::Module; 3 | 4 | use strict; 5 | 6 | use Test::Builder; 7 | 8 | require Exporter; 9 | our @ISA = qw(Exporter); 10 | 11 | our $VERSION = '0.94'; 12 | $VERSION = eval $VERSION; ## no critic (BuiltinFunctions::ProhibitStringyEval) 13 | 14 | 15 | #line 74 16 | 17 | sub import { 18 | my($class) = shift; 19 | 20 | # Don't run all this when loading ourself. 21 | return 1 if $class eq 'Test::Builder::Module'; 22 | 23 | my $test = $class->builder; 24 | 25 | my $caller = caller; 26 | 27 | $test->exported_to($caller); 28 | 29 | $class->import_extra( \@_ ); 30 | my(@imports) = $class->_strip_imports( \@_ ); 31 | 32 | $test->plan(@_); 33 | 34 | $class->export_to_level( 1, $class, @imports ); 35 | } 36 | 37 | sub _strip_imports { 38 | my $class = shift; 39 | my $list = shift; 40 | 41 | my @imports = (); 42 | my @other = (); 43 | my $idx = 0; 44 | while( $idx <= $#{$list} ) { 45 | my $item = $list->[$idx]; 46 | 47 | if( defined $item and $item eq 'import' ) { 48 | push @imports, @{ $list->[ $idx + 1 ] }; 49 | $idx++; 50 | } 51 | else { 52 | push @other, $item; 53 | } 54 | 55 | $idx++; 56 | } 57 | 58 | @$list = @other; 59 | 60 | return @imports; 61 | } 62 | 63 | #line 137 64 | 65 | sub import_extra { } 66 | 67 | #line 167 68 | 69 | sub builder { 70 | return Test::Builder->new; 71 | } 72 | 73 | 1; 74 | -------------------------------------------------------------------------------- /lib/OpenResty/Backend.pm: -------------------------------------------------------------------------------- 1 | package OpenResty::Backend; 2 | 3 | #use Smart::Comments; 4 | use strict; 5 | use warnings; 6 | 7 | sub new { 8 | my ($class, $backend) = @_; 9 | if (!$backend) { 10 | die "No backend specified"; 11 | } 12 | my $backend_class = $class . '::' . $backend; 13 | ### $backend_class 14 | eval "use $backend_class"; 15 | if ($@) { 16 | die $@; 17 | } 18 | $backend_class->new({ PrintWarn => 0 }); 19 | } 20 | 21 | 1; 22 | __END__ 23 | 24 | =head1 NAME 25 | 26 | OpenResty::Backend - class factory for OpenResty backend classes 27 | 28 | =head1 SYNOPSIS 29 | 30 | my $type = 'Pg'; # or 'PgFarm' or 'PgMocked' 31 | my $backend = OpenResty::Backend->new($type); 32 | # where $backend is a OpenResty::Backend::Pg instance. 33 | 34 | =head1 DESCRIPTION 35 | 36 | This class serves as a class factory for the various OpenResty backend classes like L, L, and L. 37 | 38 | =head1 METHODS 39 | 40 | =over 41 | 42 | =item C<< $obj = OpenResty::Backend->new($type) >> 43 | 44 | Creates an instance of the specified backend class (via C<$type>). 45 | 46 | =back 47 | 48 | =head1 AUTHOR 49 | 50 | Yichun Zhang (agentzh) C<< >> 51 | 52 | =head1 SEE ALSO 53 | 54 | L, L, L, L, L. 55 | 56 | -------------------------------------------------------------------------------- /lib/OpenResty/Backend/PLPerl.pm: -------------------------------------------------------------------------------- 1 | package OpenResty::Backend::PLPerl; 2 | 3 | use strict; 4 | use warnings; 5 | 6 | use base 'OpenResty::Backend::Pg'; 7 | use OpenResty::Limits; 8 | 9 | sub new { 10 | return bless { user => undef }, $_[0]; 11 | } 12 | 13 | sub select { 14 | my ($self, $sql, $opts) = @_; 15 | my $rv = ::spi_exec_query($sql, $MAX_SELECT_LIMIT) or 16 | return []; 17 | my $rows = $rv->{rows} || []; 18 | unless ($opts->{use_hash}) { 19 | map { $_ = [values %$_] } @$rows; 20 | } 21 | return $rows; 22 | } 23 | 24 | sub do { 25 | my ($self, $sql) = @_; 26 | my $rv = ::spi_exec_query($sql) or return 0; 27 | return $rv->{processed}; 28 | } 29 | 30 | sub quote { 31 | my $val = pop; 32 | return undef unless defined $val; 33 | $val =~ s/\\/\\\\/g; 34 | $val =~ s/'/''/g; 35 | "'$val'"; 36 | } 37 | 38 | sub quote_identifier { 39 | my $val = pop; 40 | return undef unless defined $val; 41 | $val =~ s/\\/\\\\/g; 42 | $val =~ s/"/""/g; 43 | qq{"$val"}; 44 | } 45 | 46 | sub ping { 1; } 47 | 48 | 1; 49 | __END__ 50 | 51 | =head1 NAME 52 | 53 | OpenResty::Backend::PLPerl - Pg backend for OpenResty running via PL/Perl 54 | 55 | =head1 INHERITANCE 56 | 57 | OpenResty::Backend::PLPerl 58 | ISA OpenResty::Backend::Pg 59 | 60 | =head1 DESCRIPTION 61 | 62 | At the moment this backend is highly experimental and any serious uses are strongly discouraged. 63 | 64 | =head1 AUTHOR 65 | 66 | Yichun Zhang (agentzh) C<< >> 67 | 68 | =head1 SEE ALSO 69 | 70 | L, L, L, L, L. 71 | 72 | -------------------------------------------------------------------------------- /lib/OpenResty/FastCGI.pm: -------------------------------------------------------------------------------- 1 | package OpenResty::FastCGI; 2 | 3 | our $VERSION='1.07'; # SKIP 4 | 5 | use FCGI; 6 | use base 'CGI::Simple'; 7 | 8 | # workaround for known bug in libfcgi 9 | while (($ignore) = each %ENV) { } 10 | 11 | # override the initialization behavior so that 12 | # state is NOT maintained between invocations 13 | sub save_request { 14 | # no-op 15 | } 16 | 17 | # If ENV{FCGI_SOCKET_PATH} is specified, we maintain a FCGI Request handle 18 | # in this package variable. 19 | use vars qw($Ext_Request); 20 | BEGIN { 21 | # If ENV{FCGI_SOCKET_PATH} is given, explicitly open the socket, 22 | # and keep the request handle around from which to call Accept(). 23 | if ($ENV{FCGI_SOCKET_PATH}) { 24 | my $path = $ENV{FCGI_SOCKET_PATH}; 25 | my $backlog = $ENV{FCGI_LISTEN_QUEUE} || 100; 26 | my $socket = FCGI::OpenSocket( $path, $backlog ); 27 | $Ext_Request = FCGI::Request( \*STDIN, \*STDOUT, \*STDERR, 28 | \%ENV, $socket, 1 ); 29 | } 30 | } 31 | 32 | # New is slightly different in that it calls FCGI's 33 | # accept() method. 34 | sub new { 35 | my ($self, $initializer, @param) = @_; 36 | unless (defined $initializer) { 37 | if ($Ext_Request) { 38 | return undef unless $Ext_Request->Accept() >= 0; 39 | } else { 40 | return undef unless FCGI::accept() >= 0; 41 | } 42 | } 43 | return $CGI::Q = $self->SUPER::new($initializer, @param); 44 | } 45 | 46 | # to work around an IPC::Run issue... 47 | *FCGI::Stream::FILENO = sub { 1; }; 48 | 49 | 1; 50 | 51 | -------------------------------------------------------------------------------- /lib/OpenResty/Handler/Base.pm: -------------------------------------------------------------------------------- 1 | package OpenResty::Handler::Base; 2 | 3 | use strict; 4 | use warnings; 5 | 6 | sub go { 7 | my ($self, $openresty, $http_meth, $bits) = @_; 8 | my $level = @$bits - 1; 9 | my $name = $self->level2name($level); 10 | if (!defined $name) { 11 | die "Unknown URL level: $level\n"; 12 | } 13 | my $meth = $http_meth . '_' . $name; 14 | if (!$self->can($meth)) { 15 | $name =~ s/_/ /g; 16 | die "HTTP $http_meth method not supported for $name.\n"; 17 | } 18 | $self->$meth($openresty, $bits); 19 | } 20 | 21 | sub register { 22 | my $class = shift; 23 | for my $cat (@_) { 24 | $OpenResty::Dispatcher::Handlers{$cat} = $class; 25 | } 26 | } 27 | 28 | sub requires_acl { 1; } 29 | 30 | 1; 31 | 32 | -------------------------------------------------------------------------------- /lib/OpenResty/Handler/LastResponse.pm: -------------------------------------------------------------------------------- 1 | package OpenResty::Handler::LastResponse; 2 | 3 | use strict; 4 | use warnings; 5 | 6 | use base 'OpenResty::Handler::Base'; 7 | 8 | __PACKAGE__->register('last'); 9 | 10 | sub requires_acl { undef } 11 | 12 | sub level2name { 13 | (undef, 'last_response_wo_id', 'last_response')[$_[-1]] 14 | } 15 | 16 | sub GET_last_response_wo_id { 17 | die "No last response ID specified."; 18 | } 19 | 20 | sub GET_last_response { 21 | my ($self, $openresty, $bits) = @_; 22 | die "Only /=/last/response is allowed.\n" if $bits->[1] ne 'response'; 23 | my $last_res_id = $bits->[2]; 24 | my $res = $OpenResty::Cache->get_last_res($last_res_id); 25 | if (!defined $res) { 26 | die "No last response found for ID $last_res_id"; 27 | return; 28 | } 29 | $openresty->{_bin_data} = "$res\n"; 30 | #warn "last_response: $response_from_cookie\n"; 31 | return; 32 | } 33 | 34 | sub set_last_response { 35 | my ($self, $openresty, $value) = @_; 36 | #warn "!!!!!!!!!!!!!!!!!!!!!!!!!!wdy!"; 37 | 38 | my $id = $openresty->builtin_param('_last_response'); 39 | if ($id) { 40 | $OpenResty::Cache->set_last_res($id, $value); 41 | } 42 | } 43 | 44 | 1; 45 | 46 | -------------------------------------------------------------------------------- /lib/OpenResty/Handler/Logout.pm: -------------------------------------------------------------------------------- 1 | package OpenResty::Handler::Logout; 2 | 3 | use strict; 4 | use warnings; 5 | 6 | use base 'OpenResty::Handler::Base'; 7 | 8 | __PACKAGE__->register('logout'); 9 | 10 | sub requires_acl { undef } 11 | 12 | sub level2name { 13 | qw< logout >[$_[-1]]; 14 | } 15 | 16 | sub GET_logout { 17 | ### Yeah yeah yeah! 18 | my ($self, $openresty, $bits) = @_; 19 | my $session = $openresty->get_session; 20 | #my $session = $openresty->{_session}; 21 | #warn "session: $session"; 22 | if ($session) { 23 | $OpenResty::Cache->remove($session); 24 | } 25 | #warn "HERE!"; 26 | $openresty->{_bin_data} = "{\"success\":1}\n"; 27 | return undef; 28 | } 29 | 30 | 1; 31 | -------------------------------------------------------------------------------- /lib/OpenResty/Handler/Unsafe.pm: -------------------------------------------------------------------------------- 1 | package OpenResty::Handler::Unsafe; 2 | 3 | use strict; 4 | use warnings; 5 | 6 | use Params::Util qw( _STRING ); 7 | 8 | use base 'OpenResty::Handler::Base'; 9 | 10 | __PACKAGE__->register('unsafe'); 11 | 12 | sub level2name { 13 | qw< unsafe unsafe_op >[$_[-1]]; 14 | } 15 | 16 | # XXX TODO we should provide a config option to turn off or on the Unsafe API 17 | sub POST_unsafe_op { 18 | my ($self, $openresty, $bits) = @_; 19 | 20 | my $user = $openresty->current_user; 21 | unless ($OpenResty::UnsafeAccounts{$user}) { 22 | die "Unsafe operations not permitted for the $user account.\n"; 23 | } 24 | my $op = $bits->[1]; 25 | if ($op ne 'select' and $op ne 'do') { 26 | die "Unsafe operation not supported: $op\n"; 27 | } 28 | ### $op 29 | my $sql = _STRING($openresty->{_req_data}) or 30 | die "SQL literal must be a string.\n"; 31 | 32 | 33 | if ($op eq 'select') { 34 | return $openresty->select($sql, { use_hash => 1 }); 35 | } elsif ($op eq 'do') { 36 | $openresty->do($sql); 37 | return { success => 1 }; 38 | } 39 | } 40 | 41 | 1; 42 | __END__ 43 | 44 | =head1 NAME 45 | 46 | OpenResty::Handler::Unsafe - The "unsafe" handler for OpenResty 47 | 48 | =head1 SYNOPSIS 49 | 50 | =head1 DESCRIPTION 51 | 52 | This OpenResty handler class implements the Unsafe API, i.e., the C stuff. 53 | 54 | =head1 METHODS 55 | 56 | =head1 AUTHOR 57 | 58 | Yichun Zhang (agentzh) C<< >> 59 | 60 | =head1 SEE ALSO 61 | 62 | L, L, L, L, L, L, L, L, L. 63 | 64 | -------------------------------------------------------------------------------- /lib/OpenResty/Inlined.pm: -------------------------------------------------------------------------------- 1 | package OpenResty::Inlined; 2 | 3 | use strict; 4 | use warnings; 5 | 6 | use base 'OpenResty'; 7 | 8 | sub response { 9 | my $self = shift; 10 | if ($self->{_no_response}) { return undef; } 11 | 12 | #print "HTTP/1.1 200 OK\n"; 13 | #warn $s; 14 | if (my $bin_data = $self->{_bin_data}) { 15 | return "BINARY DATA"; 16 | } 17 | if (my $error = $self->{_error}) { 18 | return $self->emit_error($error); 19 | } 20 | if (my $data = $self->{_data}) { 21 | if ($self->{_warning}) { 22 | $data->{warning} = $self->{_warning}; 23 | } 24 | return $data; 25 | } 26 | return undef; 27 | } 28 | 29 | sub emit_data { 30 | my ($self, $data) = @_; 31 | #warn "$data"; 32 | return $data; 33 | } 34 | 35 | 1; 36 | __END__ 37 | 38 | =head1 NAME 39 | 40 | OpenResty::Inlined - OpenResty app class for inlined REST requrests 41 | 42 | -------------------------------------------------------------------------------- /lib/OpenResty/QuasiQuote/SQL.pm: -------------------------------------------------------------------------------- 1 | package OpenResty::QuasiQuote::SQL; 2 | 3 | use strict; 4 | use warnings; 5 | 6 | require Filter::QuasiQuote; 7 | our @ISA = qw( Filter::QuasiQuote ); 8 | 9 | #use Module::Optimize -base; sub pmc_optimize { return $_[1]; } 10 | 11 | sub sql { 12 | my ($self, $s, $file, $line, $col) = @_; 13 | my $package = ref $self; 14 | #warn "SQL: $file: $line: $s\n"; 15 | $s =~ s/^\s+|\s+$/ /gs; 16 | #$s =~ s/\n/ /gs; 17 | $s =~ s/\\/\\\\/g; 18 | $s =~ s/\s+/ /gs; 19 | #$s =~ s/\t/\\t/gs; 20 | $s =~ s/"/\\"/g; 21 | $s =~ s/\$(\w+)\b([^:])/".Q(\$$1)."$2/g; 22 | $s =~ s/\$\w+$/".Q($&)."/g; 23 | $s =~ s/\$sym:(\w+)\b/".QI(\$$1)."/g; 24 | $s =~ s/\$kw:(\w+)\b/".\$$1."/g; 25 | if ($s =~ /\$(\w+):\w+\b/) { 26 | die __PACKAGE__, ": Unknown antiquoting sequence: $&\n"; 27 | } 28 | $s = qq{"$s"}; 29 | $s =~ s/\.""$//; 30 | $s; 31 | } 32 | 33 | 1; 34 | 35 | -------------------------------------------------------------------------------- /lib/OpenResty/QuasiQuote/Validator.pm: -------------------------------------------------------------------------------- 1 | package OpenResty::QuasiQuote::Validator; 2 | 3 | use strict; 4 | use warnings; 5 | 6 | #use Smart::Comments; 7 | use OpenResty::QuasiQuote::Validator::Compiler; 8 | require Filter::QuasiQuote; 9 | our @ISA = qw( Filter::QuasiQuote ); 10 | 11 | #$::RD_HINT = 1; 12 | #$::RD_TRACE = 1; 13 | our $Comp = OpenResty::QuasiQuote::Validator::Compiler->new; 14 | 15 | sub validator { 16 | my ($self, $s, $fname, $ln, $col) = @_; 17 | my $r = $Comp->validator($s, $ln) or die "Execution aborted due to syntax errors in validator quasiquotations.\n"; 18 | $r =~ s/\n/ /sg; 19 | $r; 20 | } 21 | 22 | 1; 23 | 24 | -------------------------------------------------------------------------------- /lib/OpenResty/SQL/Statement.pm: -------------------------------------------------------------------------------- 1 | package OpenResty::SQL::Statement; 2 | 3 | use strict; 4 | use warnings; 5 | use base 'Clone'; 6 | use overload '""' => sub { $_[0]->generate }; 7 | 8 | sub reset { 9 | my $self = shift; 10 | %$self = %{ $self->new(@_) }; 11 | $self; 12 | } 13 | 14 | sub where { 15 | my $self = shift; 16 | if (@_ == 2) { 17 | push @{ $self->{where} }, [$_[0], '=', $_[1]]; 18 | } else { 19 | push @{ $self->{where} }, [@_]; 20 | } 21 | $self; 22 | } 23 | 24 | 1; 25 | __END__ 26 | 27 | =head1 NAME 28 | 29 | OpenResty::SQL::Statement - Base class for the various SQL generator classes 30 | 31 | =head1 DESCRIPTION 32 | 33 | =head1 AUTHOR 34 | 35 | Yichun Zhang (agentzh) C<< >> 36 | 37 | =head1 SEE ALSO 38 | 39 | L, L, L, L. 40 | 41 | -------------------------------------------------------------------------------- /lib/OpenResty/Script/Upgrade.pm: -------------------------------------------------------------------------------- 1 | package OpenResty::Script::Upgrade; 2 | 3 | use strict; 4 | use warnings; 5 | 6 | sub go { 7 | my ($class, $backend, $user) = @_; 8 | if ($user) { 9 | if ($backend->has_user($user)) { 10 | $backend->set_user($user); 11 | my $base = $backend->get_upgrading_base; 12 | if ($base >= 0) { 13 | $backend->upgrade_local_metamodel($base); 14 | } else { 15 | warn "User $user is already up to date.\n"; 16 | } 17 | } else { 18 | die "User $user does not exist.\n"; 19 | } 20 | } else { 21 | $backend->upgrade_all; 22 | } 23 | } 24 | 25 | 1; 26 | -------------------------------------------------------------------------------- /lib/OpenResty/Server.pm: -------------------------------------------------------------------------------- 1 | package OpenResty::Server; 2 | 3 | use strict; 4 | use warnings; 5 | use base qw(HTTP::Server::Simple::CGI); 6 | 7 | our $IsRunning = 0; 8 | 9 | sub handle_request { 10 | my ($self, $cgi) = @_; 11 | $IsRunning = 1; 12 | OpenResty::Dispatcher->process_request($cgi); 13 | } 14 | 15 | #sub net_server { "Net::Server::PreFork" } 16 | 17 | 1; 18 | __END__ 19 | 20 | =head1 NAME 21 | 22 | OpenResty::Server - Standalone server based on HTTP::Server::Simple for OpenResty 23 | 24 | =head1 INHERITANCE 25 | 26 | OpenResty::Server 27 | ISA HTTP::Server::Simple::CGI 28 | 29 | =head1 DESCRIPTION 30 | 31 | =head1 AUTHOR 32 | 33 | Yichun Zhang (agentzh) C<< >>. 34 | 35 | =head1 SEE ALSO 36 | 37 | L, L, L. 38 | 39 | -------------------------------------------------------------------------------- /lib/OpenResty/Shell/History.pm: -------------------------------------------------------------------------------- 1 | package OpenResty::Shell::History; 2 | 3 | use strict; 4 | use warnings; 5 | use YAML::Syck qw(LoadFile DumpFile); 6 | 7 | sub new { 8 | my ($class, $opts) = @_; 9 | $opts ||= {}; 10 | my $file = $opts->{file} or 11 | die "No file name given"; 12 | my $term = $opts->{term} or 13 | die "No Term::ReadLine object given"; 14 | my $count = $opts->{count} || 100; 15 | my $features = $term->Features; 16 | my $hist; 17 | if (-f $file) { 18 | $hist = LoadFile($file); 19 | for my $cmd (@$hist) { 20 | #warn $cmd; 21 | $term->addhistory($cmd) 22 | if $cmd && $cmd =~ /\w/ && $features->{autohistory}; 23 | } 24 | } 25 | bless { 26 | hist => $hist || [], 27 | file => $file, 28 | features => $features, 29 | term => $term, 30 | count => $count, 31 | }, $class; 32 | } 33 | 34 | sub add_history { 35 | my ($self, $input) = @_; 36 | return unless $input && $input =~ /\w/; 37 | my $hist = $self->{hist}; 38 | my $file = $self->{file}; 39 | my $count = $self->{count}; 40 | if (@$hist >= $count) { 41 | shift @$hist; 42 | } 43 | push @$hist, $input; 44 | my $features = $self->{features}; 45 | $self->{term}->addhistory($input) 46 | if $features->{autohistory}; 47 | DumpFile($file, $hist); 48 | } 49 | 50 | 1; 51 | -------------------------------------------------------------------------------- /lib/OpenResty/Spec/Arch_cn.pod: -------------------------------------------------------------------------------- 1 | =encoding UTF-8 2 | 3 | =head1 NAME 4 | 5 | OpenResty::Spec::Arch_cn - OpenSearch 体系结构白皮书(草案) 6 | 7 | =head1 AUTHOR 8 | 9 | Ting (于霆) 10 | 11 | =head1 VERSION 12 | 13 | CREATED: Dec 1, 2007 14 | LAST MODIFIED: Dec 1, 2007 15 | VERSION: 0.01 16 | 17 | =head1 DESCRIPTION 18 | 19 | 本文定义了 OpenSearch 的系统结构, 协议层由 OpenResty 支撑, 存储上使用的是PostgreSQL集群. 20 | 21 | =head2 DESIGN GOALS 22 | 23 | =over 24 | 25 | =item * 26 | 27 | 能够支持 OpenResty 中对数据的所有操作, 在保证 OpenResty 的足够灵活的基础上,同时通过PostgreSQL 28 | 的存储过程,或者视图来简化 OpenResty 对于OpenSearch的复杂操作逻辑. 29 | 30 | =item * 31 | 32 | OpenSearch 结构化数据存储和查询部分是完全由 PostgreSQL 支持的. 非结构化数据是由某种分布式 33 | 文件系统来支撑. (这里的非结构化数据,通常是指大对象文件). 34 | 35 | =item * 36 | 37 | 在存储结构化数据的时候,要保证灵活. 具体体现在可以支持用户自定义的数据结构. 38 | 39 | =item * 40 | 41 | 系统本身要是可扩充的,每个用户拥有其各自的独立空间,用户在系统内部是可迁移的(在节点之间是可迁移.) 42 | 43 | =back 44 | 45 | =head2 DESIGN BACKGROUND 46 | 47 | PE Team 长期对于理想Search系统的孜孜不倦的追求. 这个理想的系统具备的特征是, 高度可扩展的,支持丰富索引类型的,数据之间在系统内部可以建立关系的,容易运维的系统. 48 | 49 | =head1 Data stream 50 | 51 | =head1 System operate type. 52 | 53 | =head1 User define. 54 | 55 | =head1 Role define. 56 | 57 | =head1 ACL 58 | 59 | -------------------------------------------------------------------------------- /lib/OpenResty/Spec/Install/Apache.pod: -------------------------------------------------------------------------------- 1 | =head1 NAME 2 | 3 | OpenResty::Spec::Install::Apache - Configuring OpenResty.pm with Apache2 + mod_fcgid 4 | 5 | =head1 SYNOPSIS 6 | 7 | # File /opt/apache2/conf/httpd.conf 8 | ... 9 | LoadModule fcgid_module modules/mod_fcgid.so 10 | LoadModule rewrite_module modules/mod_rewrite.so 11 | # the line below is optional: 12 | LoadModule deflate_module modules/mod_deflate.so 13 | DocumentRoot "/some/path/to/my/doc/root" 14 | RewriteEngine on 15 | RewriteRule ^/=/ /openresty.fcgi [QSA,L] 16 | AllowEncodedSlashes On 17 | 18 | Options ExecCGI FollowSymLinks 19 | # the line below is optional: 20 | AddOutputFilter DEFLATE .fcgi .html .css .js 21 | AddHandler fcgid-script .fcgi 22 | Allow from all 23 | 24 | 25 | # File /some/path/to/my/doc/root/openresty.fcgi (remember chmod +x this!) 26 | #!/bin/sh 27 | exec openresty fastcgi 28 | 29 | =head1 DESCRIPTION 30 | 31 | OpenResty.pm could be run as a FastCGI application with C or C. See L for sample configurations. 32 | 33 | Note that when using with C to do gzip/deflate compression, it's recommended to set C to C<0>. 34 | 35 | Apache's C should be turned on or the following model request would result in a 404 error: 36 | 37 | http://server:1234/=/model/urls/~/http%3A%2F%2Fwww.yahoo.cn%2Fhello%3Fabc%3D32 38 | 39 | =head1 AUTHOR 40 | 41 | Yichun Zhang (agentzh) C<< >>. 42 | 43 | =head1 SEE ALSO 44 | 45 | L, L, L. 46 | 47 | -------------------------------------------------------------------------------- /lib/OpenResty/Spec/Install/Lighttpd.pod: -------------------------------------------------------------------------------- 1 | =head1 NAME 2 | 3 | OpenResty::Spec::Install::Lighttpd - Configuring OpenResty.pm with Lighttpd + mod_fastcgi 4 | 5 | =head1 SYNOPSIS 6 | 7 | # lighttpd.conf 8 | 9 | server.modules = ( 10 | "mod_fastcgi", 11 | ... 12 | ) 13 | 14 | fastcgi.server = ( 15 | "/=" => ( 16 | "openresty" => ( 17 | "socket" => "/tmp/openresty.socket", 18 | "check-local" => "disable", 19 | "bin-path" => "/PATH/TO/YOUR/bin/openresty", 20 | "bin-environment" => ( 21 | "OPENRESTY_URL_PREFIX" => "", 22 | "OPENRESTY_COMMAND" => "fastcgi", 23 | ), 24 | "min-procs" => 1, 25 | "max-procs" => 5, 26 | "max-load-per-proc" => 1, 27 | "idle-timeout" => 20, 28 | ) 29 | ) 30 | ) 31 | 32 | And also B the following line is commented out: 33 | 34 | # url.access-deny = ( "~", ".inc" ) 35 | 36 | =head1 DESCRIPTION 37 | 38 | OpenResty.pm could be run by lighttpd 1.4.x's mod_fastcgi module. But note that because lighttpd's mod_fastcgi won't refresh its underlying perl processes, and one may observe slow momery leaks after weeks' run. It's recommended to use Apache2's mod_fcgid to run OpenResty.pm. See L for details. 39 | 40 | =head1 AUTHOR 41 | 42 | Yichun Zhang (agentzh) C<< >>. 43 | 44 | =head1 SEE ALSO 45 | 46 | L, L, L. 47 | 48 | -------------------------------------------------------------------------------- /lib/OpenResty/Spec/TestSuite.pod: -------------------------------------------------------------------------------- 1 | =head1 NAME 2 | 3 | OpenResty::Spec::TestSuite - Introduction to the OpenResty test suite 4 | 5 | =head1 SYNOPSIS 6 | 7 | $ make test -f dev.mk 8 | # OR 9 | $ prove -Ilib -r t 10 | 11 | =head1 DESCRIPTION 12 | 13 | OpenResty comes with a relatively big test suite. 14 | 15 | Most of the test suite is organized by the L. The main test 16 | scaffold is in the F file. 17 | 18 | There's various different ways to run the suite. 19 | 20 | The C option in the config file (i.e., 21 | F) determines which backend the server is 22 | using. Possible values are C, C, and C. The default 23 | value is C, which is a mocked-up version of the C backend, 24 | so that users without a proper Pg setup (like CPAN testers) can still 25 | run the whole test suite. Please see L 26 | for more information. 27 | 28 | The C option in the config file determines whether 29 | or not the test scaffold should use HTTP to test the server. When it 30 | is set to 1, the test harness will use C to test the 31 | server specified by the C and C 32 | options. If set to 0, the test suite will run directly in the same 33 | process of the OpenResty server by using a mocked-up CGI environment 34 | provided by L. 35 | 36 | Note that when C is set to 1, it's possible to test 37 | a I OpenResty server. 38 | 39 | =head1 AUTHOR 40 | 41 | Yichun Zhang (agentzh) C<< >> 42 | 43 | =head1 SEE ALSO 44 | 45 | L. 46 | 47 | -------------------------------------------------------------------------------- /misc/plperl.sql: -------------------------------------------------------------------------------- 1 | set search_path to _global; 2 | 3 | create or replace function openresty_init () returns boolean as $$ 4 | use OpenResty::Dispatcher; 5 | use JSON::Syck; 6 | use OpenResty::Util; 7 | OpenResty::Dispatcher->init('plperl'); 8 | return true; 9 | $$ language plperlu; 10 | 11 | create type openresty_res_type as (content_type text, content text); 12 | drop function if exists openresty_request(text,text,text,text); 13 | 14 | create or replace function openresty_request (text, text, text, text) returns 15 | text as $$ 16 | my ($meth, $url, $content, $raw_cookie) = @_; 17 | local %ENV; 18 | $ENV{HTTP_COOKIE} = $raw_cookie; 19 | $ENV{REQUEST_URI} = $url; 20 | $ENV{REQUEST_METHOD} = $meth; 21 | my $cgi = OpenResty::Util::new_mocked_cgi($url, $content); 22 | my $res = OpenResty::Dispatcher->process_request($cgi, 1); 23 | # return_next($res); 24 | return JSON::Syck::Dump($res); 25 | $$ language plperlu; 26 | 27 | select openresty_init(); 28 | select openresty_request('GET', '/=/view/PrevNextPost/current/5?user=agentzh.Public', '', ''); 29 | 30 | -------------------------------------------------------------------------------- /misc/restylog/Makefile: -------------------------------------------------------------------------------- 1 | year=2008 2 | month=07 3 | day=04 4 | html_file=stats-$(year)$(month)$(day).html 5 | 6 | all: $(html_file) 7 | 8 | $(html_file): stats.html 9 | cp $< $@ 10 | 11 | %.html: %.pod 12 | podhtm --index --css perl.css -o $@ $< 13 | 14 | %.pod: %.podx 15 | DSN=dbi:Pg:dbname=test /usr/local/bin/podx -u agentz $< 16 | 17 | %.podx: %.tt 18 | tpage --define year=$(year) --define month=$(month) --define day=$(day) $< > $@ 19 | 20 | upload: $(html_file) 21 | scp -P 18888 -l 10000 $(html_file) agentzh@agentzh.org:~/misc/logs/ 22 | 23 | import: 24 | perl import.pl ced02 ced02/$(year)/$(month)/$(day)/*.log 25 | 26 | -------------------------------------------------------------------------------- /misc/restylog/matrix.tt: -------------------------------------------------------------------------------- 1 | [% DEFAULT 2 | year = '2008', 3 | month = '07', 4 | day = '04' 5 | -%] 6 | [% ymd = year _ month _ day -%] 7 | [% table = 'access_' _ ymd %] 8 | =encoding utf8 9 | 10 | =head1 NAME 11 | 12 | matrix_stats - 腐败魔方应用的 ced02 日志分析 ([% year %]-[% month %]-[% day %]) 13 | 14 | 15 | =SQL set search_path to restylog; 16 | 17 | =head1 Queries for 腐败魔方 18 | 19 | 总请求数目: 20 | 21 | =begin SQL 22 | 23 | select count(*) from restylog.[% table %] where account = 'lives'; 24 | 25 | =end SQL 26 | 27 | 请求列表 28 | 29 | =begin SQL 30 | 31 | select count(*), 32 | regexp_replace(url, '/=/view/.*?\\?|&_user=lives\\.Public|&limit=\\d+&offset=\\d+', '', 'g') as query 33 | from restylog.[% table %] 34 | where account = 'lives' and url like '/=/view/magicbox_cool%' and url like '%&addr=%' 35 | group by query 36 | order by query 37 | 38 | =end SQL 39 | -------------------------------------------------------------------------------- /misc/restylog/perl.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agentzh/old-openresty/53dad17e84dc6d2a0dffddb119851c50c0ca3a8d/misc/restylog/perl.css -------------------------------------------------------------------------------- /obsolete/minisql/lib/OpenAPI/.~ko-4.1.1-perllint~c: -------------------------------------------------------------------------------- 1 | # Generated by OpenAPI::_p6grammar 0 (Module::Compile 0.20) - do not edit! 2 | ################((( 32-bit Checksum Validator III )))################ 3 | #line 1 4 | BEGIN { use 5.006; local (*F, $/); ($F = __FILE__) =~ s!c$!!; open(F) 5 | or die "Cannot open $F: $!"; binmode(F, ':crlf'); if (unpack('%32N*', 6 | $F=readline(*F)) != 0x42CC99A6) { use Filter::Util::Call; my $f = $F; 7 | filter_add(sub { filter_del(); 1 while &filter_read; $_ = $f; 1; })}} 8 | #line 1 9 | # 13362d28eaf259978a36faeb9815166d7294ada5 10 | use strict; 11 | use warnings; 12 | 13 | package OpenAPI::miniSQL; 14 | 15 | use lib ".."; 16 | 17 | 18 | 1; 19 | -------------------------------------------------------------------------------- /obsolete/minisql/lib/OpenAPI/miniSQL/Compile.pm: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl -w 2 | use strict; 3 | use warnings; 4 | 5 | package OpenResty::miniSQL::Compile; 6 | 7 | use Module::Compile -base; 8 | use Pugs::Compiler::Grammar; 9 | use Pugs::Runtime::Tracer; 10 | use File::Slurp; 11 | 12 | 13 | my $debug = 0; 14 | my $safe_mode = 0; 15 | my $debug_dir = './dbg/'; 16 | 17 | sub import { 18 | my ($self, %opt) = @_; 19 | $debug = 1 if $opt{'debug'}; 20 | $safe_mode = 1 if $opt{'safe_mode'}; 21 | $debug_dir = $opt{'debug_dir'} if exists $opt{'debug_dir'}; 22 | goto &Module::Compile::import; 23 | } 24 | 25 | sub pmc_compile { 26 | my ($self, $source) = @_; 27 | # grammar name 28 | $source =~ m/grammar\s+(.+?);/; 29 | my $grammar_name = $1; 30 | # write grammar to a tmp file 31 | $grammar_name =~ s/::/-/; 32 | mkdir $debug_dir if not -x $debug_dir and $debug; 33 | write_file("$debug_dir$grammar_name.grammar", \$source) if $debug; 34 | # call the compiler 35 | my $compiler = Pugs::Compiler::Grammar->compile( 36 | $source, { safe_mode => $safe_mode } ) or die; 37 | # return with tracing code if $debug 38 | return $debug ? expand_tracing_code($compiler->perl5) 39 | : $compiler->perl5; 40 | } 41 | 42 | 1; -------------------------------------------------------------------------------- /obsolete/minisql/t/02-symbol.t: -------------------------------------------------------------------------------- 1 | use strict; 2 | use warnings; 3 | 4 | use t::miniSQL; 5 | 6 | test 'symbol', 'a', 'a'; 7 | test 'symbol', 'abc', 'abc'; 8 | test 'symbol', 'ABC', 'ABC'; 9 | test 'symbol', 'aBc', 'aBc'; 10 | test 'symbol', 'abc123', 'abc123'; 11 | test 'symbol', 'abc123_', 'abc123_'; 12 | test 'symbol', '_abc123_', '_abc123_'; 13 | test 'symbol', '_abc_123_', '_abc_123_'; 14 | test 'symbol', '123abc', 'abc'; 15 | 16 | test 'qualified_symbol', '_a3_bc_._1b_ca2_', { 17 | symbol => [ 18 | symbol('_a3_bc_'), 19 | symbol('_1b_ca2_') 20 | ] 21 | }; 22 | 23 | test 'alias', 'abc_123', { 24 | 'symbol' => 'abc_123' 25 | }; 26 | test 'model', '_Abc1CbA', { 27 | 'symbol' => '_Abc1CbA' 28 | }; 29 | 30 | 31 | test 'column', 'abc', { 32 | 'symbol' => 'abc' 33 | }; 34 | test 'column', 'abc.efg', { 35 | qualified_symbol => qualified_symbol('abc.efg') 36 | }; 37 | -------------------------------------------------------------------------------- /obsolete/minisql/t/miniSQL.pm: -------------------------------------------------------------------------------- 1 | use strict; 2 | use warnings; 3 | 4 | package t::miniSQL; 5 | 6 | use OpenResty::miniSQL; 7 | 8 | use Test::More qw(no_plan); 9 | use Data::Dumper; 10 | 11 | sub import() { 12 | no strict 'refs'; 13 | *{caller()."::test"} = \&test; 14 | *{caller()."::rule"} = \&rule; 15 | *{caller()."::AUTOLOAD"} = \&AUTOLOAD; 16 | } 17 | 18 | sub rule(@) { 19 | my ($rule, $in) = @_; 20 | no strict 'refs'; 21 | my $r = *{"OpenResty::miniSQL::$rule"}; 22 | return $r->("OpenResty::miniSQL", $in); 23 | } 24 | 25 | sub rule_capture(@) { 26 | return rule(@_)->(); 27 | } 28 | 29 | sub AUTOLOAD { 30 | no strict 'refs'; 31 | if (${__PACKAGE__."::AUTOLOAD"} =~ m/::([^:]+)$/) { 32 | unshift @_, $1; 33 | goto &rule_capture; 34 | } 35 | } 36 | 37 | sub test(@) { 38 | my ($rule, $in, $expect) = @_; 39 | #my $prefix = "\n".("#" x 30)."\n"; 40 | my $prefix = "\n"; 41 | cmp_ok $prefix.Dumper(rule($rule, $in)->()), 'eq', $prefix.Dumper($expect); 42 | } 43 | 44 | 1; 45 | -------------------------------------------------------------------------------- /obsolete/minisql/test.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl -w 2 | 3 | use strict; 4 | 5 | use Test::Harness; 6 | 7 | use lib "./lib"; 8 | 9 | runtests glob("./t/*.t"); 10 | -------------------------------------------------------------------------------- /share/README: -------------------------------------------------------------------------------- 1 | This is the share directory for OpenResty. 2 | 3 | -------------------------------------------------------------------------------- /t/00-prereq.t: -------------------------------------------------------------------------------- 1 | # vi:filetype= 2 | 3 | use t::OpenResty; 4 | 5 | plan tests => 3*blocks(); 6 | #plan tests => 3 * blocks(); 7 | 8 | run_tests; 9 | 10 | my $Test = Test::Builder->new; 11 | if (grep {!$_} $Test->summary) { # any failure 12 | $Test->BAIL_OUT('failing very basic tests, ensure your db is configured according to OpenResty::Spec::Install'); 13 | } 14 | 15 | 16 | __DATA__ 17 | 18 | === TEST 1: Login with password but w/o cookie 19 | --- request 20 | GET /=/login/$TestAccount.Admin/$TestPass 21 | --- response_like 22 | ^{"success":1,"session":"[-\w]+","account":"$TestAccount","role":"Admin"}$ 23 | -------------------------------------------------------------------------------- /t/07-bug.t: -------------------------------------------------------------------------------- 1 | # vi:filetype= 2 | 3 | use t::OpenResty; 4 | 5 | plan tests => 3 * blocks(); 6 | 7 | run_tests; 8 | 9 | __DATA__ 10 | 11 | === TEST 1: UTF-8 12 | --- charset: UTF-8 13 | --- request 14 | DELETE /=/model?_user=$TestAccount&_password=$TestPass&_use_cookie=1 15 | --- response 16 | {"success":1} 17 | 18 | 19 | 20 | === TEST 2: It hangs or report error 21 | --- request 22 | GET /=/model/Foo/~/~ 23 | --- response 24 | {"success":0,"error":"Model \"Foo\" not found."} 25 | 26 | 27 | 28 | === TEST 3: It hangs or report error 29 | --- request 30 | GET /blah 31 | --- response 32 | {"success":0,"error":"URLs must be led by '='."} 33 | --- SKIP 34 | 35 | 36 | 37 | === TEST 4: logout 38 | --- request 39 | GET /=/logout 40 | --- response 41 | {"success":1} 42 | 43 | -------------------------------------------------------------------------------- /t/09-sql-insert.t: -------------------------------------------------------------------------------- 1 | use lib 'lib'; 2 | use strict; 3 | use warnings; 4 | 5 | use Test::More tests => 4; 6 | BEGIN { use_ok('OpenResty::SQL::Insert'); } 7 | 8 | my $insert = OpenResty::SQL::Insert->new; 9 | $insert->insert( 'models' ) 10 | ->values( 'abc' => '"howdy"' ); 11 | 12 | is $insert->generate, <<_EOC_; 13 | insert into models values (abc, "howdy"); 14 | _EOC_ 15 | 16 | is "$insert", <<_EOC_; 17 | insert into models values (abc, "howdy"); 18 | _EOC_ 19 | 20 | $insert->cols('foo', 'bar'); 21 | 22 | is $insert->generate, <<_EOC_; 23 | insert into models (foo, bar) values (abc, "howdy"); 24 | _EOC_ 25 | 26 | -------------------------------------------------------------------------------- /t/09-sql-select.t: -------------------------------------------------------------------------------- 1 | use lib 'lib'; 2 | use strict; 3 | use warnings; 4 | 5 | use Test::More tests => 9; 6 | BEGIN { use_ok('OpenResty::SQL::Select'); } 7 | 8 | sub _Q { "'$_[0]'" } 9 | 10 | my $select = OpenResty::SQL::Select->new; 11 | $select->select( qw ) 12 | ->from( '_columns' ); 13 | 14 | is $select->generate, <<_EOC_; 15 | select name, type, label from _columns; 16 | _EOC_ 17 | 18 | is "$select", <<_EOC_; 19 | select name, type, label from _columns; 20 | _EOC_ 21 | 22 | $select->where("table_name", '=', _Q('blah')); 23 | 24 | is $select->generate, <<_EOC_; 25 | select name, type, label from _columns where table_name = 'blah'; 26 | _EOC_ 27 | 28 | $select->order_by("foo"); 29 | 30 | is $select->generate, <<_EOC_; 31 | select name, type, label from _columns where table_name = 'blah' order by foo; 32 | _EOC_ 33 | 34 | $select->where("Foo", '>', 'bar')->where('Bar' => '3'); 35 | is "$select", <<'_EOC_'; 36 | select name, type, label from _columns where table_name = 'blah' and Foo > bar and Bar = 3 order by foo; 37 | _EOC_ 38 | 39 | $select->reset( qw ) 40 | ->from( '_columns' )->limit(5)->offset(29); 41 | is $select->generate, <<_EOC_; 42 | select name, type, label from _columns limit 5 offset 29; 43 | _EOC_ 44 | 45 | $select->reset( qw )->from("users") 46 | ->order_by( foo => 'asc' )->order_by( bar => 'desc' )->limit(0); 47 | is $select->generate, <<_EOC_; 48 | select name from users order by foo asc, bar desc limit 0; 49 | _EOC_ 50 | 51 | $select->reset( qw )->from("users")->op('or') 52 | ->where(foo => 1)->where(bar => 2)->where(baz => 3); 53 | is "$select", <<_EOC_; 54 | select name from users where foo = 1 or bar = 2 or baz = 3; 55 | _EOC_ 56 | 57 | -------------------------------------------------------------------------------- /t/09-sql-update.t: -------------------------------------------------------------------------------- 1 | use lib 'lib'; 2 | use strict; 3 | use warnings; 4 | 5 | use Test::More tests => 6; 6 | BEGIN { use_ok('OpenResty::SQL::Update'); } 7 | 8 | sub _Q { "'$_[0]'" } 9 | 10 | my $update = OpenResty::SQL::Update->new; 11 | $update->update( 'models' ) 12 | ->set( 'abc' => '"howdy"' ); 13 | 14 | is $update->generate, <<_EOC_; 15 | update models 16 | set abc = "howdy"; 17 | _EOC_ 18 | 19 | is "$update", <<_EOC_; 20 | update models 21 | set abc = "howdy"; 22 | _EOC_ 23 | 24 | $update->where("table_name", '=', _Q('blah'))->set(foo => 'bar'); 25 | 26 | is $update->generate, <<_EOC_; 27 | update models 28 | set abc = "howdy", foo = bar 29 | where table_name = 'blah'; 30 | _EOC_ 31 | 32 | $update->where("Foo", '>', 'bar'); 33 | is "$update", <<'_EOC_'; 34 | update models 35 | set abc = "howdy", foo = bar 36 | where table_name = 'blah' and Foo > bar; 37 | _EOC_ 38 | 39 | $update->reset( qw ) 40 | ->set( 'foo' => 3 )->where(name => '"John"'); 41 | is $update->generate, <<_EOC_; 42 | update abc 43 | set foo = 3 44 | where name = "John"; 45 | _EOC_ 46 | 47 | -------------------------------------------------------------------------------- /t/22-version.t: -------------------------------------------------------------------------------- 1 | # vi:filetype= 2 | 3 | use t::OpenResty; 4 | 5 | plan tests => 3 * blocks(); 6 | 7 | run_tests; 8 | 9 | __DATA__ 10 | 11 | === TEST 1: Get the version info 12 | --- request 13 | GET /=/version 14 | --- response_like 15 | ^"\d+\.\d+\.\d+"$ 16 | 17 | 18 | 19 | === TEST 2: Get the version info 20 | --- request 21 | GET /=/version/more 22 | --- response_like 23 | ^"OpenResty \d+\.\d+\.\d+ \(revision (?:Unknown|\d+)\) with the (?:\w+) (?:\([-\w]+\) )?backend\.\\nCopyright \(c\) 2007-2008 by Yahoo! China EEEE Works, Alibaba Inc\.\\n"$ 24 | 25 | 26 | 27 | === TEST 3: Another way 28 | --- request 29 | GET /=/ 30 | --- response_like 31 | ^"\d+\.\d+\.\d+"$ 32 | 33 | 34 | 35 | === TEST 4: Another way using YAML with _callback 36 | --- request 37 | GET /=/version.yml?_callback=foo 38 | --- response_like 39 | ^foo\("--- \d+\.\d+\.\d+"\);$ 40 | 41 | 42 | 43 | === TEST 5: Another way using YAML with _var 44 | --- request 45 | GET /=/version.yml?_var=foo 46 | --- response_like 47 | ^foo="--- \d+\.\d+\.\d+";$ 48 | 49 | -------------------------------------------------------------------------------- /t/25-filter.t: -------------------------------------------------------------------------------- 1 | # vi:filetype= 2 | 3 | my $reason; 4 | BEGIN { 5 | eval { 6 | require OpenResty::Filter::QP; 7 | }; 8 | if ($@) { 9 | $reason = 'Skipped because QP Filter is for internal use only'; 10 | } 11 | } 12 | 13 | use t::OpenResty $reason ? (skip_all => $reason) : (); 14 | 15 | plan tests => 3 * blocks(); 16 | 17 | run_tests; 18 | 19 | __DATA__ 20 | 21 | === TEST 1: Clear the environment 22 | --- request 23 | DELETE /=/model?_user=$TestAccount&_password=$TestPass&_use_cookie=1 24 | --- response 25 | {"success":1} 26 | 27 | 28 | 29 | === TEST 2: Create a model 30 | --- request 31 | POST /=/model/Foo 32 | { 33 | "description":"foo", 34 | "columns": 35 | [ {"name":"text", "type":"text", "label":"Text"} ] 36 | } 37 | --- response 38 | {"success":1} 39 | 40 | 41 | 42 | === TEST 3: Post a sexist's content 43 | --- request 44 | POST /=/model/Foo/~/~ 45 | { "text": "oh, what a fuck!" } 46 | --- response 47 | {"success":0,"error":"QP filter: Sexist not welcomed."} 48 | 49 | 50 | 51 | === TEST 4: logout 52 | --- request 53 | GET /=/logout 54 | --- response 55 | {"success":1} 56 | 57 | -------------------------------------------------------------------------------- /t/27-transaction.t: -------------------------------------------------------------------------------- 1 | # vi:filetype= 2 | 3 | use t::OpenResty; 4 | 5 | plan tests => 3 * blocks(); 6 | 7 | run_tests; 8 | 9 | __DATA__ 10 | 11 | === TEST 1: Login 12 | --- request 13 | GET /=/login/$TestAccount.Admin/$TestPass?_use_cookie=1 14 | --- response_like 15 | ^{"success":1,"session":"[-\w]+","account":"$TestAccount","role":"Admin"}$ 16 | 17 | 18 | 19 | === TEST 2: Delete existing models 20 | --- request 21 | DELETE /=/model 22 | --- response 23 | {"success":1} 24 | 25 | 26 | 27 | === TEST 3: Create a model with various types 28 | --- request 29 | POST /=/model/Foo 30 | { 31 | "description": "transaction testing", 32 | "columns": [ 33 | {"name": "name", "label": "Name", "type": "text"}, 34 | {"name": "age", "label": "Age", "type": "integer"} 35 | ] 36 | } 37 | --- response 38 | {"success":1} 39 | 40 | 41 | 42 | === TEST 4: Insert various records 43 | --- request 44 | POST /=/model/Foo/~/~ 45 | [{"name":"Marry","age":17},{"name":"Bob","age":"invalid"}] 46 | --- response_like 47 | {"success":0,"error": 48 | 49 | 50 | 51 | === TEST 5: Check if the first record has been inserted 52 | --- request 53 | GET /=/model/Foo/~/~ 54 | --- response 55 | [] 56 | 57 | 58 | 59 | === TEST 6: logout 60 | --- request 61 | GET /=/logout 62 | --- response 63 | {"success":1} 64 | 65 | -------------------------------------------------------------------------------- /t/33-duplicate-def.t: -------------------------------------------------------------------------------- 1 | # vi:filetype= 2 | 3 | use t::OpenResty; 4 | 5 | plan tests => 3 * blocks(); 6 | 7 | run_tests; 8 | 9 | __DATA__ 10 | 11 | === TEST 1: Delete existing models 12 | --- request 13 | DELETE /=/model?_user=$TestAccount&_password=$TestPass&_use_cookie=1 14 | --- response 15 | {"success":1} 16 | 17 | 18 | 19 | === TEST 2: Delete existing views 20 | --- request 21 | DELETE /=/view 22 | --- response 23 | {"success":1} 24 | 25 | 26 | 27 | === TEST 3: Create a view 28 | --- request 29 | POST /=/view/Toy 30 | {"definition":"select 12"} 31 | --- response 32 | {"success":1} 33 | 34 | 35 | 36 | === TEST 4: Create an identical view but with a different name 37 | --- request 38 | POST /=/view/Toy2 39 | {"definition":"select 12"} 40 | --- response 41 | {"success":1} 42 | 43 | -------------------------------------------------------------------------------- /t/34-unique.t: -------------------------------------------------------------------------------- 1 | # vi:filetype= 2 | 3 | use t::OpenResty; 4 | 5 | plan tests => 3 * (blocks() - 1); 6 | 7 | run_tests; 8 | 9 | __DATA__ 10 | 11 | === TEST 1: Delete existing models 12 | --- request 13 | DELETE /=/model?_user=$TestAccount&_password=$TestPass&_use_cookie=1 14 | --- response 15 | {"success":1} 16 | 17 | 18 | 19 | === TEST 2: Create a model 20 | --- request 21 | POST /=/model/Post 22 | {"description":"Post", 23 | "columns":[{"name":"name","label":"Name","type":"text","unique":true}, 24 | {"name":"age","label":"Age","type":"integer","unique":false}] 25 | } 26 | --- response 27 | {"success":1} 28 | 29 | 30 | 31 | === TEST 3: Insert 2 records with the same name 32 | --- debug: 1 33 | --- request 34 | POST /=/model/Post/~/~ 35 | [ 36 | {"name":"agentzh","age":23}, 37 | {"name":"agentzh","age":34} 38 | ] 39 | --- response_like 40 | duplicate key (?:value )?violates unique constraint \\"Post_name_key\\" 41 | 42 | 43 | 44 | === TEST 4: Insert 2 records with the same name 45 | --- debug: 0 46 | --- request 47 | POST /=/model/Post 48 | [ 49 | {"name":"agentzh","age":23}, 50 | {"name":"agentzh","age":34} 51 | ] 52 | --- response 53 | {"success":0,"error":"Operation failed."} 54 | 55 | 56 | 57 | === TEST 5: Insert 2 records with the same name 58 | --- debug: 1 59 | --- request 60 | POST /=/model/Post/~/~ 61 | [ 62 | {"name":"agentzh","age":23}, 63 | {"name":"yuting","age":23} 64 | ] 65 | --- response 66 | {"last_row":"/=/model/Post/id/4","rows_affected":2,"success":1} 67 | 68 | 69 | 70 | === TEST 6: Modify the uniqueness 71 | XXX TODO... 72 | --- request 73 | PUT /=/model/Post/age 74 | {"unique":true} 75 | --- response 76 | {"error":"Updating column's uniqueness is not implemented yet.","success":0} 77 | --- SKIP 78 | 79 | 80 | 81 | === TEST 7: logout 82 | --- request 83 | GET /=/logout 84 | --- response 85 | {"success":1} 86 | 87 | -------------------------------------------------------------------------------- /t/38-global-search.t: -------------------------------------------------------------------------------- 1 | # vi:filetype= 2 | 3 | use t::OpenResty; 4 | 5 | plan tests => 3 * blocks(); 6 | 7 | run_tests; 8 | 9 | __DATA__ 10 | 11 | === TEST 1: Delete existing models 12 | --- request 13 | DELETE /=/model.js?_user=$TestAccount&_password=$TestPass&_use_cookie=1 14 | --- response 15 | {"success":1} 16 | 17 | 18 | 19 | === TEST 2: Create a new model 20 | --- request 21 | POST /=/model/Post 22 | { "description":"Post", 23 | "columns": 24 | [ 25 | { "name": "Title", "type":"text", "label": "Title" }, 26 | { "name": "Created", "type":"timestamp (0) without time zone", "label": "Created" } 27 | ] 28 | } 29 | --- response 30 | {"success":1} 31 | 32 | 33 | 34 | === TEST 3: Insert some records 35 | --- request 36 | POST /=/model/Post/~/~ 37 | [ 38 | {"Title":"Google你好","Created":"2008-08-09 15:36:00"}, 39 | {"Title":"Yahoo你好","Created":"2008-08-10 22:37:00"} 40 | ] 41 | --- response 42 | {"last_row":"/=/model/Post/id/2","rows_affected":2,"success":1} 43 | 44 | 45 | 46 | === TEST 4: Search in all columns 47 | --- request 48 | GET /=/model/Post/~/你好?_op=contains 49 | --- response 50 | [{"Created":"2008-08-09 15:36:00","Title":"Google你好","id":"1"},{"Created":"2008-08-10 22:37:00","Title":"Yahoo你好","id":"2"}] 51 | 52 | 53 | 54 | === TEST 5: Search timestamp 55 | --- request 56 | GET /=/model/Post/~/2008-08-10?_op=contains 57 | --- response 58 | [{"Created":"2008-08-10 22:37:00","id":"2","Title":"Yahoo你好"}] 59 | 60 | -------------------------------------------------------------------------------- /t/39-model-col-bug.t: -------------------------------------------------------------------------------- 1 | # vi:filetype= 2 | 3 | use t::OpenResty; 4 | 5 | plan tests => 3 * blocks(); 6 | 7 | run_tests; 8 | 9 | __DATA__ 10 | 11 | === TEST 1: Delete existing models 12 | --- request 13 | DELETE /=/model.js?_user=$TestAccount&_password=$TestPass&_use_cookie=1 14 | --- response 15 | {"success":1} 16 | 17 | 18 | 19 | === TEST 2: Create a new model 20 | --- request 21 | POST /=/model/Post 22 | { "description":"Post" } 23 | --- response 24 | {"success":1,"warning":"No 'columns' specified for model \"Post\"."} 25 | 26 | 27 | 28 | === TEST 3: Add a serial column 29 | --- request 30 | POST /=/model/Post/~ 31 | {"name":"id2","type":"serial","label":"id2"} 32 | --- response 33 | {"src":"/=/model/Post/id2","success":1} 34 | 35 | 36 | 37 | === TEST 4: Add a new column with space in it 38 | --- request 39 | POST /=/model/Post/~ 40 | {"name":"q a","type":"text","label":"Q & A"} 41 | --- response 42 | {"success":0,"error":"Bad value for \"name\": Identifier expected."} 43 | 44 | 45 | 46 | === TEST 5: logout 47 | --- request 48 | GET /=/logout 49 | --- response 50 | {"success":1} 51 | 52 | -------------------------------------------------------------------------------- /t/41-action-proxy.t: -------------------------------------------------------------------------------- 1 | # vi:filetype= 2 | 3 | use strict; 4 | use warnings; 5 | 6 | #use OpenResty; 7 | #use OpenResty::Config; 8 | my $ExePath; 9 | my $skip; 10 | use t::OpenResty; 11 | BEGIN { 12 | OpenResty::Config->init; 13 | my $allowed = $OpenResty::AllowForwarding{$t::OpenResty::user}; 14 | if (!$allowed) { 15 | $skip = "$t::OpenResty::user not allowed for open HTTP forwarding"; 16 | } 17 | use FindBin; 18 | $ExePath = "$FindBin::Bin/../haskell/bin/restyscript"; 19 | if (!-f $ExePath) { 20 | $skip = "$ExePath is not found"; 21 | return; 22 | } 23 | if (!-x $ExePath) { 24 | $skip = "$ExePath is not an executable"; 25 | return; 26 | } 27 | }; 28 | 29 | use t::OpenResty $skip ? (skip_all => $skip) : (); 30 | 31 | plan tests => 3 * blocks(); 32 | 33 | run_tests; 34 | 35 | __DATA__ 36 | 37 | === TEST 1: Delete existing actions 38 | --- request 39 | DELETE /=/action?_user=$TestAccount&_password=$TestPass&_use_cookie=1 40 | --- response 41 | {"success":1,"warning":"Builtin actions were skipped."} 42 | 43 | 44 | 45 | === TEST 2: Relay a cross-site request 46 | --- request 47 | POST /=/action/Test 48 | { "definition": "GET 'http://api.openresty.org/=/version'" } 49 | --- response 50 | {"success":1} 51 | 52 | 53 | 54 | === TEST 3: Invoke it 55 | --- request 56 | GET /=/action/Test/~/~ 57 | --- response_like 58 | ^\["\d+\.\d+\.\d+"\]$ 59 | 60 | -------------------------------------------------------------------------------- /t/43-view-bug.t: -------------------------------------------------------------------------------- 1 | # vi:filetype= 2 | 3 | use t::OpenResty; 4 | 5 | plan tests => 3 * blocks(); 6 | 7 | run_tests; 8 | 9 | __DATA__ 10 | 11 | === TEST 1: Delete existing models 12 | --- request 13 | DELETE /=/model?_user=$TestAccount&_password=$TestPass&_use_cookie=1 14 | --- response 15 | {"success":1} 16 | 17 | 18 | 19 | === TEST 2: Delete existing views 20 | --- request 21 | DELETE /=/view 22 | --- response 23 | {"success":1} 24 | 25 | 26 | 27 | === TEST 3: Check the view list 28 | --- request 29 | GET /=/view 30 | --- response 31 | [] 32 | 33 | 34 | 35 | === TEST 4: Create model A 36 | --- request 37 | POST /=/model/A 38 | { "description": "A", 39 | "columns": [{ "name": "title", "type":"text", "label": "title" }] 40 | } 41 | --- response 42 | {"success":1} 43 | 44 | 45 | 46 | === TEST 5: Create model B 47 | --- request 48 | POST /=/model/B 49 | { "description": "B", 50 | "columns": [ 51 | {"name":"body","type":"text", "label":"body"}, 52 | {"name":"a","type":"integer","label":"a"} 53 | ] 54 | } 55 | --- response 56 | {"success":1} 57 | 58 | 59 | 60 | === TEST 6: Create the view 61 | --- request 62 | POST /=/view/View 63 | { "definition": "select * from A, B where A.id = B.a order by A.title" } 64 | --- response 65 | {"success":1} 66 | 67 | 68 | 69 | === TEST 7: Create the view with duplicate name 70 | --- request 71 | POST /=/view/View 72 | { "definition": "select * from A, B where A.id = B.a order by A.title" } 73 | --- response 74 | {"success":0,"error":"View \"View\" already exists."} 75 | 76 | 77 | 78 | === TEST 8: Create the view with duplicate definition 79 | --- request 80 | POST /=/view/View1 81 | { "definition": "select * from A, B where A.id = B.a order by A.title" } 82 | --- response 83 | {"success":1} 84 | 85 | 86 | 87 | === TEST 9: logout 88 | --- request 89 | GET /=/logout 90 | --- response 91 | {"success":1} 92 | 93 | -------------------------------------------------------------------------------- /t/49-view-builtin-vars.t: -------------------------------------------------------------------------------- 1 | # vi:filetype= 2 | 3 | use t::OpenResty; 4 | 5 | plan tests => 3 * blocks(); 6 | 7 | run_tests; 8 | 9 | __DATA__ 10 | 11 | === TEST 1: Delete existing views 12 | --- request 13 | DELETE /=/view?_user=$TestAccount&_password=$TestPass&_use_cookie=1 14 | --- response 15 | {"success":1} 16 | 17 | 18 | 19 | === TEST 2: Create a view with builtin vars 20 | --- request 21 | POST /=/view/Foo 22 | { "description": "test builtin vars", "definition":"select $_ACCOUNT as account, $_ROLE as role;" } 23 | --- response 24 | {"success":1} 25 | 26 | 27 | 28 | === TEST 3: Invoke the view with explicit variable binding 29 | --- request 30 | GET /=/view/Foo/_ACCOUNT/32?_ROLE=56 31 | --- response 32 | [{"account":"tester","role":"Admin"}] 33 | 34 | 35 | 36 | === TEST 4: Invoke the view w/o binding 37 | --- request 38 | GET /=/view/Foo/~/~ 39 | --- response 40 | [{"account":"tester","role":"Admin"}] 41 | 42 | -------------------------------------------------------------------------------- /t/50-action-builtin-vars.t: -------------------------------------------------------------------------------- 1 | # vi:filetype= 2 | 3 | my $ExePath; 4 | BEGIN { 5 | use FindBin; 6 | $ExePath = "$FindBin::Bin/../haskell/bin/restyscript"; 7 | if (!-f $ExePath) { 8 | $skip = "$ExePath is not found.\n"; 9 | return; 10 | } 11 | if (!-x $ExePath) { 12 | $skip = "$ExePath is not an executable.\n"; 13 | return; 14 | } 15 | }; 16 | use t::OpenResty $skip ? (skip_all => $skip) : (); 17 | 18 | plan tests => 3 * blocks(); 19 | 20 | run_tests; 21 | 22 | __DATA__ 23 | 24 | === TEST 1: Delete existing actions 25 | --- request 26 | DELETE /=/action?_user=$TestAccount&_password=$TestPass&_use_cookie=1 27 | --- response 28 | {"success":1,"warning":"Builtin actions were skipped."} 29 | 30 | 31 | 32 | === TEST 2: Create an action with builtin vars 33 | --- request 34 | POST /=/action/Foo 35 | { "description": "test builtin vars", 36 | "definition": "select $_ACCOUNT as account, $_ROLE as role;" } 37 | --- response 38 | {"success":1} 39 | 40 | 41 | 42 | === TEST 3: Invoke the action with explicit variable binding 43 | --- request 44 | GET /=/action/Foo/_ACCOUNT/32?_ROLE=56 45 | --- response 46 | [[{"account":"tester","role":"Admin"}]] 47 | 48 | 49 | 50 | === TEST 4: Invoke the action w/o binding 51 | --- request 52 | GET /=/action/Foo/~/~ 53 | --- response 54 | [[{"account":"tester","role":"Admin"}]] 55 | 56 | 57 | 58 | === TEST 5: Create an action with non-recognized builtin vars 59 | --- request 60 | POST /=/action/Bar 61 | { "description": "test builtin vars", 62 | "definition": "select $_blah as account, $_foo as role;" } 63 | --- response 64 | {"success":0,"error":"Unknown built-in parameter: _blah"} 65 | 66 | -------------------------------------------------------------------------------- /t/53_compiled_actions.t: -------------------------------------------------------------------------------- 1 | # vi:filetype= 2 | 3 | use t::OpenResty ($ENV{USER} && $ENV{USER} ne 'xunxin') ? (skip_all => 'xunxin only') : (); 4 | 5 | =pod 6 | 7 | This test file test a bug such as DELETE /=/model/xxx/xxx?op=contains 8 | 9 | TODO 10 | * many... 11 | 12 | =cut 13 | 14 | plan tests => 3 * blocks(); 15 | 16 | run_tests; 17 | 18 | __DATA__ 19 | 20 | === TEST 1: Login 21 | --- request 22 | GET /=/login/taobao_vip.Admin/$TestPass?_use_cookie=1 23 | --- response_like 24 | ^{"success":1,"session":"[-\w]+","account":"taobao_vip","role":"Admin"}$ 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /t/57-encoded-slashes.t: -------------------------------------------------------------------------------- 1 | # vi:filetype= 2 | 3 | use t::OpenResty; 4 | 5 | plan tests => 3 * blocks(); 6 | 7 | run_tests; 8 | 9 | __DATA__ 10 | 11 | === TEST 1: Login 12 | --- request 13 | GET /=/login/$TestAccount.Admin/$TestPass?_use_cookie=1 14 | --- response_like 15 | ^{"success":1,"session":"[-\w]+","account":"$TestAccount","role":"Admin"}$ 16 | 17 | 18 | 19 | === TEST 2: Delete model a/b 20 | --- request 21 | DELETE /=/model/a%2Fb 22 | --- response 23 | {"success":0,"error":"Bad model name: \"a/b\""} 24 | 25 | -------------------------------------------------------------------------------- /t/99-pod-coverage.t: -------------------------------------------------------------------------------- 1 | use Test::More; 2 | 3 | # XXX we need more POD... 4 | my $skip_all = 1; 5 | eval "use Test::Pod::Coverage"; 6 | plan skip_all => "We know we don't have enough POD :(" if $skip_all; 7 | plan skip_all => "Test::Pod::Coverage required for testing POD coverage" if $@; 8 | all_pod_coverage_ok(); 9 | 10 | -------------------------------------------------------------------------------- /t/99-pod.t: -------------------------------------------------------------------------------- 1 | use strict; 2 | use Test::More; 3 | eval "use Test::Pod 1.00"; 4 | plan skip_all => "Test::Pod 1.00 required for testing POD" if $@; 5 | all_pod_files_ok(); 6 | 7 | -------------------------------------------------------------------------------- /t/OpenResty/Util.pm: -------------------------------------------------------------------------------- 1 | package t::OpenResty::Util; 2 | 3 | # this file contains util that can't be in t::openresty, because 4 | # spiffy is polluting the args passed in for some unknown reasons 5 | 6 | sub ensure_test_user { 7 | my ($user, $password) = @_; 8 | if ($OpenResty::Config{'backend.type'} eq 'PgMocked' || 9 | $OpenResty::Config{'test_suite.use_http'}) { 10 | return; 11 | } 12 | local $SIG{__WARN__} = sub { } 13 | unless $ENV{TEST_VERBOSE}; 14 | unless ($ENV{OPENRESTY_TEST_SERVER}) { 15 | my $backend = $OpenResty::Backend; 16 | if ( $backend->has_user($user) ) { 17 | $backend->drop_user($user); 18 | } 19 | $backend->add_user($user, $password); 20 | $backend->has_user($user) 21 | or Test::More::BAIL_OUT('Can not create test user'); 22 | } 23 | } 24 | 25 | 1; 26 | -------------------------------------------------------------------------------- /t/TODO: -------------------------------------------------------------------------------- 1 | Coverage testing TODOs: 2 | 3 | 4 | Old TODOs: 5 | * PUT an empty hash to model rows? 6 | * values in the url takes priority over the values in the data? or the other way around? TODO... 7 | * add column hits limit. 8 | * /=/model.json?var=foo 9 | * t/p3p-cookie.t for cross-site cookie support and the cookie_site url param 10 | * view description should be mandatory 11 | * [bug] when view name is duplicate (POST/PUT) 12 | * [bug] when view definition is duplicate (POST/PUT) 13 | * [bug] reject updating the names of the builtin roles. 14 | * add the sorting capability (i.e. the order_by url param) to model/view/role lists 15 | * [bug] PUT an empty label. 16 | * [bug] PUT /=/role/Foo/id/32 does not work as expected. 17 | * order in ACL rule listing 18 | 19 | * model columns' default values contain UTF-8 chars. 20 | * action definition contains UTF-8 chars. 21 | * insert rows - POST an empty list? 22 | * not_null 23 | 24 | -------------------------------------------------------------------------------- /t/col-not-null/01.t: -------------------------------------------------------------------------------- 1 | # vi:filetype= 2 | #添加不带not_null属性的列 3 | use t::OpenResty; 4 | 5 | plan tests => 3 * blocks(); 6 | 7 | run_tests; 8 | 9 | __DATA__ 10 | 11 | === TEST 1: Delete existing models 12 | --- request 13 | DELETE /=/model?_user=$TestAccount&_password=$TestPass&_use_cookie=1 14 | --- response 15 | {"success":1} 16 | 17 | 18 | 19 | === TEST 2: create a new model 20 | --- request 21 | POST /=/model/account 22 | { "description": "test model","columns": [{ "name":"A","type":"text","label":"a" }]} 23 | --- response 24 | {"success":1} 25 | 26 | 27 | 28 | === TEST 3: Add a new column 29 | --- request 30 | POST /=/model/account/B 31 | {"type":"integer","label":"b"} 32 | --- response 33 | {"success":1,"src":"/=/model/account/B"} 34 | 35 | 36 | 37 | === TEST 4: Check the new column 38 | --- request 39 | GET /=/model/account/B 40 | --- response 41 | {"name":"B","default":null,"label":"b","type":"integer","not_null":false,"unique":false} 42 | 43 | 44 | 45 | === TEST 5: Insert a record 46 | --- request 47 | POST /=/model/account/~/~ 48 | { "A": "jingjing1"} 49 | --- response 50 | {"success":1,"rows_affected":1,"last_row":"/=/model/account/id/1"} 51 | -------------------------------------------------------------------------------- /t/col-not-null/02.t: -------------------------------------------------------------------------------- 1 | # vi:filetype= 2 | #添加not_null属性为false的列 3 | use t::OpenResty; 4 | 5 | plan tests => 3 * blocks(); 6 | 7 | run_tests; 8 | 9 | __DATA__ 10 | 11 | === TEST 1: Delete existing models 12 | --- request 13 | DELETE /=/model?_user=$TestAccount&_password=$TestPass&_use_cookie=1 14 | --- response 15 | {"success":1} 16 | 17 | 18 | 19 | === TEST 2: create a new model 20 | --- request 21 | POST /=/model/account 22 | { "description": "test model","columns": [{ "name":"A","type":"text","label":"a" }]} 23 | --- response 24 | {"success":1} 25 | 26 | 27 | 28 | === TEST 3: Add a new column not null is false 29 | --- request 30 | POST /=/model/account/C 31 | {"type":"integer","label":"c","not_null":false} 32 | --- response 33 | {"success":1,"src":"/=/model/account/C"} 34 | 35 | 36 | 37 | === TEST 4: Check the new column C 38 | --- request 39 | GET /=/model/account/C 40 | --- response 41 | {"name":"C","default":null,"label":"c","type":"integer","not_null":false,"unique":false} 42 | 43 | 44 | 45 | === TEST 5: Insert a record 46 | --- request 47 | POST /=/model/account/~/~ 48 | { "A": "jingjing2"} 49 | --- response 50 | {"success":1,"rows_affected":1,"last_row":"/=/model/account/id/1"} 51 | 52 | -------------------------------------------------------------------------------- /t/col-not-null/03.t: -------------------------------------------------------------------------------- 1 | # vi:filetype= 2 | #添加not_null属性为true的列 3 | use t::OpenResty; 4 | 5 | plan tests => 3 * blocks(); 6 | 7 | run_tests; 8 | 9 | __DATA__ 10 | 11 | === TEST 1: Delete existing models 12 | --- request 13 | DELETE /=/model?_user=$TestAccount&_password=$TestPass&_use_cookie=1 14 | --- response 15 | {"success":1} 16 | 17 | 18 | 19 | === TEST 2: create a new model 20 | --- request 21 | POST /=/model/account 22 | { "description": "test model","columns": [{ "name":"A","type":"text","label":"a" }]} 23 | --- response 24 | {"success":1} 25 | 26 | 27 | 28 | === TEST 3: Add a new column not null is true 29 | --- request 30 | POST /=/model/account/D 31 | {"type":"integer","label":"d","not_null":true, "unique":false} 32 | --- response 33 | {"success":1,"src":"/=/model/account/D"} 34 | 35 | 36 | 37 | === TEST 4: Check the new column D 38 | --- request 39 | GET /=/model/account/D 40 | --- response 41 | {"name":"D","default":null,"label":"d","type":"integer","not_null":true,"unique":false} 42 | 43 | 44 | 45 | === TEST 5: Insert a record with value of D is null 46 | --- request 47 | POST /=/model/account/~/~ 48 | { "A": "jingjing3"} 49 | --- response 50 | {"success":0,"error":"null value in column \"D\" violates not-null constraint"} 51 | 52 | 53 | 54 | === TEST 6: Insert a record with value of D is not null 55 | --- request 56 | POST /=/model/account/~/~ 57 | { "A": "jingjing3","D":"1"} 58 | --- response 59 | {"success":1,"rows_affected":1,"last_row":"/=/model/account/id/2"} 60 | 61 | -------------------------------------------------------------------------------- /t/col-not-null/04.t: -------------------------------------------------------------------------------- 1 | # vi:filetype= 2 | # 0不会被认为是null 3 | use t::OpenResty; 4 | 5 | plan tests => 3 * blocks(); 6 | 7 | run_tests; 8 | 9 | __DATA__ 10 | 11 | === TEST 1: Delete existing models 12 | --- request 13 | DELETE /=/model?_user=$TestAccount&_password=$TestPass&_use_cookie=1 14 | --- response 15 | {"success":1} 16 | 17 | 18 | 19 | === TEST 2: create a new model 20 | --- request 21 | POST /=/model/account 22 | { "description": "test model","columns": [{ "name":"A","type":"text","label":"a" }]} 23 | --- response 24 | {"success":1} 25 | 26 | 27 | 28 | === TEST 3: Add a new column not null is true 29 | --- request 30 | POST /=/model/account/D 31 | {"type":"integer","label":"d","not_null":true} 32 | --- response 33 | {"success":1,"src":"/=/model/account/D"} 34 | 35 | 36 | 37 | === TEST 4: Check the new column D 38 | --- request 39 | GET /=/model/account/D 40 | --- response 41 | {"name":"D","default":null,"label":"d","type":"integer","not_null":true,"unique":false} 42 | 43 | 44 | 45 | === TEST 5: Insert a record with value of D is null 46 | --- request 47 | POST /=/model/account/~/~ 48 | { "A": "jingjing3"} 49 | --- response 50 | {"success":0,"error":"null value in column \"D\" violates not-null constraint"} 51 | 52 | 53 | 54 | === TEST 6: Insert a record with value of D is not null 55 | --- request 56 | POST /=/model/account/~/~ 57 | { "A": "jingjing3","D":"1"} 58 | --- response 59 | {"success":1,"rows_affected":1,"last_row":"/=/model/account/id/2"} 60 | 61 | 62 | 63 | === TEST 7: Insert a record with value of D is 0 64 | --- request 65 | POST /=/model/account/~/~ 66 | { "A": "jingjing3","D":"0"} 67 | --- response 68 | {"success":1,"rows_affected":1,"last_row":"/=/model/account/id/3"} 69 | 70 | 71 | -------------------------------------------------------------------------------- /t/col-not-null/07.t: -------------------------------------------------------------------------------- 1 | # vi:filetype= 2 | # ""不会被认为是null 3 | use t::OpenResty; 4 | 5 | plan tests => 3 * blocks(); 6 | 7 | run_tests; 8 | 9 | __DATA__ 10 | 11 | === TEST 1: Delete existing models 12 | --- request 13 | DELETE /=/model?_user=$TestAccount&_password=$TestPass&_use_cookie=1 14 | --- response 15 | {"success":1} 16 | 17 | 18 | 19 | === TEST 2: create a new model 20 | --- request 21 | POST /=/model/account 22 | { "description": "test model","columns": [{ "name":"A","type":"text","label":"a" }]} 23 | --- response 24 | {"success":1} 25 | 26 | 27 | 28 | === TEST 3: Add a new column not null is true 29 | --- request 30 | POST /=/model/account/D 31 | {"type":"text","label":"d","not_null":true} 32 | --- response 33 | {"success":1,"src":"/=/model/account/D"} 34 | 35 | 36 | 37 | === TEST 4: Check the new column D 38 | --- request 39 | GET /=/model/account/D 40 | --- response 41 | {"name":"D","default":null,"label":"d","type":"text","not_null":true,"unique":false} 42 | 43 | 44 | 45 | === TEST 5: Insert a record with value of D is null 46 | --- request 47 | POST /=/model/account/~/~ 48 | { "A": "jingjing3"} 49 | --- response 50 | {"success":0,"error":"null value in column \"D\" violates not-null constraint"} 51 | 52 | 53 | 54 | === TEST 6: Insert a record with value of D is not null 55 | --- request 56 | POST /=/model/account/~/~ 57 | { "A": "jingjing3","D":"1"} 58 | --- response 59 | {"success":1,"rows_affected":1,"last_row":"/=/model/account/id/2"} 60 | 61 | 62 | 63 | === TEST 7: Insert a record with value of D is "" 64 | --- request 65 | POST /=/model/account/~/~ 66 | { "A": "jingjing3", "D": ""} 67 | --- response 68 | {"success":1,"rows_affected":1,"last_row":"/=/model/account/id/3"} 69 | 70 | 71 | -------------------------------------------------------------------------------- /t/col-references/01.t_: -------------------------------------------------------------------------------- 1 | # vi:filetype= 2 | 3 | #创建1列,其References指向一个不存在的model 4 | 5 | use t::OpenResty; 6 | 7 | plan tests => 3 * blocks(); 8 | 9 | run_tests; 10 | 11 | __DATA__ 12 | 13 | === TEST 1: Delete existing models 14 | --- request 15 | DELETE /=/model?_user=$TestAccount&_password=$TestPass&_use_cookie=1 16 | --- response 17 | {"success":1} 18 | 19 | 20 | 21 | === TEST 2: create a model 22 | --- request 23 | POST /=/model/testreferences 24 | {"description": "test references path01","columns": [{ "name":"jx01","type":"text","label":"jx01","references":{"model": "referencesmodel"}}]} 25 | --- response 26 | {"success":0,"error":"model \"referencesmodel\" is not exists!"} -------------------------------------------------------------------------------- /t/col-references/02.t_: -------------------------------------------------------------------------------- 1 | # vi:filetype= 2 | 3 | #创建1列,其References指向一个存在的model中不存在的列 4 | 5 | use t::OpenResty; 6 | 7 | plan tests => 3 * blocks(); 8 | 9 | run_tests; 10 | 11 | __DATA__ 12 | 13 | === TEST 1: Delete existing models 14 | --- request 15 | DELETE /=/model?_user=$TestAccount&_password=$TestPass&_use_cookie=1 16 | --- response 17 | {"success":1} 18 | 19 | 20 | 21 | === TEST 2: create a model(referencesmodel) 22 | --- request 23 | POST /=/model/referencesmodel 24 | {"description": "referencesmodel","columns": [{ "name":"referencesid","type":"integer","label":"referencesid"}]} 25 | --- response 26 | {"success":1} 27 | 28 | 29 | 30 | === TEST 3: check the model 31 | --- request 32 | GET /=/model/ 33 | --- response 34 | [{"description": "referencesmodel","name": "referencesmodel","src":"/=/model/referencesmodel"}] 35 | 36 | 37 | 38 | === TEST 4: check the column 39 | --- request 40 | GET /=/model/referencesmodel/referencesid 41 | --- response 42 | {"name":"referencesid","default":null,"label":"referencesid","type":"integer"} 43 | 44 | 45 | 46 | === TEST 5: create a model 47 | --- request 48 | POST /=/model/testreferences 49 | {"description": "test references path02","columns": [{ "name":"jx02","type":"integer","label":"jx02","references":{"model": "referencesmodel","column":"id"}}]} 50 | --- response 51 | {"success":0,"error":"column \"id\" is not exists!"} -------------------------------------------------------------------------------- /t/col-references/03.t_: -------------------------------------------------------------------------------- 1 | # vi:filetype= 2 | 3 | #创建1列,其References指向一个存在的model中属性值不匹配的列 4 | 5 | use t::OpenResty; 6 | 7 | plan tests => 3 * blocks(); 8 | 9 | run_tests; 10 | 11 | __DATA__ 12 | 13 | === TEST 1: Delete existing models 14 | --- request 15 | DELETE /=/model?_user=$TestAccount&_password=$TestPass&_use_cookie=1 16 | --- response 17 | {"success":1} 18 | 19 | 20 | 21 | === TEST 2: create a model(referencesmodel) 22 | --- request 23 | POST /=/model/referencesmodel 24 | {"description": "referencesmodel","columns": [{ "name":"referencesid","type":"integer","label":"referencesid"}]} 25 | --- response 26 | {"success":1} 27 | 28 | 29 | 30 | === TEST 3: check the model 31 | --- request 32 | GET /=/model/ 33 | --- response 34 | [{"description": "referencesmodel","name": "referencesmodel","src":"/=/model/referencesmodel"}] 35 | 36 | 37 | 38 | === TEST 4: check the column 39 | --- request 40 | GET /=/model/referencesmodel/referencesid 41 | --- response 42 | {"name":"referencesid","default":null,"label":"referencesid","type":"integer"} 43 | 44 | 45 | 46 | === TEST 5: create a model 47 | --- request 48 | POST /=/model/testreferences 49 | {"description": "test references path03","columns": [{ "name":"jx03","type":"text","label":"jx03","references":{"model": "referencesmodel","column":"referencesid"}}]} 50 | --- response 51 | {"success":0,"error":"the type of \"jx03\" is not match of references \"referencesid\"!"} -------------------------------------------------------------------------------- /t/col-unique/01.t: -------------------------------------------------------------------------------- 1 | # vi:filetype= 2 | 3 | #创建不带 unique 属性的列,验证插入两行有相同值的行没有报错 4 | 5 | use t::OpenResty; 6 | 7 | plan tests => 3 * blocks(); 8 | 9 | run_tests; 10 | 11 | __DATA__ 12 | 13 | === TEST 1: Delete existing models 14 | --- request 15 | DELETE /=/model?_user=$TestAccount&_password=$TestPass&_use_cookie=1 16 | --- response 17 | {"success":1} 18 | 19 | 20 | 21 | === TEST 2: create a model(column without unique attribute) 22 | --- request 23 | POST /=/model/testunique 24 | { "description": "test unique path01","columns": [{ "name":"jx01","type":"text","label":"jx01"}]} 25 | --- response 26 | {"success":1} 27 | 28 | 29 | 30 | === TEST 3: check the model 31 | --- request 32 | GET /=/model/ 33 | --- response 34 | [{"description": "test unique path01","name": "testunique","src":"/=/model/testunique"}] 35 | 36 | 37 | 38 | === TEST 4: check the column 39 | --- request 40 | GET /=/model/testunique/jx01 41 | --- response 42 | {"name":"jx01","default":null,"label":"jx01","type":"text","unique":false,"not_null":false} 43 | 44 | 45 | 46 | === TEST 5: Insert one record 47 | --- request 48 | POST /=/model/testunique/~/~ 49 | {"jx01": "A01"} 50 | --- response 51 | {"success":1,"rows_affected":1,"last_row":"/=/model/testunique/id/1"} 52 | 53 | 54 | 55 | === TEST 6: Get all records(1 record) 56 | --- request 57 | GET /=/model/testunique/~/~ 58 | --- response 59 | [{"id":"1","jx01":"A01"}] 60 | 61 | 62 | 63 | === TEST 7: Insert the same record 64 | --- request 65 | POST /=/model/testunique/~/~ 66 | { "jx01": "A01"} 67 | --- response 68 | {"success":1,"rows_affected":1,"last_row":"/=/model/testunique/id/2"} 69 | 70 | 71 | 72 | === TEST 8: Get all records(2 records) 73 | --- request 74 | GET /=/model/testunique/~/~ 75 | --- response 76 | [{"id":"1","jx01":"A01"},{"id":"2","jx01":"A01"}] 77 | 78 | -------------------------------------------------------------------------------- /t/col-unique/02.t: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agentzh/old-openresty/53dad17e84dc6d2a0dffddb119851c50c0ca3a8d/t/col-unique/02.t -------------------------------------------------------------------------------- /t/col-unique/03.t: -------------------------------------------------------------------------------- 1 | # vi:filetype= 2 | 3 | #创建 unique 属性为 true 的列,验证插入两行带相同值的行会报"Unique constraint violated."的错误 4 | 5 | use t::OpenResty; 6 | 7 | plan tests => 3 * blocks(); 8 | 9 | run_tests; 10 | 11 | __DATA__ 12 | 13 | === TEST 1: Delete existing models 14 | --- request 15 | DELETE /=/model?_user=$TestAccount&_password=$TestPass&_use_cookie=1 16 | --- response 17 | {"success":1} 18 | 19 | 20 | 21 | === TEST 2: create a model(column with unique attribute is true) 22 | --- request 23 | POST /=/model/testunique 24 | { "description": "test unique path03","columns": [{ "name":"jx03","type":"text","label":"jx03","unique":true}]} 25 | --- response 26 | {"success":1} 27 | 28 | 29 | 30 | === TEST 3: check the model 31 | --- request 32 | GET /=/model/ 33 | --- response 34 | [{"description": "test unique path03","name": "testunique","src":"/=/model/testunique"}] 35 | 36 | 37 | 38 | === TEST 4: check the column 39 | --- request 40 | GET /=/model/testunique/jx03 41 | --- response 42 | {"name":"jx03","default":null,"label":"jx03","type":"text","unique":true,"not_null":false} 43 | 44 | 45 | 46 | === TEST 5: Insert one record 47 | --- request 48 | POST /=/model/testunique/~/~ 49 | {"jx03": "A03"} 50 | --- response 51 | {"success":1,"rows_affected":1,"last_row":"/=/model/testunique/id/1"} 52 | 53 | 54 | 55 | === TEST 6: Get all records(1 record) 56 | --- request 57 | GET /=/model/testunique/~/~ 58 | --- response 59 | [{"id":"1","jx03":"A03"}] 60 | 61 | 62 | 63 | === TEST 7: Insert the same record 64 | --- request 65 | POST /=/model/testunique/~/~ 66 | { "jx03": "A03"} 67 | --- response 68 | {"error":"duplicate key value violates unique constraint \"testunique_jx03_key\"","success":0} 69 | 70 | 71 | === TEST 8: Get all records(1 records) 72 | --- request 73 | GET /=/model/testunique/~/~ 74 | --- response 75 | [{"id":"1","jx03":"A03"}] 76 | -------------------------------------------------------------------------------- /t/pgmock-data/00-prereq.t.json: -------------------------------------------------------------------------------- 1 | ["set search_path to _global,public","0E0","data"] 2 | ["select count(*) from pg_tables where tablename = '_general' and schemaname = '_global'",[["1"]],"data"] 3 | ["select version from _global._general limit 1",[["0.009"]],"data"] 4 | ["set lc_messages to \"C\";","0E0","data"] 5 | ["select nspname from pg_namespace where nspname = 'tester' limit 1;\n",1,"data"] 6 | ["set search_path to tester,public","0E0","data"] 7 | [" select id from _roles where name = 'Admin' and password = '5f4dcc3b5aa765d61d8327deb882cf99' limit 1; ",[["1"]],"data"] 8 | -------------------------------------------------------------------------------- /t/pgmock-data/06-charset.t.json: -------------------------------------------------------------------------------- 1 | ["set search_path to _global,public","0E0","data"] 2 | ["select count(*) from pg_tables where tablename = '_general' and schemaname = '_global'",[["1"]],"data"] 3 | ["select version from _global._general limit 1",[["0.009"]],"data"] 4 | ["set lc_messages to \"C\";","0E0","data"] 5 | -------------------------------------------------------------------------------- /t/pgmock-data/07-bug.t.json: -------------------------------------------------------------------------------- 1 | ["set search_path to _global,public","0E0","data"] 2 | ["select count(*) from pg_tables where tablename = '_general' and schemaname = '_global'",[["1"]],"data"] 3 | ["select version from _global._general limit 1",[["0.009"]],"data"] 4 | ["set lc_messages to \"C\";","0E0","data"] 5 | ["select nspname from pg_namespace where nspname = 'tester' limit 1;\n",1,"data"] 6 | ["set search_path to tester,public","0E0","data"] 7 | [" select id from _roles where name = 'Admin' and password = '5f4dcc3b5aa765d61d8327deb882cf99' limit 1; ",[["1"]],"data"] 8 | ["select nspname from pg_namespace where nspname = 'tester' limit 1;\n",1,"data"] 9 | [" select c.relname as name, obj_description(c.oid, 'pg_class') as description from pg_catalog.pg_class c left join pg_catalog.pg_namespace n on n.oid = c.relnamespace where c.relkind in ('r','') and n.nspname = 'tester' and pg_catalog.pg_table_is_visible(c.oid) and substr(c.relname,1,1) <> '_' order by c.oid",[],"data"] 10 | ["select nspname from pg_namespace where nspname = 'tester' limit 1;\n",1,"data"] 11 | [" select c.oid from pg_catalog.pg_class c left join pg_catalog.pg_namespace n on n.oid = c.relnamespace where c.relkind in ('r','') and n.nspname = 'tester' and pg_catalog.pg_table_is_visible(c.oid) and substr(c.relname,1,1) <> '_' and c.relname = 'Foo' limit 1 ",[],"data"] 12 | -------------------------------------------------------------------------------- /t/pgmock-data/11-limits.t.json: -------------------------------------------------------------------------------- 1 | ["set search_path to _global,public","0E0","data"] 2 | ["select count(*) from pg_tables where tablename = '_general' and schemaname = '_global'",[["1"]],"data"] 3 | ["select version from _global._general limit 1",[["0.009"]],"data"] 4 | ["set lc_messages to \"C\";","0E0","data"] 5 | -------------------------------------------------------------------------------- /t/pgmock-data/21-captcha.t.json: -------------------------------------------------------------------------------- 1 | ["set search_path to _global,public","0E0","data"] 2 | ["select count(*) from pg_tables where tablename = '_general' and schemaname = '_global'",[["1"]],"data"] 3 | ["select version from _global._general limit 1",[["0.009"]],"data"] 4 | ["set lc_messages to \"C\";","0E0","data"] 5 | -------------------------------------------------------------------------------- /t/pgmock-data/22-version.t.json: -------------------------------------------------------------------------------- 1 | ["set search_path to _global,public","0E0","data"] 2 | ["select count(*) from pg_tables where tablename = '_general' and schemaname = '_global'",[["1"]],"data"] 3 | ["select version from _global._general limit 1",[["0.009"]],"data"] 4 | ["set lc_messages to \"C\";","0E0","data"] 5 | -------------------------------------------------------------------------------- /t/pgmock-data/28-feed.t.json: -------------------------------------------------------------------------------- 1 | ["set search_path to _global,public","0E0","data"] 2 | ["select count(*) from pg_tables where tablename = '_general' and schemaname = '_global'",[["1"]],"data"] 3 | ["select version from _global._general limit 1",[["0.009"]],"data"] 4 | ["set lc_messages to \"C\";","0E0","data"] 5 | -------------------------------------------------------------------------------- /t/pgmock-data/33-duplicate-def.t.json: -------------------------------------------------------------------------------- 1 | ["set search_path to _global,public","0E0","data"] 2 | ["select count(*) from pg_tables where tablename = '_general' and schemaname = '_global'",[["1"]],"data"] 3 | ["select version from _global._general limit 1",[["0.009"]],"data"] 4 | ["set lc_messages to \"C\";","0E0","data"] 5 | ["select nspname from pg_namespace where nspname = 'tester' limit 1;\n",1,"data"] 6 | ["set search_path to tester,public","0E0","data"] 7 | [" select id from _roles where name = 'Admin' and password = '5f4dcc3b5aa765d61d8327deb882cf99' limit 1; ",[["1"]],"data"] 8 | ["select nspname from pg_namespace where nspname = 'tester' limit 1;\n",1,"data"] 9 | [" select c.relname as name, obj_description(c.oid, 'pg_class') as description from pg_catalog.pg_class c left join pg_catalog.pg_namespace n on n.oid = c.relnamespace where c.relkind in ('r','') and n.nspname = 'tester' and pg_catalog.pg_table_is_visible(c.oid) and substr(c.relname,1,1) <> '_' order by c.oid",[],"data"] 10 | ["select nspname from pg_namespace where nspname = 'tester' limit 1;\n",1,"data"] 11 | [" select name from _views ",[],"data"] 12 | ["truncate _views;","0E0","data"] 13 | ["select nspname from pg_namespace where nspname = 'tester' limit 1;\n",1,"data"] 14 | ["select count(*) from _views",[["0"]],"data"] 15 | [" select id from _views where name = 'Toy' limit 1; ",[],"data"] 16 | [" insert into _views (name, definition, description) values('Toy', 'select 12', NULL) ",1,"data"] 17 | ["select nspname from pg_namespace where nspname = 'tester' limit 1;\n",1,"data"] 18 | ["select count(*) from _views",[["1"]],"data"] 19 | [" select id from _views where name = 'Toy2' limit 1; ",[],"data"] 20 | [" insert into _views (name, definition, description) values('Toy2', 'select 12', NULL) ",1,"data"] 21 | -------------------------------------------------------------------------------- /t/pgmock-data/41-action-proxy.t.json: -------------------------------------------------------------------------------- 1 | ["set search_path to _global,public","0E0","data"] 2 | ["select count(*) from pg_tables where tablename = '_general' and schemaname = '_global'",[["1"]],"data"] 3 | ["select version from _global._general limit 1",[["0.009"]],"data"] 4 | ["set lc_messages to \"C\";","0E0","data"] 5 | ["select nspname from pg_namespace where nspname = 'tester' limit 1;\n",1,"data"] 6 | ["set search_path to tester,public","0E0","data"] 7 | [" select id from _roles where name = 'Admin' and password = '5f4dcc3b5aa765d61d8327deb882cf99' limit 1; ",[["1"]],"data"] 8 | ["select nspname from pg_namespace where nspname = 'tester' limit 1;\n",1,"data"] 9 | [" select name from _actions ",[],"data"] 10 | ["select nspname from pg_namespace where nspname = 'tester' limit 1;\n",1,"data"] 11 | ["select count(*) from _actions",[["0"]],"data"] 12 | [" select compiled from _actions where name = 'Test' limit 1; ",[],"data"] 13 | [" insert into _actions (name, definition, description, compiled) values('Test', 'GET ''http://api.openresty.org/=/version''', NULL, '[{},[[\"GET\",[\"http://api.openresty.org/=/version\"]]]]'); ",1,"data"] 14 | ["select max(id) from \"_actions\"",[["1"]],"data"] 15 | ["","","data"] 16 | ["select nspname from pg_namespace where nspname = 'tester' limit 1;\n",1,"data"] 17 | [" select compiled from _actions where name = 'Test' limit 1; ",[["[{},[[\"GET\",[\"http://api.openresty.org/=/version\"]]]]"]],"data"] 18 | -------------------------------------------------------------------------------- /t/pgmock-data/49-view-builtin-vars.t.json: -------------------------------------------------------------------------------- 1 | ["set search_path to _global,public","0E0","data"] 2 | ["select count(*) from pg_tables where tablename = '_general' and schemaname = '_global'",[["1"]],"data"] 3 | ["select version from _global._general limit 1",[["0.009"]],"data"] 4 | ["set lc_messages to \"C\";","0E0","data"] 5 | ["select nspname from pg_namespace where nspname = 'tester' limit 1;\n",1,"data"] 6 | ["set search_path to tester,public","0E0","data"] 7 | [" select id from _roles where name = 'Admin' and password = '5f4dcc3b5aa765d61d8327deb882cf99' limit 1; ",[["1"]],"data"] 8 | ["select nspname from pg_namespace where nspname = 'tester' limit 1;\n",1,"data"] 9 | [" select name from _views ",[],"data"] 10 | ["truncate _views;","0E0","data"] 11 | ["select nspname from pg_namespace where nspname = 'tester' limit 1;\n",1,"data"] 12 | ["select count(*) from _views",[["0"]],"data"] 13 | [" select id from _views where name = 'Foo' limit 1; ",[],"data"] 14 | [" insert into _views (name, definition, description) values('Foo', 'select $_ACCOUNT as account, $_ROLE as role;', 'test builtin vars') ",1,"data"] 15 | ["select nspname from pg_namespace where nspname = 'tester' limit 1;\n",1,"data"] 16 | [" select id from _views where name = 'Foo' limit 1; ",[["1"]],"data"] 17 | ["select definition from _views where name = 'Foo'",[["select $_ACCOUNT as account, $_ROLE as role;"]],"data"] 18 | ["select 'tester' as account , 'Admin' as role",[{"account":"tester","role":"Admin"}],"data"] 19 | ["select nspname from pg_namespace where nspname = 'tester' limit 1;\n",1,"data"] 20 | [" select id from _views where name = 'Foo' limit 1; ",[["1"]],"data"] 21 | ["select definition from _views where name = 'Foo'",[["select $_ACCOUNT as account, $_ROLE as role;"]],"data"] 22 | ["select 'tester' as account , 'Admin' as role",[{"account":"tester","role":"Admin"}],"data"] 23 | -------------------------------------------------------------------------------- /t/pgmock-data/53_compiled_actions.t.json: -------------------------------------------------------------------------------- 1 | ["set search_path to _global,public","0E0","data"] 2 | ["select count(*) from pg_tables where tablename = '_general' and schemaname = '_global'",[["1"]],"data"] 3 | ["select version from _global._general limit 1",[["0.009"]],"data"] 4 | ["set lc_messages to \"C\";","0E0","data"] 5 | -------------------------------------------------------------------------------- /t/pgmock-data/55-login-by-captchapassword.t.json: -------------------------------------------------------------------------------- 1 | ["set search_path to _global,public","0E0","data"] 2 | ["select count(*) from pg_tables where tablename = '_general' and schemaname = '_global'",[["1"]],"data"] 3 | ["select version from _global._general limit 1",[["0.009"]],"data"] 4 | ["set lc_messages to \"C\";","0E0","data"] 5 | -------------------------------------------------------------------------------- /t/pgmock-data/56-shell.t.json: -------------------------------------------------------------------------------- 1 | ["set search_path to _global,public","0E0","data"] 2 | ["select count(*) from pg_tables where tablename = '_general' and schemaname = '_global'",[["1"]],"data"] 3 | ["select version from _global._general limit 1",[["0.009"]],"data"] 4 | ["set lc_messages to \"C\";","0E0","data"] 5 | -------------------------------------------------------------------------------- /t/pgmock-data/57-encoded-slashes.t.json: -------------------------------------------------------------------------------- 1 | ["set search_path to _global,public","0E0","data"] 2 | ["select count(*) from pg_tables where tablename = '_general' and schemaname = '_global'",[["1"]],"data"] 3 | ["select version from _global._general limit 1",[["0.009"]],"data"] 4 | ["set lc_messages to \"C\";","0E0","data"] 5 | ["select nspname from pg_namespace where nspname = 'tester' limit 1;\n",1,"data"] 6 | ["set search_path to tester,public","0E0","data"] 7 | [" select id from _roles where name = 'Admin' and password = '5f4dcc3b5aa765d61d8327deb882cf99' limit 1; ",[["1"]],"data"] 8 | ["select nspname from pg_namespace where nspname = 'tester' limit 1;\n",1,"data"] 9 | -------------------------------------------------------------------------------- /test: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | #export PATH=/opt/perl/bin:$PATH 4 | exec make test -f dev.mk 5 | 6 | -------------------------------------------------------------------------------- /util/push_pkg: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | 3 | use FindBin; 4 | 5 | 6 | if( $#ARGV < 0 ) 7 | { 8 | print "usage: $0 \n"; 9 | exit; 10 | } 11 | 12 | chdir("$FindBin::Bin/../"); 13 | print "svn up ing\n"; 14 | system("svn up"); 15 | 16 | print "seting revision..\n"; 17 | system("bin/revision.pl\n"); 18 | 19 | print "get revision number..\n"; 20 | $rev = `cat revision`; 21 | $pkgname=$pkgdir="openapi-$rev"; 22 | 23 | $dist_host=join(",",@ARGV); 24 | print "commiting $rev revision.."; 25 | system("svn ci -m 'openapi-$rev packaged and will upload to $dist_host'"); 26 | 27 | chdir("../"); 28 | system("cp -rf trunk openapi-$rev"); 29 | system("tar -cz --exclude=$pkgdir/util --exclude=$pkgdir/pkg --exclude=.svn -f $FindBin::Bin/../pkg/$pkgname.tgz $pkgdir"); 30 | system("/usr/bin/shar -z $pkgdir $FindBin::Bin/../pkg/$pkgname.pkg && chmod a+x $FindBin::Bin/../pkg/$pkgname.pkg "); 31 | 32 | foreach (@ARGV) 33 | { 34 | system("scp -l 10000 $FindBin::Bin/../pkg/$pkgname.pkg $_:/tmp"); 35 | } 36 | 37 | --------------------------------------------------------------------------------