From e8e4b0d293021fe90326a85828f3cfb087bf18b7 Mon Sep 17 00:00:00 2001 From: Robert Newson Date: Tue, 17 May 2011 11:15:14 +0000 Subject: tagging 1.1.0 git-svn-id: https://svn.apache.org/repos/asf/couchdb/tags/1.1.0@1104149 13f79535-47bb-0310-9956-ffa450edef68 --- 1.1.x/.gitignore | 100 + 1.1.x/AUTHORS | 20 + 1.1.x/BUGS | 6 + 1.1.x/CHANGES | 632 ++ 1.1.x/DEVELOPERS | 95 + 1.1.x/INSTALL.Unix | 231 + 1.1.x/INSTALL.Windows | 153 + 1.1.x/LICENSE | 400 ++ 1.1.x/Makefile.am | 149 + 1.1.x/NEWS | 301 + 1.1.x/NOTICE | 55 + 1.1.x/README | 81 + 1.1.x/THANKS | 85 + 1.1.x/acinclude.m4.in | 30 + 1.1.x/bin/Makefile.am | 98 + 1.1.x/bin/couchdb.bat.tpl.in | 26 + 1.1.x/bin/couchdb.tpl.in | 330 ++ 1.1.x/bin/couchjs.tpl.in | 92 + 1.1.x/bootstrap | 68 + 1.1.x/configure.ac | 440 ++ 1.1.x/etc/Makefile.am | 117 + 1.1.x/etc/couchdb/Makefile.am | 86 + 1.1.x/etc/couchdb/default.ini.tpl.in | 148 + 1.1.x/etc/couchdb/local.ini | 74 + 1.1.x/etc/default/Makefile.am | 13 + 1.1.x/etc/default/couchdb | 7 + 1.1.x/etc/init/Makefile.am | 13 + 1.1.x/etc/init/couchdb.tpl.in | 168 + 1.1.x/etc/launchd/Makefile.am | 13 + 1.1.x/etc/launchd/org.apache.couchdb.plist.tpl.in | 30 + 1.1.x/etc/logrotate.d/Makefile.am | 13 + 1.1.x/etc/logrotate.d/couchdb.tpl.in | 9 + 1.1.x/etc/windows/Makefile.am | 13 + 1.1.x/etc/windows/README.txt.tpl | 29 + 1.1.x/etc/windows/couchdb.iss.tpl | 87 + 1.1.x/license.skip | 111 + 1.1.x/m4/ac_check_curl.m4.gz | Bin 0 -> 944 bytes 1.1.x/m4/ac_check_icu.m4.gz | Bin 0 -> 956 bytes 1.1.x/share/Makefile.am | 201 + 1.1.x/share/server/filter.js | 23 + 1.1.x/share/server/json2.js | 482 ++ 1.1.x/share/server/loop.js | 142 + 1.1.x/share/server/mimeparse.js | 158 + 1.1.x/share/server/render.js | 352 ++ 1.1.x/share/server/state.js | 32 + 1.1.x/share/server/util.js | 146 + 1.1.x/share/server/validate.js | 22 + 1.1.x/share/server/views.js | 126 + 1.1.x/share/www/_sidebar.html | 59 + 1.1.x/share/www/config.html | 135 + 1.1.x/share/www/couch_tests.html | 98 + 1.1.x/share/www/custom_test.html | 112 + 1.1.x/share/www/database.html | 267 + 1.1.x/share/www/dialog/_admin_party.html | 33 + 1.1.x/share/www/dialog/_change_password.html | 31 + 1.1.x/share/www/dialog/_compact_cleanup.html | 51 + 1.1.x/share/www/dialog/_create_admin.html | 50 + 1.1.x/share/www/dialog/_create_config.html | 42 + 1.1.x/share/www/dialog/_create_database.html | 33 + 1.1.x/share/www/dialog/_database_security.html | 50 + 1.1.x/share/www/dialog/_delete_database.html | 27 + 1.1.x/share/www/dialog/_delete_document.html | 26 + 1.1.x/share/www/dialog/_login.html | 34 + 1.1.x/share/www/dialog/_save_view_as.html | 35 + 1.1.x/share/www/dialog/_share_test_reports.html | 42 + 1.1.x/share/www/dialog/_signup.html | 35 + 1.1.x/share/www/dialog/_upload_attachment.html | 36 + 1.1.x/share/www/document.html | 114 + 1.1.x/share/www/favicon.ico | Bin 0 -> 9326 bytes 1.1.x/share/www/image/add.png | Bin 0 -> 709 bytes 1.1.x/share/www/image/apply.gif | Bin 0 -> 652 bytes 1.1.x/share/www/image/bg.png | Bin 0 -> 372 bytes 1.1.x/share/www/image/cancel.gif | Bin 0 -> 659 bytes 1.1.x/share/www/image/compact.png | Bin 0 -> 28735 bytes 1.1.x/share/www/image/delete-mini.png | Bin 0 -> 418 bytes 1.1.x/share/www/image/delete.png | Bin 0 -> 718 bytes 1.1.x/share/www/image/grippie.gif | Bin 0 -> 75 bytes 1.1.x/share/www/image/hgrad.gif | Bin 0 -> 118 bytes 1.1.x/share/www/image/key.png | Bin 0 -> 859 bytes 1.1.x/share/www/image/load.png | Bin 0 -> 780 bytes 1.1.x/share/www/image/logo.png | Bin 0 -> 3010 bytes 1.1.x/share/www/image/order-asc.gif | Bin 0 -> 195 bytes 1.1.x/share/www/image/order-desc.gif | Bin 0 -> 187 bytes 1.1.x/share/www/image/path.gif | Bin 0 -> 104 bytes 1.1.x/share/www/image/progress.gif | Bin 0 -> 10819 bytes 1.1.x/share/www/image/rarrow.png | Bin 0 -> 27721 bytes 1.1.x/share/www/image/run-mini.png | Bin 0 -> 478 bytes 1.1.x/share/www/image/run.png | Bin 0 -> 718 bytes 1.1.x/share/www/image/running.png | Bin 0 -> 284 bytes 1.1.x/share/www/image/save.png | Bin 0 -> 843 bytes 1.1.x/share/www/image/sidebar-toggle.png | Bin 0 -> 512 bytes 1.1.x/share/www/image/spinner.gif | Bin 0 -> 3008 bytes 1.1.x/share/www/image/spinner_33.gif | Bin 0 -> 2987 bytes 1.1.x/share/www/image/spinner_6b.gif | Bin 0 -> 2969 bytes 1.1.x/share/www/image/test_failure.gif | Bin 0 -> 114 bytes 1.1.x/share/www/image/test_success.gif | Bin 0 -> 185 bytes 1.1.x/share/www/image/thead-key.gif | Bin 0 -> 77 bytes 1.1.x/share/www/image/thead.gif | Bin 0 -> 51 bytes 1.1.x/share/www/image/toggle-collapse.gif | Bin 0 -> 176 bytes 1.1.x/share/www/image/toggle-expand.gif | Bin 0 -> 181 bytes 1.1.x/share/www/image/twisty.gif | Bin 0 -> 160 bytes 1.1.x/share/www/index.html | 94 + 1.1.x/share/www/replicator.html | 184 + 1.1.x/share/www/script/base64.js | 124 + 1.1.x/share/www/script/couch.js | 473 ++ 1.1.x/share/www/script/couch_test_runner.js | 437 ++ 1.1.x/share/www/script/couch_tests.js | 105 + 1.1.x/share/www/script/futon.browse.js | 1290 ++++ 1.1.x/share/www/script/futon.format.js | 146 + 1.1.x/share/www/script/futon.js | 535 ++ .../www/script/jquery-ui-1.8.11.custom.min.js | 81 + 1.1.x/share/www/script/jquery.couch.js | 699 +++ 1.1.x/share/www/script/jquery.dialog.js | 96 + 1.1.x/share/www/script/jquery.editinline.js | 114 + 1.1.x/share/www/script/jquery.form.js | 660 +++ 1.1.x/share/www/script/jquery.js | 6240 ++++++++++++++++++++ 1.1.x/share/www/script/jquery.resizer.js | 84 + 1.1.x/share/www/script/jquery.suggest.js | 163 + 1.1.x/share/www/script/json2.js | 482 ++ 1.1.x/share/www/script/jspec/jspec.css | 149 + 1.1.x/share/www/script/jspec/jspec.jquery.js | 72 + 1.1.x/share/www/script/jspec/jspec.js | 1756 ++++++ 1.1.x/share/www/script/jspec/jspec.xhr.js | 195 + 1.1.x/share/www/script/oauth.js | 511 ++ 1.1.x/share/www/script/sha1.js | 202 + 1.1.x/share/www/script/test/all_docs.js | 136 + .../share/www/script/test/attachment_conflicts.js | 56 + 1.1.x/share/www/script/test/attachment_names.js | 98 + 1.1.x/share/www/script/test/attachment_paths.js | 153 + 1.1.x/share/www/script/test/attachment_ranges.js | 134 + 1.1.x/share/www/script/test/attachment_views.js | 98 + 1.1.x/share/www/script/test/attachments.js | 275 + .../share/www/script/test/attachments_multipart.js | 408 ++ 1.1.x/share/www/script/test/auth_cache.js | 280 + 1.1.x/share/www/script/test/basics.js | 249 + 1.1.x/share/www/script/test/batch_save.js | 48 + 1.1.x/share/www/script/test/bulk_docs.js | 100 + 1.1.x/share/www/script/test/changes.js | 509 ++ 1.1.x/share/www/script/test/compact.js | 59 + 1.1.x/share/www/script/test/config.js | 163 + 1.1.x/share/www/script/test/conflicts.js | 64 + 1.1.x/share/www/script/test/content_negotiation.js | 39 + 1.1.x/share/www/script/test/cookie_auth.js | 256 + 1.1.x/share/www/script/test/copy_doc.js | 51 + 1.1.x/share/www/script/test/delayed_commits.js | 154 + 1.1.x/share/www/script/test/design_docs.js | 427 ++ 1.1.x/share/www/script/test/design_options.js | 74 + 1.1.x/share/www/script/test/design_paths.js | 72 + 1.1.x/share/www/script/test/erlang_views.js | 133 + 1.1.x/share/www/script/test/etags_head.js | 78 + 1.1.x/share/www/script/test/etags_views.js | 212 + 1.1.x/share/www/script/test/form_submit.js | 26 + 1.1.x/share/www/script/test/http.js | 54 + 1.1.x/share/www/script/test/invalid_docids.js | 77 + 1.1.x/share/www/script/test/jsonp.js | 82 + 1.1.x/share/www/script/test/large_docs.js | 33 + 1.1.x/share/www/script/test/list_views.js | 475 ++ 1.1.x/share/www/script/test/lorem.txt | 103 + 1.1.x/share/www/script/test/lorem_b64.txt | 1 + 1.1.x/share/www/script/test/lots_of_docs.js | 55 + 1.1.x/share/www/script/test/method_override.js | 40 + 1.1.x/share/www/script/test/multiple_rows.js | 80 + 1.1.x/share/www/script/test/oauth.js | 267 + 1.1.x/share/www/script/test/proxyauth.js | 130 + 1.1.x/share/www/script/test/purge.js | 145 + 1.1.x/share/www/script/test/reader_acl.js | 198 + 1.1.x/share/www/script/test/recreate_doc.js | 80 + 1.1.x/share/www/script/test/reduce.js | 185 + 1.1.x/share/www/script/test/reduce_builtin.js | 179 + 1.1.x/share/www/script/test/reduce_false.js | 44 + 1.1.x/share/www/script/test/reduce_false_temp.js | 37 + 1.1.x/share/www/script/test/replication.js | 792 +++ 1.1.x/share/www/script/test/replicator_db.js | 1155 ++++ 1.1.x/share/www/script/test/rev_stemming.js | 99 + 1.1.x/share/www/script/test/rewrite.js | 410 ++ 1.1.x/share/www/script/test/security_validation.js | 336 ++ 1.1.x/share/www/script/test/show_documents.js | 436 ++ 1.1.x/share/www/script/test/stats.js | 330 ++ 1.1.x/share/www/script/test/update_documents.js | 168 + 1.1.x/share/www/script/test/users_db.js | 124 + 1.1.x/share/www/script/test/utf8.js | 41 + 1.1.x/share/www/script/test/uuids.js | 120 + 1.1.x/share/www/script/test/view_collation.js | 116 + 1.1.x/share/www/script/test/view_collation_raw.js | 123 + 1.1.x/share/www/script/test/view_compaction.js | 104 + 1.1.x/share/www/script/test/view_conflicts.js | 49 + 1.1.x/share/www/script/test/view_errors.js | 189 + 1.1.x/share/www/script/test/view_include_docs.js | 192 + .../www/script/test/view_multi_key_all_docs.js | 91 + .../share/www/script/test/view_multi_key_design.js | 216 + 1.1.x/share/www/script/test/view_multi_key_temp.js | 37 + 1.1.x/share/www/script/test/view_offsets.js | 108 + 1.1.x/share/www/script/test/view_pagination.js | 147 + 1.1.x/share/www/script/test/view_sandboxing.js | 140 + 1.1.x/share/www/script/test/view_update_seq.js | 106 + 1.1.x/share/www/script/test/view_xml.js | 39 + 1.1.x/share/www/session.html | 96 + .../share/www/spec/couch_js_class_methods_spec.js | 401 ++ .../www/spec/couch_js_instance_methods_1_spec.js | 311 + .../www/spec/couch_js_instance_methods_2_spec.js | 246 + .../www/spec/couch_js_instance_methods_3_spec.js | 215 + 1.1.x/share/www/spec/custom_helpers.js | 51 + .../www/spec/jquery_couch_js_class_methods_spec.js | 523 ++ .../jquery_couch_js_instance_methods_1_spec.js | 202 + .../jquery_couch_js_instance_methods_2_spec.js | 433 ++ .../jquery_couch_js_instance_methods_3_spec.js | 540 ++ 1.1.x/share/www/spec/run.html | 46 + 1.1.x/share/www/status.html | 109 + 1.1.x/share/www/style/jquery-ui-1.8.11.custom.css | 347 ++ 1.1.x/share/www/style/layout.css | 618 ++ 1.1.x/src/Makefile.am | 13 + 1.1.x/src/couchdb/Makefile.am | 209 + 1.1.x/src/couchdb/couch.app.tpl.in | 29 + 1.1.x/src/couchdb/couch.erl | 39 + 1.1.x/src/couchdb/couch_app.erl | 56 + 1.1.x/src/couchdb/couch_auth_cache.erl | 419 ++ 1.1.x/src/couchdb/couch_btree.erl | 679 +++ 1.1.x/src/couchdb/couch_changes.erl | 339 ++ 1.1.x/src/couchdb/couch_config.erl | 254 + 1.1.x/src/couchdb/couch_config_writer.erl | 86 + 1.1.x/src/couchdb/couch_db.erl | 1210 ++++ 1.1.x/src/couchdb/couch_db.hrl | 278 + 1.1.x/src/couchdb/couch_db_update_notifier.erl | 73 + 1.1.x/src/couchdb/couch_db_update_notifier_sup.erl | 63 + 1.1.x/src/couchdb/couch_db_updater.erl | 896 +++ 1.1.x/src/couchdb/couch_doc.erl | 527 ++ 1.1.x/src/couchdb/couch_event_sup.erl | 73 + 1.1.x/src/couchdb/couch_external_manager.erl | 101 + 1.1.x/src/couchdb/couch_external_server.erl | 69 + 1.1.x/src/couchdb/couch_file.erl | 614 ++ 1.1.x/src/couchdb/couch_httpd.erl | 997 ++++ 1.1.x/src/couchdb/couch_httpd_auth.erl | 359 ++ 1.1.x/src/couchdb/couch_httpd_db.erl | 1283 ++++ 1.1.x/src/couchdb/couch_httpd_external.erl | 169 + 1.1.x/src/couchdb/couch_httpd_misc_handlers.erl | 284 + 1.1.x/src/couchdb/couch_httpd_oauth.erl | 176 + 1.1.x/src/couchdb/couch_httpd_proxy.erl | 431 ++ 1.1.x/src/couchdb/couch_httpd_rewrite.erl | 434 ++ 1.1.x/src/couchdb/couch_httpd_show.erl | 404 ++ 1.1.x/src/couchdb/couch_httpd_stats_handlers.erl | 56 + 1.1.x/src/couchdb/couch_httpd_vhost.erl | 403 ++ 1.1.x/src/couchdb/couch_httpd_view.erl | 755 +++ 1.1.x/src/couchdb/couch_js_functions.hrl | 226 + 1.1.x/src/couchdb/couch_key_tree.erl | 332 ++ 1.1.x/src/couchdb/couch_log.erl | 193 + 1.1.x/src/couchdb/couch_native_process.erl | 402 ++ 1.1.x/src/couchdb/couch_os_daemons.erl | 364 ++ 1.1.x/src/couchdb/couch_os_process.erl | 185 + 1.1.x/src/couchdb/couch_query_servers.erl | 589 ++ 1.1.x/src/couchdb/couch_ref_counter.erl | 111 + 1.1.x/src/couchdb/couch_rep.erl | 972 +++ 1.1.x/src/couchdb/couch_rep_att.erl | 119 + 1.1.x/src/couchdb/couch_rep_changes_feed.erl | 503 ++ 1.1.x/src/couchdb/couch_rep_httpc.erl | 317 + 1.1.x/src/couchdb/couch_rep_missing_revs.erl | 198 + 1.1.x/src/couchdb/couch_rep_reader.erl | 283 + 1.1.x/src/couchdb/couch_rep_sup.erl | 31 + 1.1.x/src/couchdb/couch_rep_writer.erl | 165 + 1.1.x/src/couchdb/couch_replication_manager.erl | 383 ++ 1.1.x/src/couchdb/couch_server.erl | 405 ++ 1.1.x/src/couchdb/couch_server_sup.erl | 220 + 1.1.x/src/couchdb/couch_stats_aggregator.erl | 297 + 1.1.x/src/couchdb/couch_stats_collector.erl | 136 + 1.1.x/src/couchdb/couch_stream.erl | 357 ++ 1.1.x/src/couchdb/couch_task_status.erl | 124 + 1.1.x/src/couchdb/couch_util.erl | 478 ++ 1.1.x/src/couchdb/couch_uuids.erl | 95 + 1.1.x/src/couchdb/couch_view.erl | 460 ++ 1.1.x/src/couchdb/couch_view_compactor.erl | 102 + 1.1.x/src/couchdb/couch_view_group.erl | 642 ++ 1.1.x/src/couchdb/couch_view_updater.erl | 265 + 1.1.x/src/couchdb/couch_work_queue.erl | 155 + 1.1.x/src/couchdb/priv/Makefile.am | 93 + 1.1.x/src/couchdb/priv/couch_js/http.c | 675 +++ 1.1.x/src/couchdb/priv/couch_js/http.h | 18 + 1.1.x/src/couchdb/priv/couch_js/main.c | 338 ++ 1.1.x/src/couchdb/priv/couch_js/utf8.c | 286 + 1.1.x/src/couchdb/priv/couch_js/utf8.h | 19 + .../src/couchdb/priv/icu_driver/couch_icu_driver.c | 177 + .../priv/spawnkillable/couchspawnkillable.sh | 20 + .../priv/spawnkillable/couchspawnkillable_win.c | 145 + 1.1.x/src/couchdb/priv/stat_descriptions.cfg.in | 50 + 1.1.x/src/erlang-oauth/Makefile.am | 50 + 1.1.x/src/erlang-oauth/oauth.app.in | 20 + 1.1.x/src/erlang-oauth/oauth.erl | 107 + 1.1.x/src/erlang-oauth/oauth_hmac_sha1.erl | 11 + 1.1.x/src/erlang-oauth/oauth_http.erl | 22 + 1.1.x/src/erlang-oauth/oauth_plaintext.erl | 10 + 1.1.x/src/erlang-oauth/oauth_rsa_sha1.erl | 30 + 1.1.x/src/erlang-oauth/oauth_unix.erl | 16 + 1.1.x/src/erlang-oauth/oauth_uri.erl | 88 + 1.1.x/src/etap/Makefile.am | 44 + 1.1.x/src/etap/etap.erl | 416 ++ 1.1.x/src/etap/etap_application.erl | 72 + 1.1.x/src/etap/etap_can.erl | 79 + 1.1.x/src/etap/etap_exception.erl | 66 + 1.1.x/src/etap/etap_process.erl | 42 + 1.1.x/src/etap/etap_report.erl | 343 ++ 1.1.x/src/etap/etap_request.erl | 89 + 1.1.x/src/etap/etap_string.erl | 47 + 1.1.x/src/etap/etap_web.erl | 65 + 1.1.x/src/ibrowse/Makefile.am | 49 + 1.1.x/src/ibrowse/ibrowse.app.in | 13 + 1.1.x/src/ibrowse/ibrowse.erl | 863 +++ 1.1.x/src/ibrowse/ibrowse.hrl | 21 + 1.1.x/src/ibrowse/ibrowse_app.erl | 63 + 1.1.x/src/ibrowse/ibrowse_http_client.erl | 1855 ++++++ 1.1.x/src/ibrowse/ibrowse_lb.erl | 235 + 1.1.x/src/ibrowse/ibrowse_lib.erl | 391 ++ 1.1.x/src/ibrowse/ibrowse_sup.erl | 63 + 1.1.x/src/ibrowse/ibrowse_test.erl | 513 ++ 1.1.x/src/mochiweb/Makefile.am | 102 + 1.1.x/src/mochiweb/internal.hrl | 3 + 1.1.x/src/mochiweb/mochifmt.erl | 425 ++ 1.1.x/src/mochiweb/mochifmt_records.erl | 38 + 1.1.x/src/mochiweb/mochifmt_std.erl | 30 + 1.1.x/src/mochiweb/mochiglobal.erl | 107 + 1.1.x/src/mochiweb/mochihex.erl | 91 + 1.1.x/src/mochiweb/mochijson.erl | 531 ++ 1.1.x/src/mochiweb/mochijson2.erl | 802 +++ 1.1.x/src/mochiweb/mochilists.erl | 104 + 1.1.x/src/mochiweb/mochilogfile2.erl | 140 + 1.1.x/src/mochiweb/mochinum.erl | 331 ++ 1.1.x/src/mochiweb/mochitemp.erl | 310 + 1.1.x/src/mochiweb/mochiutf8.erl | 316 + 1.1.x/src/mochiweb/mochiweb.app.in | 32 + 1.1.x/src/mochiweb/mochiweb.app.src | 9 + 1.1.x/src/mochiweb/mochiweb.erl | 289 + 1.1.x/src/mochiweb/mochiweb_acceptor.erl | 48 + 1.1.x/src/mochiweb/mochiweb_app.erl | 27 + 1.1.x/src/mochiweb/mochiweb_charref.erl | 308 + 1.1.x/src/mochiweb/mochiweb_cookies.erl | 309 + 1.1.x/src/mochiweb/mochiweb_cover.erl | 75 + 1.1.x/src/mochiweb/mochiweb_echo.erl | 38 + 1.1.x/src/mochiweb/mochiweb_headers.erl | 299 + 1.1.x/src/mochiweb/mochiweb_html.erl | 1061 ++++ 1.1.x/src/mochiweb/mochiweb_http.erl | 273 + 1.1.x/src/mochiweb/mochiweb_io.erl | 46 + 1.1.x/src/mochiweb/mochiweb_mime.erl | 94 + 1.1.x/src/mochiweb/mochiweb_multipart.erl | 824 +++ 1.1.x/src/mochiweb/mochiweb_request.erl | 768 +++ 1.1.x/src/mochiweb/mochiweb_response.erl | 64 + 1.1.x/src/mochiweb/mochiweb_skel.erl | 86 + 1.1.x/src/mochiweb/mochiweb_socket.erl | 84 + 1.1.x/src/mochiweb/mochiweb_socket_server.erl | 272 + 1.1.x/src/mochiweb/mochiweb_sup.erl | 41 + 1.1.x/src/mochiweb/mochiweb_util.erl | 973 +++ 1.1.x/src/mochiweb/reloader.erl | 161 + 1.1.x/test/Makefile.am | 14 + 1.1.x/test/bench/Makefile.am | 22 + 1.1.x/test/bench/bench_marks.js | 103 + 1.1.x/test/bench/benchbulk.sh | 69 + 1.1.x/test/bench/run.tpl | 28 + 1.1.x/test/etap/001-load.t | 68 + 1.1.x/test/etap/002-icu-driver.t | 33 + 1.1.x/test/etap/010-file-basics.t | 108 + 1.1.x/test/etap/011-file-headers.t | 145 + 1.1.x/test/etap/020-btree-basics.t | 205 + 1.1.x/test/etap/021-btree-reductions.t | 141 + 1.1.x/test/etap/030-doc-from-json.t | 236 + 1.1.x/test/etap/031-doc-to-json.t | 197 + 1.1.x/test/etap/040-util.t | 80 + 1.1.x/test/etap/041-uuid-gen-seq.ini | 19 + 1.1.x/test/etap/041-uuid-gen-utc.ini | 19 + 1.1.x/test/etap/041-uuid-gen.t | 118 + 1.1.x/test/etap/050-stream.t | 87 + 1.1.x/test/etap/060-kt-merging.t | 115 + 1.1.x/test/etap/061-kt-missing-leaves.t | 65 + 1.1.x/test/etap/062-kt-remove-leaves.t | 69 + 1.1.x/test/etap/063-kt-get-leaves.t | 98 + 1.1.x/test/etap/064-kt-counting.t | 46 + 1.1.x/test/etap/065-kt-stemming.t | 42 + 1.1.x/test/etap/070-couch-db.t | 73 + 1.1.x/test/etap/080-config-get-set.t | 128 + 1.1.x/test/etap/081-config-override.1.ini | 22 + 1.1.x/test/etap/081-config-override.2.ini | 22 + 1.1.x/test/etap/081-config-override.t | 212 + 1.1.x/test/etap/082-config-register.t | 94 + 1.1.x/test/etap/083-config-no-files.t | 55 + 1.1.x/test/etap/090-task-status.t | 209 + 1.1.x/test/etap/100-ref-counter.t | 114 + 1.1.x/test/etap/110-replication-httpc.t | 132 + 1.1.x/test/etap/111-replication-changes-feed.t | 253 + 1.1.x/test/etap/112-replication-missing-revs.t | 207 + 1.1.x/test/etap/113-replication-attachment-comp.t | 314 + 1.1.x/test/etap/120-stats-collect.t | 150 + 1.1.x/test/etap/121-stats-aggregates.cfg | 19 + 1.1.x/test/etap/121-stats-aggregates.ini | 20 + 1.1.x/test/etap/121-stats-aggregates.t | 171 + 1.1.x/test/etap/130-attachments-md5.t | 248 + 1.1.x/test/etap/140-attachment-comp.t | 762 +++ 1.1.x/test/etap/150-invalid-view-seq.t | 190 + 1.1.x/test/etap/160-vhosts.t | 291 + 1.1.x/test/etap/170-os-daemons.es | 26 + 1.1.x/test/etap/170-os-daemons.t | 114 + 1.1.x/test/etap/171-os-daemons-config.es | 83 + 1.1.x/test/etap/171-os-daemons-config.t | 74 + 1.1.x/test/etap/172-os-daemon-errors.1.es | 22 + 1.1.x/test/etap/172-os-daemon-errors.2.es | 16 + 1.1.x/test/etap/172-os-daemon-errors.3.es | 17 + 1.1.x/test/etap/172-os-daemon-errors.4.es | 17 + 1.1.x/test/etap/172-os-daemon-errors.t | 126 + 1.1.x/test/etap/173-os-daemon-cfg-register.t | 93 + 1.1.x/test/etap/180-http-proxy.ini | 20 + 1.1.x/test/etap/180-http-proxy.t | 378 ++ 1.1.x/test/etap/200-view-group-no-db-leaks.t | 262 + 1.1.x/test/etap/Makefile.am | 88 + 1.1.x/test/etap/random_port.ini | 19 + 1.1.x/test/etap/run.tpl | 27 + 1.1.x/test/etap/test_cfg_register.c | 30 + 1.1.x/test/etap/test_util.erl.in | 42 + 1.1.x/test/etap/test_web.erl | 99 + 1.1.x/test/javascript/Makefile.am | 25 + 1.1.x/test/javascript/cli_runner.js | 52 + 1.1.x/test/javascript/couch_http.js | 62 + 1.1.x/test/javascript/run.tpl | 30 + 1.1.x/test/view_server/Makefile.am | 15 + 1.1.x/test/view_server/query_server_spec.rb | 824 +++ 1.1.x/test/view_server/run_native_process.es | 59 + 1.1.x/utils/Makefile.am | 42 + 1.1.x/var/Makefile.am | 23 + 421 files changed, 85032 insertions(+) create mode 100644 1.1.x/.gitignore create mode 100644 1.1.x/AUTHORS create mode 100644 1.1.x/BUGS create mode 100644 1.1.x/CHANGES create mode 100644 1.1.x/DEVELOPERS create mode 100644 1.1.x/INSTALL.Unix create mode 100644 1.1.x/INSTALL.Windows create mode 100644 1.1.x/LICENSE create mode 100644 1.1.x/Makefile.am create mode 100644 1.1.x/NEWS create mode 100644 1.1.x/NOTICE create mode 100644 1.1.x/README create mode 100644 1.1.x/THANKS create mode 100644 1.1.x/acinclude.m4.in create mode 100644 1.1.x/bin/Makefile.am create mode 100644 1.1.x/bin/couchdb.bat.tpl.in create mode 100644 1.1.x/bin/couchdb.tpl.in create mode 100644 1.1.x/bin/couchjs.tpl.in create mode 100755 1.1.x/bootstrap create mode 100644 1.1.x/configure.ac create mode 100644 1.1.x/etc/Makefile.am create mode 100644 1.1.x/etc/couchdb/Makefile.am create mode 100644 1.1.x/etc/couchdb/default.ini.tpl.in create mode 100644 1.1.x/etc/couchdb/local.ini create mode 100644 1.1.x/etc/default/Makefile.am create mode 100644 1.1.x/etc/default/couchdb create mode 100644 1.1.x/etc/init/Makefile.am create mode 100644 1.1.x/etc/init/couchdb.tpl.in create mode 100644 1.1.x/etc/launchd/Makefile.am create mode 100644 1.1.x/etc/launchd/org.apache.couchdb.plist.tpl.in create mode 100644 1.1.x/etc/logrotate.d/Makefile.am create mode 100644 1.1.x/etc/logrotate.d/couchdb.tpl.in create mode 100644 1.1.x/etc/windows/Makefile.am create mode 100644 1.1.x/etc/windows/README.txt.tpl create mode 100644 1.1.x/etc/windows/couchdb.iss.tpl create mode 100644 1.1.x/license.skip create mode 100644 1.1.x/m4/ac_check_curl.m4.gz create mode 100644 1.1.x/m4/ac_check_icu.m4.gz create mode 100644 1.1.x/share/Makefile.am create mode 100644 1.1.x/share/server/filter.js create mode 100644 1.1.x/share/server/json2.js create mode 100644 1.1.x/share/server/loop.js create mode 100644 1.1.x/share/server/mimeparse.js create mode 100644 1.1.x/share/server/render.js create mode 100644 1.1.x/share/server/state.js create mode 100644 1.1.x/share/server/util.js create mode 100644 1.1.x/share/server/validate.js create mode 100644 1.1.x/share/server/views.js create mode 100644 1.1.x/share/www/_sidebar.html create mode 100644 1.1.x/share/www/config.html create mode 100644 1.1.x/share/www/couch_tests.html create mode 100644 1.1.x/share/www/custom_test.html create mode 100644 1.1.x/share/www/database.html create mode 100644 1.1.x/share/www/dialog/_admin_party.html create mode 100644 1.1.x/share/www/dialog/_change_password.html create mode 100644 1.1.x/share/www/dialog/_compact_cleanup.html create mode 100644 1.1.x/share/www/dialog/_create_admin.html create mode 100644 1.1.x/share/www/dialog/_create_config.html create mode 100644 1.1.x/share/www/dialog/_create_database.html create mode 100644 1.1.x/share/www/dialog/_database_security.html create mode 100644 1.1.x/share/www/dialog/_delete_database.html create mode 100644 1.1.x/share/www/dialog/_delete_document.html create mode 100644 1.1.x/share/www/dialog/_login.html create mode 100644 1.1.x/share/www/dialog/_save_view_as.html create mode 100644 1.1.x/share/www/dialog/_share_test_reports.html create mode 100644 1.1.x/share/www/dialog/_signup.html create mode 100644 1.1.x/share/www/dialog/_upload_attachment.html create mode 100644 1.1.x/share/www/document.html create mode 100644 1.1.x/share/www/favicon.ico create mode 100644 1.1.x/share/www/image/add.png create mode 100644 1.1.x/share/www/image/apply.gif create mode 100644 1.1.x/share/www/image/bg.png create mode 100644 1.1.x/share/www/image/cancel.gif create mode 100644 1.1.x/share/www/image/compact.png create mode 100644 1.1.x/share/www/image/delete-mini.png create mode 100644 1.1.x/share/www/image/delete.png create mode 100644 1.1.x/share/www/image/grippie.gif create mode 100644 1.1.x/share/www/image/hgrad.gif create mode 100644 1.1.x/share/www/image/key.png create mode 100644 1.1.x/share/www/image/load.png create mode 100644 1.1.x/share/www/image/logo.png create mode 100644 1.1.x/share/www/image/order-asc.gif create mode 100644 1.1.x/share/www/image/order-desc.gif create mode 100644 1.1.x/share/www/image/path.gif create mode 100644 1.1.x/share/www/image/progress.gif create mode 100644 1.1.x/share/www/image/rarrow.png create mode 100644 1.1.x/share/www/image/run-mini.png create mode 100644 1.1.x/share/www/image/run.png create mode 100644 1.1.x/share/www/image/running.png create mode 100644 1.1.x/share/www/image/save.png create mode 100644 1.1.x/share/www/image/sidebar-toggle.png create mode 100644 1.1.x/share/www/image/spinner.gif create mode 100644 1.1.x/share/www/image/spinner_33.gif create mode 100644 1.1.x/share/www/image/spinner_6b.gif create mode 100644 1.1.x/share/www/image/test_failure.gif create mode 100644 1.1.x/share/www/image/test_success.gif create mode 100644 1.1.x/share/www/image/thead-key.gif create mode 100644 1.1.x/share/www/image/thead.gif create mode 100644 1.1.x/share/www/image/toggle-collapse.gif create mode 100644 1.1.x/share/www/image/toggle-expand.gif create mode 100644 1.1.x/share/www/image/twisty.gif create mode 100644 1.1.x/share/www/index.html create mode 100644 1.1.x/share/www/replicator.html create mode 100644 1.1.x/share/www/script/base64.js create mode 100644 1.1.x/share/www/script/couch.js create mode 100644 1.1.x/share/www/script/couch_test_runner.js create mode 100644 1.1.x/share/www/script/couch_tests.js create mode 100644 1.1.x/share/www/script/futon.browse.js create mode 100644 1.1.x/share/www/script/futon.format.js create mode 100644 1.1.x/share/www/script/futon.js create mode 100644 1.1.x/share/www/script/jquery-ui-1.8.11.custom.min.js create mode 100644 1.1.x/share/www/script/jquery.couch.js create mode 100644 1.1.x/share/www/script/jquery.dialog.js create mode 100644 1.1.x/share/www/script/jquery.editinline.js create mode 100644 1.1.x/share/www/script/jquery.form.js create mode 100644 1.1.x/share/www/script/jquery.js create mode 100644 1.1.x/share/www/script/jquery.resizer.js create mode 100644 1.1.x/share/www/script/jquery.suggest.js create mode 100644 1.1.x/share/www/script/json2.js create mode 100644 1.1.x/share/www/script/jspec/jspec.css create mode 100644 1.1.x/share/www/script/jspec/jspec.jquery.js create mode 100644 1.1.x/share/www/script/jspec/jspec.js create mode 100644 1.1.x/share/www/script/jspec/jspec.xhr.js create mode 100644 1.1.x/share/www/script/oauth.js create mode 100644 1.1.x/share/www/script/sha1.js create mode 100644 1.1.x/share/www/script/test/all_docs.js create mode 100644 1.1.x/share/www/script/test/attachment_conflicts.js create mode 100644 1.1.x/share/www/script/test/attachment_names.js create mode 100644 1.1.x/share/www/script/test/attachment_paths.js create mode 100644 1.1.x/share/www/script/test/attachment_ranges.js create mode 100644 1.1.x/share/www/script/test/attachment_views.js create mode 100644 1.1.x/share/www/script/test/attachments.js create mode 100644 1.1.x/share/www/script/test/attachments_multipart.js create mode 100644 1.1.x/share/www/script/test/auth_cache.js create mode 100644 1.1.x/share/www/script/test/basics.js create mode 100644 1.1.x/share/www/script/test/batch_save.js create mode 100644 1.1.x/share/www/script/test/bulk_docs.js create mode 100644 1.1.x/share/www/script/test/changes.js create mode 100644 1.1.x/share/www/script/test/compact.js create mode 100644 1.1.x/share/www/script/test/config.js create mode 100644 1.1.x/share/www/script/test/conflicts.js create mode 100644 1.1.x/share/www/script/test/content_negotiation.js create mode 100644 1.1.x/share/www/script/test/cookie_auth.js create mode 100644 1.1.x/share/www/script/test/copy_doc.js create mode 100644 1.1.x/share/www/script/test/delayed_commits.js create mode 100644 1.1.x/share/www/script/test/design_docs.js create mode 100644 1.1.x/share/www/script/test/design_options.js create mode 100644 1.1.x/share/www/script/test/design_paths.js create mode 100644 1.1.x/share/www/script/test/erlang_views.js create mode 100644 1.1.x/share/www/script/test/etags_head.js create mode 100644 1.1.x/share/www/script/test/etags_views.js create mode 100644 1.1.x/share/www/script/test/form_submit.js create mode 100644 1.1.x/share/www/script/test/http.js create mode 100644 1.1.x/share/www/script/test/invalid_docids.js create mode 100644 1.1.x/share/www/script/test/jsonp.js create mode 100644 1.1.x/share/www/script/test/large_docs.js create mode 100644 1.1.x/share/www/script/test/list_views.js create mode 100644 1.1.x/share/www/script/test/lorem.txt create mode 100644 1.1.x/share/www/script/test/lorem_b64.txt create mode 100644 1.1.x/share/www/script/test/lots_of_docs.js create mode 100644 1.1.x/share/www/script/test/method_override.js create mode 100644 1.1.x/share/www/script/test/multiple_rows.js create mode 100644 1.1.x/share/www/script/test/oauth.js create mode 100644 1.1.x/share/www/script/test/proxyauth.js create mode 100644 1.1.x/share/www/script/test/purge.js create mode 100644 1.1.x/share/www/script/test/reader_acl.js create mode 100644 1.1.x/share/www/script/test/recreate_doc.js create mode 100644 1.1.x/share/www/script/test/reduce.js create mode 100644 1.1.x/share/www/script/test/reduce_builtin.js create mode 100644 1.1.x/share/www/script/test/reduce_false.js create mode 100644 1.1.x/share/www/script/test/reduce_false_temp.js create mode 100644 1.1.x/share/www/script/test/replication.js create mode 100644 1.1.x/share/www/script/test/replicator_db.js create mode 100644 1.1.x/share/www/script/test/rev_stemming.js create mode 100644 1.1.x/share/www/script/test/rewrite.js create mode 100644 1.1.x/share/www/script/test/security_validation.js create mode 100644 1.1.x/share/www/script/test/show_documents.js create mode 100644 1.1.x/share/www/script/test/stats.js create mode 100644 1.1.x/share/www/script/test/update_documents.js create mode 100644 1.1.x/share/www/script/test/users_db.js create mode 100644 1.1.x/share/www/script/test/utf8.js create mode 100644 1.1.x/share/www/script/test/uuids.js create mode 100644 1.1.x/share/www/script/test/view_collation.js create mode 100644 1.1.x/share/www/script/test/view_collation_raw.js create mode 100644 1.1.x/share/www/script/test/view_compaction.js create mode 100644 1.1.x/share/www/script/test/view_conflicts.js create mode 100644 1.1.x/share/www/script/test/view_errors.js create mode 100644 1.1.x/share/www/script/test/view_include_docs.js create mode 100644 1.1.x/share/www/script/test/view_multi_key_all_docs.js create mode 100644 1.1.x/share/www/script/test/view_multi_key_design.js create mode 100644 1.1.x/share/www/script/test/view_multi_key_temp.js create mode 100644 1.1.x/share/www/script/test/view_offsets.js create mode 100644 1.1.x/share/www/script/test/view_pagination.js create mode 100644 1.1.x/share/www/script/test/view_sandboxing.js create mode 100644 1.1.x/share/www/script/test/view_update_seq.js create mode 100644 1.1.x/share/www/script/test/view_xml.js create mode 100644 1.1.x/share/www/session.html create mode 100644 1.1.x/share/www/spec/couch_js_class_methods_spec.js create mode 100644 1.1.x/share/www/spec/couch_js_instance_methods_1_spec.js create mode 100644 1.1.x/share/www/spec/couch_js_instance_methods_2_spec.js create mode 100644 1.1.x/share/www/spec/couch_js_instance_methods_3_spec.js create mode 100644 1.1.x/share/www/spec/custom_helpers.js create mode 100644 1.1.x/share/www/spec/jquery_couch_js_class_methods_spec.js create mode 100644 1.1.x/share/www/spec/jquery_couch_js_instance_methods_1_spec.js create mode 100644 1.1.x/share/www/spec/jquery_couch_js_instance_methods_2_spec.js create mode 100644 1.1.x/share/www/spec/jquery_couch_js_instance_methods_3_spec.js create mode 100644 1.1.x/share/www/spec/run.html create mode 100644 1.1.x/share/www/status.html create mode 100644 1.1.x/share/www/style/jquery-ui-1.8.11.custom.css create mode 100644 1.1.x/share/www/style/layout.css create mode 100644 1.1.x/src/Makefile.am create mode 100644 1.1.x/src/couchdb/Makefile.am create mode 100644 1.1.x/src/couchdb/couch.app.tpl.in create mode 100644 1.1.x/src/couchdb/couch.erl create mode 100644 1.1.x/src/couchdb/couch_app.erl create mode 100644 1.1.x/src/couchdb/couch_auth_cache.erl create mode 100644 1.1.x/src/couchdb/couch_btree.erl create mode 100644 1.1.x/src/couchdb/couch_changes.erl create mode 100644 1.1.x/src/couchdb/couch_config.erl create mode 100644 1.1.x/src/couchdb/couch_config_writer.erl create mode 100644 1.1.x/src/couchdb/couch_db.erl create mode 100644 1.1.x/src/couchdb/couch_db.hrl create mode 100644 1.1.x/src/couchdb/couch_db_update_notifier.erl create mode 100644 1.1.x/src/couchdb/couch_db_update_notifier_sup.erl create mode 100644 1.1.x/src/couchdb/couch_db_updater.erl create mode 100644 1.1.x/src/couchdb/couch_doc.erl create mode 100644 1.1.x/src/couchdb/couch_event_sup.erl create mode 100644 1.1.x/src/couchdb/couch_external_manager.erl create mode 100644 1.1.x/src/couchdb/couch_external_server.erl create mode 100644 1.1.x/src/couchdb/couch_file.erl create mode 100644 1.1.x/src/couchdb/couch_httpd.erl create mode 100644 1.1.x/src/couchdb/couch_httpd_auth.erl create mode 100644 1.1.x/src/couchdb/couch_httpd_db.erl create mode 100644 1.1.x/src/couchdb/couch_httpd_external.erl create mode 100644 1.1.x/src/couchdb/couch_httpd_misc_handlers.erl create mode 100644 1.1.x/src/couchdb/couch_httpd_oauth.erl create mode 100644 1.1.x/src/couchdb/couch_httpd_proxy.erl create mode 100644 1.1.x/src/couchdb/couch_httpd_rewrite.erl create mode 100644 1.1.x/src/couchdb/couch_httpd_show.erl create mode 100644 1.1.x/src/couchdb/couch_httpd_stats_handlers.erl create mode 100644 1.1.x/src/couchdb/couch_httpd_vhost.erl create mode 100644 1.1.x/src/couchdb/couch_httpd_view.erl create mode 100644 1.1.x/src/couchdb/couch_js_functions.hrl create mode 100644 1.1.x/src/couchdb/couch_key_tree.erl create mode 100644 1.1.x/src/couchdb/couch_log.erl create mode 100644 1.1.x/src/couchdb/couch_native_process.erl create mode 100644 1.1.x/src/couchdb/couch_os_daemons.erl create mode 100644 1.1.x/src/couchdb/couch_os_process.erl create mode 100644 1.1.x/src/couchdb/couch_query_servers.erl create mode 100644 1.1.x/src/couchdb/couch_ref_counter.erl create mode 100644 1.1.x/src/couchdb/couch_rep.erl create mode 100644 1.1.x/src/couchdb/couch_rep_att.erl create mode 100644 1.1.x/src/couchdb/couch_rep_changes_feed.erl create mode 100644 1.1.x/src/couchdb/couch_rep_httpc.erl create mode 100644 1.1.x/src/couchdb/couch_rep_missing_revs.erl create mode 100644 1.1.x/src/couchdb/couch_rep_reader.erl create mode 100644 1.1.x/src/couchdb/couch_rep_sup.erl create mode 100644 1.1.x/src/couchdb/couch_rep_writer.erl create mode 100644 1.1.x/src/couchdb/couch_replication_manager.erl create mode 100644 1.1.x/src/couchdb/couch_server.erl create mode 100644 1.1.x/src/couchdb/couch_server_sup.erl create mode 100644 1.1.x/src/couchdb/couch_stats_aggregator.erl create mode 100644 1.1.x/src/couchdb/couch_stats_collector.erl create mode 100644 1.1.x/src/couchdb/couch_stream.erl create mode 100644 1.1.x/src/couchdb/couch_task_status.erl create mode 100644 1.1.x/src/couchdb/couch_util.erl create mode 100644 1.1.x/src/couchdb/couch_uuids.erl create mode 100644 1.1.x/src/couchdb/couch_view.erl create mode 100644 1.1.x/src/couchdb/couch_view_compactor.erl create mode 100644 1.1.x/src/couchdb/couch_view_group.erl create mode 100644 1.1.x/src/couchdb/couch_view_updater.erl create mode 100644 1.1.x/src/couchdb/couch_work_queue.erl create mode 100644 1.1.x/src/couchdb/priv/Makefile.am create mode 100644 1.1.x/src/couchdb/priv/couch_js/http.c create mode 100644 1.1.x/src/couchdb/priv/couch_js/http.h create mode 100644 1.1.x/src/couchdb/priv/couch_js/main.c create mode 100644 1.1.x/src/couchdb/priv/couch_js/utf8.c create mode 100644 1.1.x/src/couchdb/priv/couch_js/utf8.h create mode 100644 1.1.x/src/couchdb/priv/icu_driver/couch_icu_driver.c create mode 100644 1.1.x/src/couchdb/priv/spawnkillable/couchspawnkillable.sh create mode 100644 1.1.x/src/couchdb/priv/spawnkillable/couchspawnkillable_win.c create mode 100644 1.1.x/src/couchdb/priv/stat_descriptions.cfg.in create mode 100644 1.1.x/src/erlang-oauth/Makefile.am create mode 100644 1.1.x/src/erlang-oauth/oauth.app.in create mode 100644 1.1.x/src/erlang-oauth/oauth.erl create mode 100644 1.1.x/src/erlang-oauth/oauth_hmac_sha1.erl create mode 100644 1.1.x/src/erlang-oauth/oauth_http.erl create mode 100644 1.1.x/src/erlang-oauth/oauth_plaintext.erl create mode 100644 1.1.x/src/erlang-oauth/oauth_rsa_sha1.erl create mode 100644 1.1.x/src/erlang-oauth/oauth_unix.erl create mode 100644 1.1.x/src/erlang-oauth/oauth_uri.erl create mode 100644 1.1.x/src/etap/Makefile.am create mode 100644 1.1.x/src/etap/etap.erl create mode 100644 1.1.x/src/etap/etap_application.erl create mode 100644 1.1.x/src/etap/etap_can.erl create mode 100644 1.1.x/src/etap/etap_exception.erl create mode 100644 1.1.x/src/etap/etap_process.erl create mode 100644 1.1.x/src/etap/etap_report.erl create mode 100644 1.1.x/src/etap/etap_request.erl create mode 100644 1.1.x/src/etap/etap_string.erl create mode 100644 1.1.x/src/etap/etap_web.erl create mode 100644 1.1.x/src/ibrowse/Makefile.am create mode 100644 1.1.x/src/ibrowse/ibrowse.app.in create mode 100644 1.1.x/src/ibrowse/ibrowse.erl create mode 100644 1.1.x/src/ibrowse/ibrowse.hrl create mode 100644 1.1.x/src/ibrowse/ibrowse_app.erl create mode 100644 1.1.x/src/ibrowse/ibrowse_http_client.erl create mode 100644 1.1.x/src/ibrowse/ibrowse_lb.erl create mode 100644 1.1.x/src/ibrowse/ibrowse_lib.erl create mode 100644 1.1.x/src/ibrowse/ibrowse_sup.erl create mode 100644 1.1.x/src/ibrowse/ibrowse_test.erl create mode 100644 1.1.x/src/mochiweb/Makefile.am create mode 100644 1.1.x/src/mochiweb/internal.hrl create mode 100644 1.1.x/src/mochiweb/mochifmt.erl create mode 100644 1.1.x/src/mochiweb/mochifmt_records.erl create mode 100644 1.1.x/src/mochiweb/mochifmt_std.erl create mode 100644 1.1.x/src/mochiweb/mochiglobal.erl create mode 100644 1.1.x/src/mochiweb/mochihex.erl create mode 100644 1.1.x/src/mochiweb/mochijson.erl create mode 100644 1.1.x/src/mochiweb/mochijson2.erl create mode 100644 1.1.x/src/mochiweb/mochilists.erl create mode 100644 1.1.x/src/mochiweb/mochilogfile2.erl create mode 100644 1.1.x/src/mochiweb/mochinum.erl create mode 100644 1.1.x/src/mochiweb/mochitemp.erl create mode 100644 1.1.x/src/mochiweb/mochiutf8.erl create mode 100644 1.1.x/src/mochiweb/mochiweb.app.in create mode 100644 1.1.x/src/mochiweb/mochiweb.app.src create mode 100644 1.1.x/src/mochiweb/mochiweb.erl create mode 100644 1.1.x/src/mochiweb/mochiweb_acceptor.erl create mode 100644 1.1.x/src/mochiweb/mochiweb_app.erl create mode 100644 1.1.x/src/mochiweb/mochiweb_charref.erl create mode 100644 1.1.x/src/mochiweb/mochiweb_cookies.erl create mode 100644 1.1.x/src/mochiweb/mochiweb_cover.erl create mode 100644 1.1.x/src/mochiweb/mochiweb_echo.erl create mode 100644 1.1.x/src/mochiweb/mochiweb_headers.erl create mode 100644 1.1.x/src/mochiweb/mochiweb_html.erl create mode 100644 1.1.x/src/mochiweb/mochiweb_http.erl create mode 100644 1.1.x/src/mochiweb/mochiweb_io.erl create mode 100644 1.1.x/src/mochiweb/mochiweb_mime.erl create mode 100644 1.1.x/src/mochiweb/mochiweb_multipart.erl create mode 100644 1.1.x/src/mochiweb/mochiweb_request.erl create mode 100644 1.1.x/src/mochiweb/mochiweb_response.erl create mode 100644 1.1.x/src/mochiweb/mochiweb_skel.erl create mode 100644 1.1.x/src/mochiweb/mochiweb_socket.erl create mode 100644 1.1.x/src/mochiweb/mochiweb_socket_server.erl create mode 100644 1.1.x/src/mochiweb/mochiweb_sup.erl create mode 100644 1.1.x/src/mochiweb/mochiweb_util.erl create mode 100644 1.1.x/src/mochiweb/reloader.erl create mode 100644 1.1.x/test/Makefile.am create mode 100644 1.1.x/test/bench/Makefile.am create mode 100644 1.1.x/test/bench/bench_marks.js create mode 100755 1.1.x/test/bench/benchbulk.sh create mode 100755 1.1.x/test/bench/run.tpl create mode 100755 1.1.x/test/etap/001-load.t create mode 100644 1.1.x/test/etap/002-icu-driver.t create mode 100755 1.1.x/test/etap/010-file-basics.t create mode 100755 1.1.x/test/etap/011-file-headers.t create mode 100755 1.1.x/test/etap/020-btree-basics.t create mode 100755 1.1.x/test/etap/021-btree-reductions.t create mode 100755 1.1.x/test/etap/030-doc-from-json.t create mode 100755 1.1.x/test/etap/031-doc-to-json.t create mode 100755 1.1.x/test/etap/040-util.t create mode 100644 1.1.x/test/etap/041-uuid-gen-seq.ini create mode 100644 1.1.x/test/etap/041-uuid-gen-utc.ini create mode 100755 1.1.x/test/etap/041-uuid-gen.t create mode 100755 1.1.x/test/etap/050-stream.t create mode 100755 1.1.x/test/etap/060-kt-merging.t create mode 100755 1.1.x/test/etap/061-kt-missing-leaves.t create mode 100755 1.1.x/test/etap/062-kt-remove-leaves.t create mode 100755 1.1.x/test/etap/063-kt-get-leaves.t create mode 100755 1.1.x/test/etap/064-kt-counting.t create mode 100755 1.1.x/test/etap/065-kt-stemming.t create mode 100755 1.1.x/test/etap/070-couch-db.t create mode 100755 1.1.x/test/etap/080-config-get-set.t create mode 100644 1.1.x/test/etap/081-config-override.1.ini create mode 100644 1.1.x/test/etap/081-config-override.2.ini create mode 100755 1.1.x/test/etap/081-config-override.t create mode 100755 1.1.x/test/etap/082-config-register.t create mode 100755 1.1.x/test/etap/083-config-no-files.t create mode 100755 1.1.x/test/etap/090-task-status.t create mode 100755 1.1.x/test/etap/100-ref-counter.t create mode 100755 1.1.x/test/etap/110-replication-httpc.t create mode 100755 1.1.x/test/etap/111-replication-changes-feed.t create mode 100755 1.1.x/test/etap/112-replication-missing-revs.t create mode 100755 1.1.x/test/etap/113-replication-attachment-comp.t create mode 100755 1.1.x/test/etap/120-stats-collect.t create mode 100644 1.1.x/test/etap/121-stats-aggregates.cfg create mode 100644 1.1.x/test/etap/121-stats-aggregates.ini create mode 100755 1.1.x/test/etap/121-stats-aggregates.t create mode 100755 1.1.x/test/etap/130-attachments-md5.t create mode 100755 1.1.x/test/etap/140-attachment-comp.t create mode 100755 1.1.x/test/etap/150-invalid-view-seq.t create mode 100755 1.1.x/test/etap/160-vhosts.t create mode 100755 1.1.x/test/etap/170-os-daemons.es create mode 100755 1.1.x/test/etap/170-os-daemons.t create mode 100755 1.1.x/test/etap/171-os-daemons-config.es create mode 100755 1.1.x/test/etap/171-os-daemons-config.t create mode 100644 1.1.x/test/etap/172-os-daemon-errors.1.es create mode 100755 1.1.x/test/etap/172-os-daemon-errors.2.es create mode 100755 1.1.x/test/etap/172-os-daemon-errors.3.es create mode 100755 1.1.x/test/etap/172-os-daemon-errors.4.es create mode 100755 1.1.x/test/etap/172-os-daemon-errors.t create mode 100755 1.1.x/test/etap/173-os-daemon-cfg-register.t create mode 100644 1.1.x/test/etap/180-http-proxy.ini create mode 100755 1.1.x/test/etap/180-http-proxy.t create mode 100755 1.1.x/test/etap/200-view-group-no-db-leaks.t create mode 100644 1.1.x/test/etap/Makefile.am create mode 100644 1.1.x/test/etap/random_port.ini create mode 100644 1.1.x/test/etap/run.tpl create mode 100644 1.1.x/test/etap/test_cfg_register.c create mode 100644 1.1.x/test/etap/test_util.erl.in create mode 100644 1.1.x/test/etap/test_web.erl create mode 100644 1.1.x/test/javascript/Makefile.am create mode 100644 1.1.x/test/javascript/cli_runner.js create mode 100644 1.1.x/test/javascript/couch_http.js create mode 100644 1.1.x/test/javascript/run.tpl create mode 100644 1.1.x/test/view_server/Makefile.am create mode 100644 1.1.x/test/view_server/query_server_spec.rb create mode 100755 1.1.x/test/view_server/run_native_process.es create mode 100644 1.1.x/utils/Makefile.am create mode 100644 1.1.x/var/Makefile.am diff --git a/1.1.x/.gitignore b/1.1.x/.gitignore new file mode 100644 index 00000000..33028e7e --- /dev/null +++ b/1.1.x/.gitignore @@ -0,0 +1,100 @@ +*.beam +*.gz +*.tpl +*.o +*.lo +*.la +*.m4 +*.in +*~ +*.orig +*.rej +erl_crash.dump +configure +autom4te.cache +build-aux +*.diff + +# ./configure + +Makefile +bin/Makefile +config.h +config.log +config.status +etc/Makefile +etc/couchdb/Makefile +etc/default/Makefile +etc/init/Makefile +etc/launchd/Makefile +etc/logrotate.d/Makefile +libtool +share/Makefile +src/couchdb/.deps/* +src/couchdb/Makefile +src/couchdb/priv/Makefile +src/mochiweb/Makefile +stamp-h1 +test/.deps/ +test/Makefile +test/javascript/run_js_tests.sh +var/Makefile + +# for make + +bin/couchdb +bin/couchdb.1 +bin/couchjs +bin/couchjs.1 +etc/couchdb/default.ini +etc/launchd/org.apache.couchdb.plist +etc/logrotate.d/couchdb +src/couchdb/.libs/* +src/couchdb/couch.app +src/couchdb/couchjs +src/couchdb/edoc-info +src/couchdb/erlang.png +src/couchdb/stylesheet.css +src/couchdb/priv/.deps/ +src/couchdb/priv/.libs/ +src/couchdb/priv/couch_icu_driver.la +src/couchdb/priv/couchjs +src/couchdb/priv/couchspawnkillable +src/couchdb/priv/stat_descriptions.cfg +src/erlang-oauth/oauth.app +src/ibrowse/ibrowse.app +src/mochiweb/mochiweb.app +test/local.ini +test/etap/.deps/ +test/etap/run +test/etap/test_cfg_register +test/etap/test_util.erl +test/javascript/run +share/server/main.js + +# for make dev + +bin/.deps/ +bin/couchjs_dev +bin/couchpw +etc/couchdb/default_dev.ini +etc/couchdb/local_dev.ini +utils/run +tmp +src/couchdb/priv/stat_descriptions.cfg +src/erlang-oauth/oauth.app +src/ibrowse/ibrowse.app +src/mochiweb/mochiweb.app +test/etap/run + +# for make check + +test/etap/temp.* +test/bench/run +couchdb.stderr +couchdb.stdout + +# for make cover + +cover/* +INSTALL diff --git a/1.1.x/AUTHORS b/1.1.x/AUTHORS new file mode 100644 index 00000000..e0181c1d --- /dev/null +++ b/1.1.x/AUTHORS @@ -0,0 +1,20 @@ +Apache CouchDB AUTHORS +====================== + +A number of people have contributed directly to Apache CouchDB by writing +documentation or developing software. Some of these people are: + + * Damien Katz + * Jan Lehnardt + * Noah Slater + * Christopher Lenz + * J. Chris Anderson + * Paul Joseph Davis + * Adam Kocoloski + * Jason Davies + * Mark Hammond + * BenoĆ®t Chesneau + * Filipe Manana + * Robert Newson + +For a list of other credits see the `THANKS` file. diff --git a/1.1.x/BUGS b/1.1.x/BUGS new file mode 100644 index 00000000..8cd1d161 --- /dev/null +++ b/1.1.x/BUGS @@ -0,0 +1,6 @@ +Apache CouchDB BUGS +=================== + +Please see the [documentation][1] on how to report bugs with Apache CouchDB. + +[1] http://couchdb.apache.org/community/issues.html diff --git a/1.1.x/CHANGES b/1.1.x/CHANGES new file mode 100644 index 00000000..a32797f5 --- /dev/null +++ b/1.1.x/CHANGES @@ -0,0 +1,632 @@ +Apache CouchDB CHANGES +====================== + +Version 1.1.0 +------------- + +All CHANGES for 1.0.2 and 1.0.3 also apply to 1.1.0. + +HTTP Interface: + + * Native SSL support. + * Added support for HTTP range requests for attachments. + * Added built-in filters for `_changes`: `_doc_ids` and `_design`. + * Added configuration option for TCP_NODELAY aka "Nagle". + * Allow POSTing arguments to `_changes`. + * Allow `keys` parameter for GET requests to views. + * Allow wildcards in vhosts definitions. + * More granular ETag support for views. + * More flexible URL rewriter. + * Added support for recognizing "Q values" and media parameters in + HTTP Accept headers. + * Validate doc ids that come from a PUT to a URL. + +Externals: + + * Added OS Process module to manage daemons outside of CouchDB. + * Added HTTP Proxy handler for more scalable externals. + +Replicator: + + * Added `_replicator` database to manage replications. + * Fixed issues when an endpoint is a remote database accessible via SSL. + * Added support for continuous by-doc-IDs replication. + +Storage System: + + * Multiple micro-optimizations when reading data. + +View Server: + + * Added CommonJS support to map functions. + * Added `stale=update_after` query option that triggers a view update after + returning a `stale=ok` response. + * Warn about empty result caused by `startkey` and `endkey` limiting. + * Built-in reduce function `_sum` now accepts lists of integers as input. + * Added view query aliases start_key, end_key, start_key_doc_id and + end_key_doc_id. + +Futon: + + * Added a "change password"-feature to Futon. + + +Version 1.0.1 +------------- + +Storage System: + + * Fix data corruption bug COUCHDB-844. Please see + http://couchdb.apache.org/notice/1.0.1.html for details. + +Replicator: + + * Added support for replication via an HTTP/HTTPS proxy. + * Fix pull replication of attachments from 0.11 to 1.0.x. + * Make the _changes feed work with non-integer seqnums. + +HTTP Interface: + + * Expose `committed_update_seq` for monitoring purposes. + * Show fields saved along with _deleted=true. Allows for auditing of deletes. + * More robust Accept-header detection. + +Authentication: + + * Enable basic-auth popup when required to access the server, to prevent + people from getting locked out. + +Futon: + + * User interface element for querying stale (cached) views. + +Build and System Integration: + + * Included additional source files for distribution. + +Version 1.0.0 +------------- + +Security: + + * Added authentication caching, to avoid repeated opening and closing of the + users database for each request requiring authentication. + +Storage System: + + * Small optimization for reordering result lists. + * More efficient header commits. + * Use O_APPEND to save lseeks. + * Faster implementation of pread_iolist(). Further improves performance on + concurrent reads. + +View Server: + + * Faster default view collation. + * Added option to include update_seq in view responses. + +Version 0.11.2 +-------------- + +Replicator: + + * Fix bug when pushing design docs by non-admins, which was hanging the + replicator for no good reason. + * Fix bug when pulling design documents from a source that requires + basic-auth. + +HTTP Interface: + + * Better error messages on invalid URL requests. + +Authentication: + + * User documents can now be deleted by admins or the user. + +Security: + + * Avoid potential DOS attack by guarding all creation of atoms. + +Futon: + + * Add some Futon files that were missing from the Makefile. + +Version 0.11.1 +-------------- + +HTTP Interface: + + * Mask passwords in active tasks and logging. + * Update mochijson2 to allow output of BigNums not in float form. + * Added support for X-HTTP-METHOD-OVERRIDE. + * Better error message for database names. + * Disable jsonp by default. + * Accept gzip encoded standalone attachments. + * Made max_concurrent_connections configurable. + * Made changes API more robust. + * Send newly generated document rev to callers of an update function. + +Futon: + + * Use "expando links" for over-long document values in Futon. + * Added continuous replication option. + * Added option to replicating test results anonymously to a community + CouchDB instance. + * Allow creation and deletion of config entries. + * Fixed display issues with doc ids that have escaped characters. + * Fixed various UI issues. + +Build and System Integration: + + * Output of `couchdb --help` has been improved. + * Fixed compatibility with the Erlang R14 series. + * Fixed warnings on Linux builds. + * Fixed build error when aclocal needs to be called during the build. + * Require ICU 4.3.1. + * Fixed compatibility with Solaris. + +Security: + + * Added authentication redirect URL to log in clients. + * Fixed query parameter encoding issue in oauth.js. + * Made authentication timeout configurable. + * Temporary views are now admin-only resources. + +Storage System: + + * Don't require a revpos for attachment stubs. + * Added checking to ensure when a revpos is sent with an attachment stub, + it's correct. + * Make file deletions async to avoid pauses during compaction and db + deletion. + * Fixed for wrong offset when writing headers and converting them to blocks, + only triggered when header is larger than 4k. + * Preserve _revs_limit and instance_start_time after compaction. + +Configuration System: + + * Fixed timeout with large .ini files. + +JavaScript Clients: + + * Added tests for couch.js and jquery.couch.js + * Added changes handler to jquery.couch.js. + * Added cache busting to jquery.couch.js if the user agent is msie. + * Added support for multi-document-fetch (via _all_docs) to jquery.couch.js. + * Added attachment versioning to jquery.couch.js. + * Added option to control ensure_full_commit to jquery.couch.js. + * Added list functionality to jquery.couch.js. + * Fixed issues where bulkSave() wasn't sending a POST body. + +View Server: + + * Provide a UUID to update functions (and all other functions) that they can + use to create new docs. + * Upgrade CommonJS modules support to 1.1.1. + * Fixed erlang filter funs and normalize filter fun API. + * Fixed hang in view shutdown. + +Log System: + + * Log HEAD requests as HEAD, not GET. + * Keep massive JSON blobs out of the error log. + * Fixed a timeout issue. + +Replication System: + + * Refactored various internal APIs related to attachment streaming. + * Fixed hanging replication. + * Fixed keepalive issue. + +URL Rewriter & Vhosts: + + * Allow more complex keys in rewriter. + * Allow global rewrites so system defaults are available in vhosts. + * Allow isolation of databases with vhosts. + * Fix issue with passing variables to query parameters. + +Test Suite: + + * Made the test suite overall more reliable. + +Version 0.11.0 +-------------- + +Security: + + * Fixed CVE-2010-0009: Apache CouchDB Timing Attack Vulnerability. + * Added default cookie-authentication and users database. + * Added Futon user interface for user signup and login. + * Added per-database reader access control lists. + * Added per-database security object for configuration data in validation + functions. + * Added proxy authentication handler + +HTTP Interface: + + * Provide Content-MD5 header support for attachments. + * Added URL Rewriter handler. + * Added virtual host handling. + +View Server: + + * Added optional 'raw' binary collation for faster view builds where Unicode + collation is not important. + * Improved view index build time by reducing ICU collation callouts. + * Improved view information objects. + * Bug fix for partial updates during view builds. + * Move query server to a design-doc based protocol. + * Use json2.js for JSON serialization for compatiblity with native JSON. + * Major refactoring of couchjs to lay the groundwork for disabling cURL + support. The new HTTP interaction acts like a synchronous XHR. Example usage + of the new system is in the JavaScript CLI test runner. + +Replication: + + * Added option to implicitly create replication target databases. + * Avoid leaking file descriptors on automatic replication restarts. + * Added option to replicate a list of documents by id. + * Allow continuous replication to be cancelled. + +Storage System: + + * Adds batching of multiple updating requests, to improve throughput with many + writers. Removed the now redundant couch_batch_save module. + * Adds configurable compression of attachments. + +Runtime Statistics: + + * Statistics are now calculated for a moving window instead of non-overlapping + timeframes. + * Fixed a problem with statistics timers and system sleep. + * Moved statistic names to a term file in the priv directory. + +Futon: + + * Added a button for view compaction. + * JSON strings are now displayed as-is in the document view, without the escaping of + new-lines and quotes. That dramatically improves readability of multi-line + strings. + * Same goes for editing of JSON string values. When a change to a field value is + submitted, and the value is not valid JSON it is assumed to be a string. This + improves editing of multi-line strings a lot. + * Hitting tab in textareas no longer moves focus to the next form field, but simply + inserts a tab character at the current caret position. + * Fixed some font declarations. + +Build and System Integration: + + * Updated and improved source documentation. + * Fixed distribution preparation for building on Mac OS X. + * Added support for building a Windows installer as part of 'make dist'. + * Bug fix for building couch.app's module list. + * ETap tests are now run during make distcheck. This included a number of + updates to the build system to properly support VPATH builds. + * Gavin McDonald setup a build-bot instance. More info can be found at + http://ci.apache.org/buildbot.html + +Version 0.10.1 +-------------- + +Replicator: + + * Stability enhancements regarding redirects, timeouts, OAuth. + +Query Server: + + * Avoid process leaks + * Allow list and view to span languages + +Stats: + + * Eliminate new process flood on system wake + +Build and System Integration: + + * Test suite now works with the distcheck target. + +Version 0.10.0 +-------------- + +Storage Format: + + * Add move headers with checksums to the end of database files for extra robust + storage and faster storage. + +View Server: + + * Added native Erlang views for high-performance applications. + +HTTP Interface: + + * Added optional cookie-based authentication handler. + * Added optional two-legged OAuth authentication handler. + +Build and System Integration: + + * Changed `couchdb` script configuration options. + * Added default.d and local.d configuration directories to load sequence. + + +Version 0.9.2 +------------- + +Replication: + + * Fix replication with 0.10 servers initiated by an 0.9 server (COUCHDB-559). + +Build and System Integration: + + * Remove branch callbacks to allow building couchjs against newer versions of + Spidermonkey. + +Version 0.9.1 +------------- + +Build and System Integration: + + * PID file directory is now created by the SysV/BSD daemon scripts. + * Fixed the environment variables shown by the configure script. + * Fixed the build instructions shown by the configure script. + * Updated ownership and permission advice in `README` for better security. + +Configuration and stats system: + + * Corrected missing configuration file error message. + * Fixed incorrect recording of request time. + +Database Core: + + * Document validation for underscore prefixed variables. + * Made attachment storage less sparse. + * Fixed problems when a database with delayed commits pending is considered + idle, and subject to losing changes when shutdown. (COUCHDB-334) + +External Handlers: + + * Fix POST requests. + +Futon: + + * Redirect when loading a deleted view URI from the cookie. + +HTTP Interface: + + * Attachment requests respect the "rev" query-string parameter. + +JavaScript View Server: + + * Useful JavaScript Error messages. + +Replication: + + * Added support for Unicode characters transmitted as UTF-16 surrogate pairs. + * URL-encode attachment names when necessary. + * Pull specific revisions of an attachment, instead of just the latest one. + * Work around a rare chunk-merging problem in ibrowse. + * Work with documents containing Unicode characters outside the Basic + Multilingual Plane. + +Version 0.9.0 +------------- + +Futon Utility Client: + + * Added pagination to the database listing page. + * Implemented attachment uploading from the document page. + * Added page that shows the current configuration, and allows modification of + option values. + * Added a JSON "source view" for document display. + * JSON data in view rows is now syntax highlighted. + * Removed the use of an iframe for better integration with browser history and + bookmarking. + * Full database listing in the sidebar has been replaced by a short list of + recent databases. + * The view editor now allows selection of the view language if there is more + than one configured. + * Added links to go to the raw view or document URI. + * Added status page to display currently running tasks in CouchDB. + * JavaScript test suite split into multiple files. + * Pagination for reduce views. + +Design Document Resource Paths: + + * Added httpd_design_handlers config section. + * Moved _view to httpd_design_handlers. + * Added ability to render documents as non-JSON content-types with _show and + _list functions, which are also httpd_design_handlers. + +HTTP Interface: + + * Added client side UUIDs for idempotent document creation + * HTTP COPY for documents + * Streaming of chunked attachment PUTs to disk + * Remove negative count feature + * Add include_docs option for view queries + * Add multi-key view post for views + * Query parameter validation + * Use stale=ok to request potentially cached view index + * External query handler module for full-text or other indexers. + * Etags for attachments, views, shows and lists + * Show and list functions for rendering documents and views as developer + controlled content-types. + * Attachment names may use slashes to allow uploading of nested directories + (useful for static web hosting). + * Option for a view to run over design documents. + * Added newline to JSON responses. Closes bike-shed. + +Replication: + + * Using ibrowse. + * Checkpoint replications so failures are less expensive. + * Automatically retry of failed replications. + * Stream attachments in pull-replication. + +Database Core: + + * Faster B-tree implementation. + * Changed internal JSON term format. + * Improvements to Erlang VM interactions under heavy load. + * User context and administrator role. + * Update validations with design document validation functions. + * Document purge functionality. + * Ref-counting for database file handles. + +Build and System Integration: + + * The `couchdb` script now supports system chainable configuration files. + * The Mac OS X daemon script now redirects STDOUT and STDERR like SysV/BSD. + * The build and system integration have been improved for portability. + * Added COUCHDB_OPTIONS to etc/default/couchdb file. + * Remove COUCHDB_INI_FILE and COUCHDB_PID_FILE from etc/default/couchdb file. + * Updated `configure.ac` to manually link `libm` for portability. + * Updated `configure.ac` to extended default library paths. + * Removed inets configuration files. + * Added command line test runner. + * Created dev target for make. + +Configuration and stats system: + + * Separate default and local configuration files. + * HTTP interface for configuration changes. + * Statistics framework with HTTP query API. + +Version 0.8.1-incubating +------------------------ + +Database Core: + + * Fix for replication problems where the write queues can get backed up if the + writes aren't happening fast enough to keep up with the reads. For a large + replication, this can exhaust memory and crash, or slow down the machine + dramatically. The fix keeps only one document in the write queue at a time. + * Fix for databases sometimes incorrectly reporting that they contain 0 + documents after compaction. + * CouchDB now uses ibrowse instead of inets for its internal HTTP client + implementation. This means better replication stability. + +HTTP Interface: + + * Fix for chunked responses where chunks were always being split into multiple + TCP packets, which caused problems with the test suite under Safari, and in + some other cases. + * Fix for an invalid JSON response body being returned for some kinds of + views. (COUCHDB-84) + * Fix for connections not getting closed after rejecting a chunked request. + (COUCHDB-55) + * CouchDB can now be bound to IPv6 addresses. + * The HTTP `Server` header now contains the versions of CouchDB and Erlang. + +JavaScript View Server: + + * Sealing of documents has been disabled due to an incompatibility with + SpiderMonkey 1.9. + * Improve error handling for undefined values emitted by map functions. + (COUCHDB-83) + +Build and System Integration: + + * The `couchdb` script no longer uses `awk` for configuration checks as this + was causing portability problems. + * Updated `sudo` example in `README` to use the `-i` option, this fixes + problems when invoking from a directory the `couchdb` user cannot access. + +Futon: + + * The view selector dropdown should now work in Opera and Internet Explorer + even when it includes optgroups for design documents. (COUCHDB-81) + +Version 0.8.0-incubating +------------------------ + +Database Core: + + * The view engine has been completely decoupled from the storage engine. Index + data is now stored in separate files, and the format of the main database + file has changed. + * Databases can now be compacted to reclaim space used for deleted documents + and old document revisions. + * Support for incremental map/reduce views has been added. + * To support map/reduce, the structure of design documents has changed. View + values are now JSON objects containing at least a `map` member, and + optionally a `reduce` member. + * View servers are now identified by name (for example `javascript`) instead of + by media type. + * Automatically generated document IDs are now based on proper UUID generation + using the crypto module. + * The field `content-type` in the JSON representation of attachments has been + renamed to `content_type` (underscore). + +HTTP Interface: + + * CouchDB now uses MochiWeb instead of inets for the HTTP server + implementation. Among other things, this means that the extra configuration + files needed for inets (such as `couch_httpd.conf`) are no longer used. + * The HTTP interface now completely supports the `HEAD` method. (COUCHDB-3) + * Improved compliance of `Etag` handling with the HTTP specification. + (COUCHDB-13) + * Etags are no longer included in responses to document `GET` requests that + include query string parameters causing the JSON response to change without + the revision or the URI having changed. + * The bulk document update API has changed slightly on both the request and the + response side. In addition, bulk updates are now atomic. + * CouchDB now uses `TCP_NODELAY` to fix performance problems with persistent + connections on some platforms due to nagling. + * Including a `?descending=false` query string parameter in requests to views + no longer raises an error. + * Requests to unknown top-level reserved URLs (anything with a leading + underscore) now return a `unknown_private_path` error instead of the + confusing `illegal_database_name`. + * The Temporary view handling now expects a JSON request body, where the JSON + is an object with at least a `map` member, and optional `reduce` and + `language` members. + * Temporary views no longer determine the view server based on the Content-Type + header of the `POST` request, but rather by looking for a `language` member + in the JSON body of the request. + * The status code of responses to `DELETE` requests is now 200 to reflect that + that the deletion is performed synchronously. + +JavaScript View Server: + + * SpiderMonkey is no longer included with CouchDB, but rather treated as a + normal external dependency. A simple C program (`_couchjs`) is provided that + links against an existing SpiderMonkey installation and uses the interpreter + embedding API. + * View functions using the default JavaScript view server can now do logging + using the global `log(message)` function. Log messages are directed into the + CouchDB log at `INFO` level. (COUCHDB-59) + * The global `map(key, value)` function made available to view code has been + renamed to `emit(key, value)`. + * Fixed handling of exceptions raised by view functions. + +Build and System Integration: + + * CouchDB can automatically respawn following a server crash. + * Database server no longer refuses to start with a stale PID file. + * System logrotate configuration provided. + * Improved handling of ICU shared libraries. + * The `couchdb` script now automatically enables SMP support in Erlang. + * The `couchdb` and `couchjs` scripts have been improved for portability. + * The build and system integration have been improved for portability. + +Futon: + + * When adding a field to a document, Futon now just adds a field with an + autogenerated name instead of prompting for the name with a dialog. The name + is automatically put into edit mode so that it can be changed immediately. + * Fields are now sorted alphabetically by name when a document is displayed. + * Futon can be used to create and update permanent views. + * The maximum number of rows to display per page on the database page can now + be adjusted. + * Futon now uses the XMLHTTPRequest API asynchronously to communicate with the + CouchDB HTTP server, so that most operations no longer block the browser. + * View results sorting can now be switched between ascending and descending by + clicking on the `Key` column header. + * Fixed a bug where documents that contained a `@` character could not be + viewed. (COUCHDB-12) + * The database page now provides a `Compact` button to trigger database + compaction. (COUCHDB-38) + * Fixed portential double encoding of document IDs and other URI segments in + many instances. (COUCHDB-39) + * Improved display of attachments. + * The JavaScript Shell has been removed due to unresolved licensing issues. diff --git a/1.1.x/DEVELOPERS b/1.1.x/DEVELOPERS new file mode 100644 index 00000000..a7a6926e --- /dev/null +++ b/1.1.x/DEVELOPERS @@ -0,0 +1,95 @@ +Apache CouchDB DEVELOPERS +========================= + +Only follow these instructions if you are building from a source checkout. + +If you're unsure what this means, ignore this document. + +Dependencies +------------ + +You will need the following installed: + + * GNU Automake (>=1.6.3) (http://www.gnu.org/software/automake/) + * GNU Autoconf (>=2.59) (http://www.gnu.org/software/autoconf/) + * GNU Libtool (http://www.gnu.org/software/libtool/) + * GNU help2man (http://www.gnu.org/software/help2man/) + +The `help2man` tool is optional, but will generate `man` pages for you. + +Debian-based (inc. Ubuntu) Systems +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +You can install the dependencies by running: + + apt-get install automake autoconf libtool help2man + +Be sure to update the version numbers to match your system's available packages. + +Mac OS X +~~~~~~~~ + +You can install the dependencies by running: + + port install automake autoconf libtool help2man + +You will need MacPorts installed to use the `port` command. + +Bootstrapping +------------- + +Bootstrap the pristine source by running: + + ./bootstrap + +You must repeat this step every time you update your source checkout. + +Testing +------- + +Check the test suite by running: + + make check + +Generate a coverage report by running: + + make cover + +Please report any problems to the developer's mailing list. + +Releasing +--------- + +Unix-like Systems +~~~~~~~~~~~~~~~~~ + +Configure the source by running: + + ./configure + +Prepare the release artefacts by running: + + make distcheck + +You can prepare signed release artefacts by running: + + make distsign + +The release artefacts can be found in the root source directory. + +Microsoft Windows +~~~~~~~~~~~~~~~~~ + +Configure the source by running: + + ./configure + +Prepare the release artefacts by running: + + make dist + +The release artefacts can be found in the `etc/windows` directory. + +Until the build system has been improved, you must make sure that you run this +command from a clean source checkout. If you do not, your test database and log +files will be bundled up in the release artefact. diff --git a/1.1.x/INSTALL.Unix b/1.1.x/INSTALL.Unix new file mode 100644 index 00000000..768e3846 --- /dev/null +++ b/1.1.x/INSTALL.Unix @@ -0,0 +1,231 @@ +Apache CouchDB README.Unix +========================== + +A high-level guide to Unix-like systems, inc. Mac OS X and Ubuntu. + +Dependencies +------------ + +You will need the following installed: + + * Erlang OTP (>=R12B5) (http://erlang.org/) + * ICU (http://icu.sourceforge.net/) + * OpenSSL (http://www.openssl.org/) + * Mozilla SpiderMonkey (1.8) (http://www.mozilla.org/js/spidermonkey/) + * libcurl (http://curl.haxx.se/libcurl/) + * GNU Make (http://www.gnu.org/software/make/) + * GNU Compiler Collection (http://gcc.gnu.org/) + +It is recommended that you install Erlang OTP R12B-5 or above where possible. + +Ubuntu +~~~~~~ + +See + + http://wiki.apache.org/couchdb/Installing_on_Ubuntu + +for updated instructions on how to install on Ubuntu. + +Debian-based Systems +~~~~~~~~~~~~~~~~~~~~ + +You can install the build tools by running: + + sudo apt-get install build-essential + +You can install the other dependencies by running: + + sudo apt-get install erlang libicu-dev libmozjs-dev libcurl4-openssl-dev + +Be sure to update the version numbers to match your system's available packages. + +Mac OS X +~~~~~~~~ + +You can install the build tools by running: + + open /Applications/Installers/Xcode\ Tools/XcodeTools.mpkg + +You can install the other dependencies by running: + + sudo port install icu erlang spidermonkey curl + +You will need MacPorts installed to use the `port` command. + +Installing +---------- + +Once you have satisfied the dependencies you should run: + + ./configure + +This script will configure CouchDB to be installed into `/usr/local` by default. + +If you wish to customise the installation, pass `--help` to this script. + +If everything was successful you should see the following message: + + You have configured Apache CouchDB, time to relax. + +Relax. + +To install CouchDB you should run: + + make && sudo make install + +You only need to use `sudo` if you're installing into a system directory. + +Try `gmake` if `make` is giving you any problems. + +If everything was successful you should see the following message: + + You have installed Apache CouchDB, time to relax. + +Relax. + +First Run +--------- + +You can start the CouchDB server by running: + + sudo -i -u couchdb couchdb + +This uses the `sudo` command to run the `couchdb` command as the `couchdb` user. + +When CouchDB starts it should eventually display the following message: + + Apache CouchDB has started, time to relax. + +Relax. + +To check that everything has worked, point your web browser to: + + http://127.0.0.1:5984/_utils/index.html + +From here you should run the test suite. + +Security Considerations +----------------------- + +You should create a special `couchdb` user for CouchDB. + +On many Unix-like systems you can run: + + adduser --system \ + --home /usr/local/var/lib/couchdb \ + --no-create-home \ + --shell /bin/bash \ + --group --gecos \ + "CouchDB Administrator" couchdb + +On Mac OS X you can use the Workgroup Manager to create users: + + http://www.apple.com/support/downloads/serveradmintools1047.html + +You must make sure that: + + * The user has a working POSIX shell + + * The user's home directory is `/usr/local/var/lib/couchdb` + +You can test this by: + + * Trying to log in as the `couchdb` user + + * Running `pwd` and checking the present working directory + +Change the ownership of the CouchDB directories by running: + + chown -R couchdb:couchdb /usr/local/etc/couchdb + chown -R couchdb:couchdb /usr/local/var/lib/couchdb + chown -R couchdb:couchdb /usr/local/var/log/couchdb + chown -R couchdb:couchdb /usr/local/var/run/couchdb + +Change the permission of the CouchDB directories by running: + + chmod 0770 /usr/local/etc/couchdb + chmod 0770 /usr/local/var/lib/couchdb + chmod 0770 /usr/local/var/log/couchdb + chmod 0770 /usr/local/var/run/couchdb + +Running as a Daemon +------------------- + +SysV/BSD-style Systems +~~~~~~~~~~~~~~~~~~~~~~ + +You can use the `couchdb` init script to control the CouchDB daemon. + +On SysV-style systems, the init script will be installed into: + + /usr/local/etc/init.d + +On BSD-style systems, the init script will be installed into: + + /usr/local/etc/rc.d + +We use the `[init.d|rc.d]` notation to refer to both of these directories. + +You can control the CouchDB daemon by running: + + /usr/local/etc/[init.d|rc.d]/couchdb [start|stop|restart|status] + +If you wish to configure how the init script works, you can edit: + + /usr/local/etc/default/couchdb + +Comment out the `COUCHDB_USER` setting if you're running as a non-superuser. + +To start the daemon on boot, copy the init script to: + + /etc/[init.d|rc.d] + +You should then configure your system to run the init script automatically. + +You may be able to run: + + sudo update-rc.d couchdb defaults + +If this fails, consult your system documentation for more information. + +A `logrotate` configuration is installed into: + + /usr/local/etc/logrotate.d/couchdb + +Consult your `logrotate` documentation for more information. + +It is critical that the CouchDB logs are rotated so as not to fill your disk. + +Mac OS X +~~~~~~~~ + +You can use the `launchctl` command to control the CouchDB daemon. + +You can load the configuration by running: + + sudo launchctl load \ + /usr/local/Library/LaunchDaemons/org.apache.couchdb.plist + +You can stop the CouchDB daemon by running: + + sudo launchctl unload \ + /usr/local/Library/LaunchDaemons/org.apache.couchdb.plist + +You can start CouchDB by running: + + sudo launchctl start org.apache.couchdb + +You can restart CouchDB by running: + + sudo launchctl stop org.apache.couchdb + +You can edit the launchd configuration by running: + + open /usr/local/Library/LaunchDaemons/org.apache.couchdb.plist + +To start the daemon on boot, copy the configuration file to: + + /Library/LaunchDaemons + +Consult your system documentation for more information. diff --git a/1.1.x/INSTALL.Windows b/1.1.x/INSTALL.Windows new file mode 100644 index 00000000..d2082734 --- /dev/null +++ b/1.1.x/INSTALL.Windows @@ -0,0 +1,153 @@ +Apache CouchDB README.Windows +============================== + +For a high-level guide to Microsoft Windows. + +Dependencies +------------ + +You will need the following installed: + + * Erlang OTP (=14B01) (http://erlang.org/) + * ICU (http://icu.sourceforge.net/) + * OpenSSL (http://www.openssl.org/) + * Mozilla SpiderMonkey (1.8) (http://www.mozilla.org/js/spidermonkey/) + * libcurl (http://curl.haxx.se/libcurl/) + * Cygwin (http://www.cygwin.com/) + * Visual Studio 2008 (http://msdn.microsoft.com/en-gb/vstudio/default.aspx) + +General Notes +------------- + + * When installing Erlang, you must build it from source. + + The CouchDB build makes use of a number of the Erlang build scripts. + + * When installing ICU, select the binaries built with Visual Studio 2008. + + * When installing Cygwin, be sure to select all the `development` tools. + + * When installing libcurl, be sure to install by hand. + + The Cygwin binaries are incompatible and will not work with Erlang. + +Setting Up Cygwin +----------------- + +Before starting any Cygwin terminals, run: + + set CYGWIN=nontsec + +To set up your environment, run: + + [VS_BIN]/vcvars32.bat + +Replace [VS_BIN] with the path to your Visual Studio `bin` directory. + +You must check that: + + * The `which link` command points to the Microsoft linker. + + * The `which cl` command points to the Microsoft compiler. + + * The `which mc` command points to the Microsoft message compiler. + + * The `which mt` command points to the Microsoft manifest tool. + +If you do not do this, the build may fail due to Cygwin ones found in `/usr/bin` +being used instead. + +Building Erlang +--------------- + +You must include Win32 OpenSSL. + +However, you can skip the GUI tools by running: + + echo "skipping gs" > lib/gs/SKIP + + echo "skipping ic" > lib/ic/SKIP + +Follow the rest of the Erlang instructions as described. + +After running: + + ./otp_build release -a + +You should run: + + ./release/win32/Install.exe + +This will set up the release/win32/bin directory correctly. + +To set up your environment for building CouchDB, run: + + eval `./otp_build env_win32` + +To set up the `ERL_TOP` environment variable, run: + + export ERL_TOP=[ERL_TOP] + +Replace `[ERL_TOP]` with the Erlang source directory name. + +Remember to use `/cygdrive/c/` instead of `c:/` as the directory prefix. + +To set up your path, run: + + export PATH=$ERL_TOP/release/win32/erts-5.8.2/bin:$PATH + +If everything was successful, you should be ready to build CouchDB. + +Relax. + +Building CouchDB +---------------- + +Once you have satisfied the dependencies you should run: + + ./configure \ + --with-js-include=/cygdrive/c/path_to_spidermonkey_include \ + --with-js-lib=/cygdrive/c/path_to_spidermonkey_lib \ + --with-win32-icu-binaries=/cygdrive/c/path_to_icu_binaries_root \ + --with-erlang=$ERL_TOP/release/win32/usr/include \ + --with-win32-curl=/cygdrive/c/path/to/curl/root/directory \ + --with-openssl-bin-dir=/cygdrive/c/openssl/bin \ + --with-msvc-redist-dir=/cygdrive/c/dir/with/vcredist_platform_executable \ + --prefix=$ERL_TOP/release/win32 + +This command could take a while to complete. + +If everything was successful you should see the following message: + + You have configured Apache CouchDB, time to relax. + +Relax. + +To install CouchDB you should run: + + make install + +If everything was successful you should see the following message: + + You have installed Apache CouchDB, time to relax. + +Relax. + +First Run +--------- + +You can start the CouchDB server by running: + + $ERL_TOP/release/win32/bin/couchdb.bat + +When CouchDB starts it should eventually display the following message: + + Apache CouchDB has started, time to relax. + +Relax. + +To check that everything has worked, point your web browser to: + + http://127.0.0.1:5984/_utils/index.html + +From here you should run the test suite in either Firefox 3.6+ or Safari 4+. diff --git a/1.1.x/LICENSE b/1.1.x/LICENSE new file mode 100644 index 00000000..063c9981 --- /dev/null +++ b/1.1.x/LICENSE @@ -0,0 +1,400 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +Apache CouchDB Subcomponents + +The Apache CouchDB project includes a number of subcomponents with separate +copyright notices and license terms. Your use of the code for the these +subcomponents is subject to the terms and conditions of the following licenses. + +For the m4/ac_check_icu.m4 component: + + Copyright (c) 2005 Akos Maroy + + Copying and distribution of this file, with or without modification, are + permitted in any medium without royalty provided the copyright notice + and this notice are preserved. + +For the share/www/script/jquery.js component: + + Copyright (c) 2009 John Resig, http://jquery.com/ + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +For the share/www/script/jquery-ui-1.8.11.custom.min.js and + share/www/style/jquery-ui-1.8.11.custom.css components: + + Copyright (c) 2011 Paul Bakaus, http://jqueryui.com/ + + This software consists of voluntary contributions made by many + individuals (AUTHORS.txt, http://jqueryui.com/about) For exact + contribution history, see the revision history and logs, available + at http://jquery-ui.googlecode.com/svn/ + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +For the share/www/script/jquery.form.js component: + + http://malsup.com/jquery/form/ + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +For the share/www/script/json2.js component: + + Public Domain + + No warranty expressed or implied. Use at your own risk. + +For the src/mochiweb component: + + Copyright (c) 2007 Mochi Media, Inc. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +For the src/ibrowse component: + + Copyright (c) 2006, Chandrashekhar Mullaparthi + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * 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. + * Neither the name of the T-Mobile nor the names of its contributors may be + used to endorse or promote products derived from this software without + specific prior written permission. + + 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. + +For the src/erlang-oauth component: + + Copyright (c) 2008-2009 Tim Fletcher + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, + copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following + conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + OTHER DEALINGS IN THE SOFTWARE. + +For the src/etap component: + + Copyright (c) 2008-2009 Nick Gerakines + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, + copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following + conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + OTHER DEALINGS IN THE SOFTWARE. + diff --git a/1.1.x/Makefile.am b/1.1.x/Makefile.am new file mode 100644 index 00000000..2d0bbbe6 --- /dev/null +++ b/1.1.x/Makefile.am @@ -0,0 +1,149 @@ +## Licensed under the Apache License, Version 2.0 (the "License"); you may not +## use this file except in compliance with the License. You may obtain a copy of +## the License at +## +## http://www.apache.org/licenses/LICENSE-2.0 +## +## Unless required by applicable law or agreed to in writing, software +## distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +## WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +## License for the specific language governing permissions and limitations under +## the License. + +SUBDIRS = bin etc src share test var utils + +ACLOCAL_AMFLAGS = -I m4 + +localdoc_DATA = \ + AUTHORS.gz \ + BUGS.gz \ + CHANGES.gz \ + DEVELOPERS.gz \ + INSTALL.gz \ + INSTALL.Unix.gz \ + INSTALL.Windows.gz \ + LICENSE.gz \ + NEWS.gz \ + NOTICE.gz \ + README.gz \ + THANKS.gz + +DISTCLEANFILES = $(localdoc_DATA) + +EXTRA_DIST = \ + AUTHORS \ + BUGS \ + CHANGES \ + DEVELOPERS \ + INSTALL \ + INSTALL.Unix \ + INSTALL.Windows \ + LICENSE \ + NEWS \ + NOTICE \ + README \ + THANKS \ + license.skip + +AUTHORS.gz: $(top_srcdir)/AUTHORS + -gzip -9 < $< > $@ + +BUGS.gz: $(top_srcdir)/BUGS + -gzip -9 < $< > $@ + +CHANGES.gz: $(top_srcdir)/CHANGES + -gzip -9 < $< > $@ + +DEVELOPERS.gz: $(top_srcdir)/DEVELOPERS + -gzip -9 < $< > $@ + +INSTALL.gz: $(top_srcdir)/INSTALL + -gzip -9 < $< > $@ + +INSTALL.Unix.gz: $(top_srcdir)/INSTALL.Unix + -gzip -9 < $< > $@ + +INSTALL.Windows.gz: $(top_srcdir)/INSTALL.Windows + -gzip -9 < $< > $@ + +LICENSE.gz: $(top_srcdir)/LICENSE + -gzip -9 < $< > $@ + +NEWS.gz: $(top_srcdir)/NEWS + -gzip -9 < $< > $@ + +NOTICE.gz: $(top_srcdir)/NOTICE + -gzip -9 < $< > $@ + +README.gz: $(top_srcdir)/README + -gzip -9 < $< > $@ + +THANKS.gz: $(top_srcdir)/THANKS + -gzip -9 < $< > $@ + +check: dev + $(top_builddir)/test/etap/run + +cover: dev + rm -f cover/*.coverdata + COVER=1 COVER_BIN=./src/couchdb/ $(top_builddir)/test/etap/run + SRC=./src/couchdb/ \ + $(ERL) -noshell \ + -pa src/etap \ + -eval 'etap_report:create()' \ + -s init stop > /dev/null 2>&1 + +dev: all + @echo "This command is intended for developers to use;" + @echo "it creates development ini files as well as a" + @echo "$(top_builddir)/tmp structure for development runtime files." + @echo "Use ./utils/run to launch CouchDB from the source tree." + mkdir -p $(top_builddir)/etc/couchdb/default.d + mkdir -p $(top_builddir)/etc/couchdb/local.d + mkdir -p $(top_builddir)/tmp/lib + mkdir -p $(top_builddir)/tmp/log + mkdir -p $(top_builddir)/tmp/run/couchdb + +install-data-hook: + @echo + @echo "You have installed Apache CouchDB, time to relax." + +distclean-local: + rm -fr $(top_builddir)/etc/couchdb/default.d + rm -fr $(top_builddir)/etc/couchdb/local.d + rm -fr $(top_builddir)/tmp + +.PHONY: local-clean +local-clean: maintainer-clean + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may need special tools to rebuild." + rm -f $(top_srcdir)/INSTALL + rm -f $(top_srcdir)/acinclude.m4 + rm -f $(top_srcdir)/aclocal.m4 + rm -f $(top_srcdir)/config.h.in + rm -f $(top_srcdir)/configure + rm -f $(top_srcdir)/test/etap/temp.* + rm -f $(top_srcdir)/*.tar.gz + rm -f $(top_srcdir)/*.tar.gz.* + find $(top_srcdir) -name Makefile.in -exec rm -f {} \; + +dist-hook: + find $(top_srcdir) -type f -name "._*" -exec rm -f {} \; + find $(top_builddir) -type f -name "._*" -exec rm -f {} \; + +distcheck-hook: + grep -rL 'http://www.apache.org/licenses/LICENSE-2.0' * \ + | grep -vEf license.skip; \ + test "$$?" -eq 1 + +.PHONY: distsign +distsign: distcheck check + @# @@ unpack archive and run diff -r to double check missing files + @# @@ does automake have anything that does this? + gpg --armor --detach-sig --default-key DF3CEBA3 \ + < $(top_srcdir)/$(distdir).tar.gz \ + > $(top_srcdir)/$(distdir).tar.gz.asc + md5sum $(top_srcdir)/$(distdir).tar.gz \ + > $(top_srcdir)/$(distdir).tar.gz.md5 + sha1sum $(top_srcdir)/$(distdir).tar.gz \ + > $(top_srcdir)/$(distdir).tar.gz.sha diff --git a/1.1.x/NEWS b/1.1.x/NEWS new file mode 100644 index 00000000..52e5f87b --- /dev/null +++ b/1.1.x/NEWS @@ -0,0 +1,301 @@ +Apache CouchDB NEWS +=================== + +For details about backwards incompatible changes, see: + + http://wiki.apache.org/couchdb/Breaking_changes + +Each release section notes when backwards incompatible changes have been made. + +Version 1.1.0 +------------- + +All NEWS for 1.0.2 also apply to 1.1.0. + + * Native SSL support. + * Added support for HTTP range requests for attachments. + * Added built-in filters for `_changes`: `_doc_ids` and `_design`. + * Added configuration option for TCP_NODELAY aka "Nagle". + * Allow wildcards in vhosts definitions. + * More granular ETag support for views. + * More flexible URL rewriter. + * Added OS Process module to manage daemons outside of CouchDB. + * Added HTTP Proxy handler for more scalable externals. + * Added `_replicator` database to manage replications. + * Multiple micro-optimizations when reading data. + * Added CommonJS support to map functions. + * Added `stale=update_after` query option that triggers a view update after + returning a `stale=ok` response. + * More explicit error messages when it's not possible to access a file due + to lack of permissions. + * Added a "change password"-feature to Futon. + + +Version 1.0.1 +------------- + + * Fix data corruption bug COUCHDB-844. Please see + http://couchdb.apache.org/notice/1.0.1.html for details. + * Added support for replication via an HTTP/HTTPS proxy. + * Fixed various replicator bugs for interop with older CouchDB versions. + * Show fields saved along with _deleted=true. Allows for auditing of deletes. + * Enable basic-auth popup when required to access the server, to prevent + people from getting locked out. + * User interface element for querying stale (cached) views. + +Version 1.0.0 +------------- + + * More efficient header commits. + * Use O_APPEND to save lseeks. + * Faster implementation of pread_iolist(). Further improves performance on + concurrent reads. + * Added authentication caching + * Faster default view collation. + * Added option to include update_seq in view responses. + +Version 0.11.2 +-------------- + + * Replicator buxfixes for replicating design documents from secured databases. + * Better error messages on invalid URL requests. + * User documents can now be deleted by admins or the user. + * Avoid potential DOS attack by guarding all creation of atoms. + * Some Futon and JavaScript library bugfixes. + * Fixed CVE-2010-2234: Apache CouchDB Cross Site Request Forgery Attack + +Version 0.11.1 +-------------- + + * Mask passwords in active tasks and logging. + * Update mochijson2 to allow output of BigNums not in float form. + * Added support for X-HTTP-METHOD-OVERRIDE. + * Disable jsonp by default. + * Accept gzip encoded standalone attachments. + * Made max_concurrent_connections configurable. + * Added continuous replication option to Futon. + * Added option to replicating test results anonymously to a community + CouchDB instance. + * Allow creation and deletion of config entries in Futon. + * Fixed various UI issues in Futon. + * Fixed compatibility with the Erlang R14 series. + * Fixed warnings on Linux builds. + * Fixed build error when aclocal needs to be called during the build. + * Require ICU 4.3.1. + * Fixed compatibility with Solaris. + * Added authentication redirect URL to log in clients. + * Added authentication caching, to avoid repeated opening and closing of the + users database for each request requiring authentication. + * Made authentication timeout configurable. + * Temporary views are now admin-only resources. + * Don't require a revpos for attachment stubs. + * Make file deletions async to avoid pauses during compaction and db + deletion. + * Fixed for wrong offset when writing headers and converting them to blocks, + only triggered when header is larger than 4k. + * Preserve _revs_limit and instance_start_time after compaction. + * Fixed timeout with large .ini files. + * Added tests for couch.js and jquery.couch.js + * Added various API features to jquery.couch.js + * Faster default view collation. + * Upgrade CommonJS modules support to 1.1.1. + * Added option to include update_seq in view responses. + * Fixed erlang filter funs and normalize filter fun API. + * Fixed hang in view shutdown. + * Refactored various internal APIs related to attachment streaming. + * Fixed hanging replication. + * Fixed keepalive issue. + * Allow global rewrites so system defaults are available in vhosts. + * Allow isolation of databases with vhosts. + * Made the test suite overall more reliable. + +Version 0.11.0 +-------------- + +This version is a feature-freeze release candidate for Apache CouchDB 1.0. + + * Fixed CVE-2010-0009: Apache CouchDB Timing Attack Vulnerability. + * Added support for building a Windows installer as part of 'make dist'. + * Added optional 'raw' binary collation for faster view builds where Unicode + collation is not important. + * Improved view index build time by reducing ICU collation callouts. + * Added option to implicitly create replication target databases. + * Improved view information objects. + * Bug fix for partial updates during view builds. + * Bug fix for building couch.app's module list. + * Fixed a problem with statistics timers and system sleep. + * Improved the statistics calculations to use an online moving window + algorithm. + * Adds batching of multiple updating requests, to improve throughput with many + writers. + * Removed the now redundant couch_batch_save module. + * Bug fix for premature termination of chunked responses. + * Improved speed and concurrency of config lookups. + * Fixed an edge case for HTTP redirects during replication. + * Fixed HTTP timeout handling for replication. + * Fixed query parameter handling in OAuth'd replication. + * Fixed a bug preventing mixing languages with lists and views. + * Avoid OS process leaks in lists. + * Avoid leaking file descriptors on automatic replication restarts. + * Various improvements to the Futon UI. + * Provide Content-MD5 header support for attachments. + * Added default cookie-authentication and users db. + * Added per-db reader access control lists. + * Added per-db security object for configuration data in validation functions. + * Added URL Rewriter handler. + * Added proxy authentication handler. + * Added ability to replicate documents by id. + * Added virtual host handling. + * Uses json2.js for JSON serialization compatiblity with native JSON. + * Fixed CVE-2010-0009: Apache CouchDB Timing Attack Vulnerability. + +Version 0.10.2 +-------------- + + * Fixed CVE-2010-0009: Apache CouchDB Timing Attack Vulnerability. + +Version 0.10.1 +-------------- + + * Fixed test suite to work with build system. + * Fixed a problem with statistics timers and system sleep. + * Fixed an edge case for HTTP redirects during replication. + * Fixed HTTP timeout handling for replication. + * Fixed query parameter handling in OAuth'd replication. + * Fixed a bug preventing mixing languages with lists and views. + * Avoid OS process leaks in lists. + +Version 0.10.0 +-------------- + +This release contains backwards incompatible changes, please see above for help. + + * General performance improvements. + * View index generation speedups. + * Even more robust storage format. + * Native Erlang Views for high-performance applications. + * More robust push and pull replication. + * Two-legged OAuth support for applications and replication (three-legged in + preparation). + * Cookie authentication. + * API detail improvements. + * Better RFC 2616 (HTTP 1.1) compliance. + * Added modular configuration file directories. + * Miscellaneous improvements to build, system integration, and portability. + +Version 0.9.2 +------------- + + * Remove branch callbacks to allow building couchjs against newer versions of + Spidermonkey. + * Fix replication with 0.10 servers initiated by an 0.9 server. + +Version 0.9.1 +------------- + + * Various bug fixes for the build system, configuration, statistics reporting, + database core, external handlers, Futon interface, HTTP interface, + JavaScript View Server and replicator. + +Version 0.9.0 +------------- + +This release contains backwards incompatible changes, please see above for help. + + * Modular configuration. + * Performance enhancements for document and view access. + * More resilient replication process. + * Replication streams binary attachments. + * Administrator role and basic authentication. + * Document validation functions in design documents. + * Show and list functions for rendering documents and views as developer + controlled content-types. + * External process server module. + * Attachment uploading from Futon. + * Etags for views, lists, shows, document and attachment requests. + * Miscellaneous improvements to build, system integration, and portability. + +Version 0.8.1-incubating +------------------------ + + * Various bug fixes for replication, compaction, the HTTP interface and the + JavaScript View Server. + +Version 0.8.0-incubating +------------------------ + +This release contains backwards incompatible changes, please see above for help. + + * Changed core licensing to the Apache Software License 2.0. + * Refactoring of the core view and storage engines. + * Added support for incremental map/reduce views. + * Changed database file format. + * Many improvements to Futon, the web administration interface. + * Miscellaneous improvements to build, system integration, and portability. + * Swapped out Erlang's inets HTTP server for the Mochiweb HTTP server. + * SpiderMonkey is no longer included with CouchDB, but rather treated as an + external dependency. + * Added bits of awesome. + +Version 0.7.2 +------------- + + * Small changes to build process and `couchdb` command. + * Database server official port is now 5984 TCP/UDP instead of 8888. + +Version 0.7.1 +------------- + + * Small compatibility issue with Firefox 3 fixed. + +Version 0.7.0 +------------- + + * Infrastructure rewritten to use the GNU build system for portability. + * The built-in database browsing tool has been rewritten to provide a much + nicer interface for interacting directly with CouchDB from your web browser. + * XML and Fabric have been replaced with JSON and JavaScript for data + transport and View definitions. + +Version 0.6.0 +------------- + + * A replication facility is now available. + * CouchPeek can now create, delete and view documents. + * Building from source is easier and less error prone. + +Version 0.5.0 +------------- + + * A built-in CouchPeek utility. + * A full install kit buildable from a single command. + * A new GNU/Linux version is available. An OS X version is coming soon. + +Version 0.4.0 +------------- + + * Non-existent variables are now nil lists. + * Couch error codes and messages are no longer sent in the HTTP fields, + instead they are exclusively returned in the XML body. This is to avoid HTTP + header parsing problems with oddly formed error messages. + * Returned error messages are now logged at the server at the `info` level to + make general debugging easier. + * Fixed a problem where big table builds caused timeout errors. + * Lots of changes in the low level machinery. Most formulas will continue to + function the same. + * Added full compiler support for extended characters in formula source. + * Support for Perl/Ruby like regular expressions. + * Added `total_rows` and `result_start` attributes to tables. + +Version 0.3.0 +------------- + + * CouchDB now fully supports Unicode and locale specific collation via the ICU + library, both in the Fabric engine and computed tables. + * The `in` operator has been added to Fabric. + * The `startdoc` query string variable specifies the starting document to use + if there are multiple rows with identical startkeys. + * The `skip` query string variable specifies the number of rows to skip before + returning results. The `skip` value must be a positive integer. If used with + a `count` variable the skipped rows aren't counted as output. + * Various changes to the output XML format. diff --git a/1.1.x/NOTICE b/1.1.x/NOTICE new file mode 100644 index 00000000..4daa496f --- /dev/null +++ b/1.1.x/NOTICE @@ -0,0 +1,55 @@ +Apache CouchDB +Copyright 2009 The Apache Software Foundation + +This product includes software developed at +The Apache Software Foundation (http://www.apache.org/). + +This product also includes the following third-party components: + + * ac_check_icu.m4 (http://autoconf-archive.cryp.to/ac_check_icu.html) + + Copyright 2008, Akos Maroy + + * ac_check_curl.m4 (http://autoconf-archive.cryp.to/ac_check_curl.html) + + Copyright 2008, Akos Maroy + + * jQuery (http://jquery.com/) + + Copyright 2010, John Resig + + * jQuery UI (http://jqueryui.com) + + Copyright 2011, Paul Bakaus + + * json2.js (http://www.json.org/) + + In the public domain + + * MochiWeb (http://code.google.com/p/mochiweb/) + + Copyright 2007, Mochi Media Coporation + + * ibrowse (http://github.com/cmullaparthi/ibrowse/tree/master) + + Copyright 2009, Chandrashekhar Mullaparthi + + * Erlang OAuth (http://github.com/tim/erlang-oauth/tree/master) + + Copyright 2009, Tim Fletcher + + * ETap (http://github.com/ngerakines/etap/) + + Copyright 2009, Nick Gerakines + + * mimeparse.js (http://code.google.com/p/mimeparse/) + + Copyright 2009, Chris Anderson + + * base64.js + + Copyright 1999, Masanao Izumo + + * jspec.js (http://visionmedia.github.com/jspec/) + + Copyright 2010 TJ Holowaychuk diff --git a/1.1.x/README b/1.1.x/README new file mode 100644 index 00000000..540226d3 --- /dev/null +++ b/1.1.x/README @@ -0,0 +1,81 @@ +Apache CouchDB README +===================== + +Installation +------------ + +For a low-level guide, see: + + INSTALL + +For a high-level guide to Unix-like systems, inc. Mac OS X and Ubuntu, see: + + INSTALL.Unix + +For a high-level guide to Microsoft Windows, see: + + INSTALL.Windows + +Follow the proper instructions to get CouchDB installed on your system. + +If you're having problems, skip to the next section. + +Troubleshooting +---------------- + +For troubleshooting, see: + + http://wiki.apache.org/couchdb/Troubleshooting + +If you're getting a cryptic error message, see: + + http://wiki.apache.org/couchdb/Error_messages + +For general help, see: + + http://couchdb.apache.org/community/lists.html + +The mailing lists provide a wealth of support and knowledge for you to tap into. +Feel free to drop by with your questions or discussion. See the official CouchDB +website for more information about our community resources. + + +Running the Testsuite +--------------------- + +Run the testsuite for couch.js and jquery.couch.js by browsing to this site: http://127.0.0.1:5984/_utils/spec/run.html +It should work in at least Firefox >= 3.6 and Safari >= 4.0.4. + +Read more about JSpec here: http://jspec.info/ + +Trouble shooting +~~~~~~~~~~~~~~~~ + + * When you change the specs, but your changes have no effect, manually reload the changed spec file in the browser. + + * When the spec that tests erlang views fails, make sure you have enabled erlang views as described here: + + +Cryptographic Software Notice +----------------------------- + +This distribution includes cryptographic software. The country in which you +currently reside may have restrictions on the import, possession, use, and/or +re-export to another country, of encryption software. BEFORE using any +encryption software, please check your country's laws, regulations and policies +concerning the import, possession, or use, and re-export of encryption software, +to see if this is permitted. See for more +information. + +The U.S. Government Department of Commerce, Bureau of Industry and Security +(BIS), has classified this software as Export Commodity Control Number (ECCN) +5D002.C.1, which includes information security software using or performing +cryptographic functions with asymmetric algorithms. The form and manner of this +Apache Software Foundation distribution makes it eligible for export under the +License Exception ENC Technology Software Unrestricted (TSU) exception (see the +BIS Export Administration Regulations, Section 740.13) for both object code and +source code. + +The following provides more details on the included cryptographic software: + +CouchDB includes a HTTP client (ibrowse) with SSL functionality. diff --git a/1.1.x/THANKS b/1.1.x/THANKS new file mode 100644 index 00000000..aae7991c --- /dev/null +++ b/1.1.x/THANKS @@ -0,0 +1,85 @@ +Apache CouchDB THANKS +===================== + +A number of people have contributed to Apache CouchDB by reporting problems, +suggesting improvements or submitting changes. Some of these people are: + + * William Beh + * Dirk Schalge + * Roger Leigh + * Sam Ruby + * Carlos Valiente + * Till Klampaeckel + * Jim Lindley + * Yoan Blanc + * Michael Gottesman + * Mark Baran + * Michael Hendricks + * Antony Blakey + * Paul Carey + * Hunter Morris + * Brian Palmer + * Maximillian Dornseif + * Eric Casteleijn + * Maarten Thibaut + * Florian Ebeling + * Volker Mische + * Brian Candler + * Brad Anderson + * Nick Gerakines + * Bob Dionne + * Kevin Ilchmann JĆørgensen + * Dirkjan Ochtman + * Sebastian Cohnen + * Sven Helmberger + * Dan Walters + * Curt Arnold + * Gustavo Niemeyer + * Joshua Bronson + * Kostis Sagonas + * Matthew Hooker + * Ilia Cheishvili + * Lena Herrmann + * Jack Moffit + * Damjan Georgievski + * Jan Kassens + * James Marca + * Matt Goodall + * Joel Clark + * Matt Lyon + * mikeal + * Randall Leeds + * Joscha Feth + * Jarrod Roberson + * Jae Kwon + * Gavin Sherry + * Timothy Smith + * Martin HaaƟ + * Hans Ulrich Niedermann + * Jason Smith + * Dmitry Unkovsky + * Zachary Zolton + * Brian Jenkins + * Paul Bonser + * Caleb Land + * Juhani RƤnkimies + * Kev Jackson + * Jonathan D. Knezek + * David Rose + * Lim Yue Chuan + * David Davis + * Klaus Trainer + * Dale Harvey + * Juuso VƤƤnƤnen + * Jeff Zellner + * Benjamin Young + * Gabriel Farrell + * Mike Leddy + * Felix Hummel + * Tim Smith + * Sam Bisbee + * Nathan Vander Wilt + * Caolan McMahon + + +For a list of authors see the `AUTHORS` file. diff --git a/1.1.x/acinclude.m4.in b/1.1.x/acinclude.m4.in new file mode 100644 index 00000000..e1efe10c --- /dev/null +++ b/1.1.x/acinclude.m4.in @@ -0,0 +1,30 @@ +dnl Licensed under the Apache License, Version 2.0 (the "License"); you may not +dnl use this file except in compliance with the License. dnl You may obtain a +dnl copy of the License at +dnl +dnl http://www.apache.org/licenses/LICENSE-2.0 +dnl +dnl Unless required by applicable law or agreed to in writing, software +dnl distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +dnl WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +dnl License for the specific language governing permissions and limitations +dnl under the License. + +m4_define([LOCAL_PACKAGE_AUTHOR_NAME], [The Apache Software Foundation]) +m4_define([LOCAL_PACKAGE_AUTHOR_ADDRESS], [dev@couchdb.apache.org]) +m4_define([LOCAL_PACKAGE_IDENTIFIER], [couchdb]) +m4_define([LOCAL_PACKAGE_TARNAME], [apache-couchdb]) +m4_define([LOCAL_PACKAGE_NAME], [Apache CouchDB]) +m4_define([LOCAL_BUG_URI], [https://issues.apache.org/jira/browse/COUCHDB]) +m4_define([LOCAL_VERSION_MAJOR], [1]) +m4_define([LOCAL_VERSION_MINOR], [1]) +m4_define([LOCAL_VERSION_REVISION], [0]) +m4_define([LOCAL_VERSION_STAGE], []) +m4_define([LOCAL_VERSION_RELEASE], [%release%]) +m4_define([LOCAL_VERSION_PRIMARY], + [LOCAL_VERSION_MAJOR.LOCAL_VERSION_MINOR.LOCAL_VERSION_REVISION]) +m4_define([LOCAL_VERSION_SECONDARY], + [LOCAL_VERSION_STAGE[]LOCAL_VERSION_RELEASE]) +m4_define([LOCAL_VERSION], + [LOCAL_VERSION_PRIMARY[]LOCAL_VERSION_SECONDARY]) + diff --git a/1.1.x/bin/Makefile.am b/1.1.x/bin/Makefile.am new file mode 100644 index 00000000..b8b818cb --- /dev/null +++ b/1.1.x/bin/Makefile.am @@ -0,0 +1,98 @@ +## Licensed under the Apache License, Version 2.0 (the "License"); you may not +## use this file except in compliance with the License. You may obtain a copy of +## the License at +## +## http://www.apache.org/licenses/LICENSE-2.0 +## +## Unless required by applicable law or agreed to in writing, software +## distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +## WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +## License for the specific language governing permissions and limitations under +## the License. + +if WINDOWS +bin_SCRIPTS = couchdb.bat +else +bin_SCRIPTS = couchdb couchjs +endif + +noinst_SCRIPTS = couchjs_dev + +if HELP2MAN +dist_man1_MANS = couchdb.1 couchjs.1 +endif + +CLEANFILES = $(bin_SCRIPTS) $(dist_man1_MANS) $(noinst_SCRIPTS) + +transform = @program_transform_name@ +couchdb_command_name = `echo couchdb | sed '$(transform)'` +couchjs_command_name = `echo couchjs | sed '$(transform)'` + +couchdb: couchdb.tpl + sed -e "s|%ERL%|$(ERL)|g" \ + -e "s|%ICU_CONFIG%|$(ICU_CONFIG)|g" \ + -e "s|%bindir%|@bindir@|g" \ + -e "s|%localerlanglibdir%|@localerlanglibdir@|g" \ + -e "s|%defaultini%|default.ini|g" \ + -e "s|%localini%|local.ini|g" \ + -e "s|%localconfdir%|@localconfdir@|g" \ + -e "s|%localstatelogdir%|@localstatelogdir@|g" \ + -e "s|%localstatelibdir%|@localstatelibdir@|g" \ + -e "s|%localstatedir%|@localstatedir@|g" \ + -e "s|%bug_uri%|@bug_uri@|g" \ + -e "s|%package_author_address%|@package_author_address@|g" \ + -e "s|%package_author_name%|@package_author_name@|g" \ + -e "s|%package_name%|@package_name@|g" \ + -e "s|%version%|@version@|g" \ + -e "s|%couchdb_command_name%|$(couchdb_command_name)|g" > \ + $@ < $< + chmod +x $@ + +couchjs: couchjs.tpl + sed -e "s|%locallibbindir%|@locallibbindir@|g" \ + -e "s|%bug_uri%|@bug_uri@|g" \ + -e "s|%package_author_address%|@package_author_address@|g" \ + -e "s|%package_author_name%|@package_author_name@|g" \ + -e "s|%package_name%|@package_name@|g" \ + -e "s|%version%|@version@|g" \ + -e "s|%couchjs_command_name%|$(couchjs_command_name)|g" > \ + $@ < $< + chmod +x $@ + +couchjs_dev: couchjs.tpl + sed -e "s|%locallibbindir%|$(abs_top_builddir)/src/couchdb/priv|g" \ + -e "s|%bug_uri%|@bug_uri@|g" \ + -e "s|%package_author_address%|@package_author_address@|g" \ + -e "s|%package_author_name%|@package_author_name@|g" \ + -e "s|%package_name%|@package_name@|g" \ + -e "s|%version%|@version@|g" \ + -e "s|%couchjs_command_name%|$(couchjs_command_name)|g" > \ + $@ < $< + chmod +x $@ + +couchdb.bat: couchdb.bat.tpl + sed -e "s|%ICU_CONFIG%|$(ICU_CONFIG)|g" \ + -e "s|%version%|@version@|g" \ + $< > $@ + +HELP2MAN_OPTION=--no-info --help-option="-h" --version-option="-V" + +# XXX: Because the scripts are made at build time for the user we need to +# XXX: depend on the original templates so as not to cause the rebuilding of +# XXX: the man pages. + +couchdb.1: couchdb.tpl.in + touch $@ + if test -x "$(HELP2MAN_EXECUTABLE)"; then \ + $(MAKE) -f Makefile couchdb; \ + $(HELP2MAN_EXECUTABLE) $(HELP2MAN_OPTION) \ + --name="Apache CouchDB database server" ./couchdb --output $@; \ + fi + +couchjs.1: couchjs.tpl.in + touch $@ + if test -x "$(HELP2MAN_EXECUTABLE)"; then \ + $(MAKE) -f Makefile couchjs; \ + $(HELP2MAN_EXECUTABLE) $(HELP2MAN_OPTION) \ + --name="Apache CouchDB JavaScript interpreter" ./couchjs --output $@; \ + fi diff --git a/1.1.x/bin/couchdb.bat.tpl.in b/1.1.x/bin/couchdb.bat.tpl.in new file mode 100644 index 00000000..48d78513 --- /dev/null +++ b/1.1.x/bin/couchdb.bat.tpl.in @@ -0,0 +1,26 @@ +@echo off +rem Licensed under the Apache License, Version 2.0 (the "License"); you may not +rem use this file except in compliance with the License. You may obtain a copy +rem of the License at +rem +rem http://www.apache.org/licenses/LICENSE-2.0 +rem +rem Unless required by applicable law or agreed to in writing, software +rem distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +rem WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +rem License for the specific language governing permissions and limitations +rem under the License. + +setlocal +rem First change to the drive with the erlang bin directory +%~d0 +rem then change to the erlang bin directory +cd %~dp0 + +rem Allow a different erlang executable (eg, erl) to be used. +rem When using erl instead of werl, server restarts during test runs can fail +rem intermittently. But using erl should be fine for production use. +if "%ERL%x" == "x" set ERL=werl.exe + +echo CouchDB %version% - prepare to relax... +%ERL% -sasl errlog_type error -s couch diff --git a/1.1.x/bin/couchdb.tpl.in b/1.1.x/bin/couchdb.tpl.in new file mode 100644 index 00000000..94d47439 --- /dev/null +++ b/1.1.x/bin/couchdb.tpl.in @@ -0,0 +1,330 @@ +#! /bin/sh -e + +# Licensed under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. + +BACKGROUND=false +DEFAULT_CONFIG_DIR=%localconfdir%/default.d +DEFAULT_CONFIG_FILE=%localconfdir%/%defaultini% +ERL_START_OPTIONS="-sasl errlog_type error +K true +A 4" +HEART_BEAT_TIMEOUT=11 +HEART_COMMAND="%bindir%/%couchdb_command_name% -k" +INTERACTIVE=false +KILL=false +LOCAL_CONFIG_DIR=%localconfdir%/local.d +LOCAL_CONFIG_FILE=%localconfdir%/%localini% +PID_FILE=%localstatedir%/run/couchdb/couchdb.pid +RECURSED=false +RESET_CONFIG=true +RESPAWN_TIMEOUT=0 +SCRIPT_ERROR=1 +SCRIPT_OK=0 +SHUTDOWN=false +STDERR_FILE=couchdb.stderr +STDOUT_FILE=couchdb.stdout + +print_arguments="" +start_arguments="" +background_start_arguments="" + +basename=`basename $0` + +display_version () { + cat << EOF +$basename - %package_name% %version% + +Licensed under the Apache License, Version 2.0 (the "License"); you may not use +this file except in compliance with the License. You may obtain a copy of the +License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed +under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +CONDITIONS OF ANY KIND, either express or implied. See the License for the +specific language governing permissions and limitations under the License. + +EOF +} + +display_help () { + cat << EOF +Usage: $basename [OPTION] + +The $basename command runs the %package_name% server. + +Erlang is called with: + + $ERL_START_OPTIONS + +Erlang inherits the environment of this command. + +You can override these options using the environment: + + ERL_AFLAGS, ERL_FLAGS, ERL_ZFLAGS + +See erl(1) for more information about the environment variables. + +The exit status is 0 for success or 1 for failure. + +Options: + + -h display a short help message and exit + -V display version information and exit + -a FILE add configuration FILE to chain + -A DIR add configuration DIR to chain + -n reset configuration file chain (including system default) + -c print configuration file chain and exit + -i use the interactive Erlang shell + -b spawn as a background process + -p FILE set the background PID FILE (overrides system default) + -r SECONDS respawn background process after SECONDS (defaults to no respawn) + -o FILE redirect background stdout to FILE (defaults to $STDOUT_FILE) + -e FILE redirect background stderr to FILE (defaults to $STDERR_FILE) + -s display the status of the background process + -k kill the background process, will respawn if needed + -d shutdown the background process + +Report bugs at <%bug_uri%>. +EOF +} + +display_error () { + if test -n "$1"; then + echo $1 >&2 + fi + echo >&2 + echo "Try \`"$basename" -h' for more information." >&2 + false +} + +_get_pid () { + if test -f $PID_FILE; then + PID=`cat $PID_FILE` + fi + echo $PID +} + +_add_config_file () { + if test -z "$print_arguments"; then + print_arguments="$1" + else + print_arguments="`cat < /dev/null; then + echo "Apache CouchDB is running as process $PID, time to relax." + return $SCRIPT_OK + else + echo >&2 << EOF +Apache CouchDB is not running but a stale PID file exists: $PID_FILE" +EOF + fi + else + echo "Apache CouchDB is not running." >&2 + fi + return $SCRIPT_ERROR +} + +check_environment () { + if test "$BACKGROUND" != "true"; then + return + fi + touch $PID_FILE 2> /dev/null || true + touch $STDOUT_FILE 2> /dev/null || true + touch $STDERR_FILE 2> /dev/null || true + message_prefix="Apache CouchDB needs write permission on the" + if test ! -w $PID_FILE; then + echo "$message_prefix PID file: $PID_FILE" >&2 + false + fi + if test ! -w $STDOUT_FILE; then + echo "$message_prefix STDOUT file: $STDOUT_FILE" >&2 + false + fi + if test ! -w $STDERR_FILE; then + echo "$message_prefix STDERR file: $STDERR_FILE" >&2 + false + fi + message_prefix="Apache CouchDB needs a regular" + if test `echo 2> /dev/null >> $PID_FILE; echo $?` -gt 0; then + echo "$message_prefix PID file: $PID_FILE" >&2 + false + fi + if test `echo 2> /dev/null >> $STDOUT_FILE; echo $?` -gt 0; then + echo "$message_prefix STDOUT file: $STDOUT_FILE" >&2 + false + fi + if test `echo 2> /dev/null >> $STDERR_FILE; echo $?` -gt 0; then + echo "$message_prefix STDERR file: $STDERR_FILE" >&2 + false + fi +} + +start_couchdb () { + if test ! "$RECURSED" = "true"; then + if check_status 2> /dev/null; then + exit + fi + check_environment + fi + interactive_option="+Bd -noinput" + if test "$INTERACTIVE" = "true"; then + interactive_option="" + fi + if test "$BACKGROUND" = "true"; then + touch $PID_FILE + interactive_option="+Bd -noinput" + fi + command="%ERL% $interactive_option $ERL_START_OPTIONS \ + -env ERL_LIBS %localerlanglibdir% -couch_ini $start_arguments -s couch" + if test "$BACKGROUND" = "true" -a "$RECURSED" = "false"; then + $0 $background_start_arguments -b -r $RESPAWN_TIMEOUT -p $PID_FILE \ + -o $STDOUT_FILE -e $STDERR_FILE -R & + echo "Apache CouchDB has started, time to relax." + else + if test "$RECURSED" = "true"; then + while true; do + export HEART_COMMAND + export HEART_BEAT_TIMEOUT + `eval $command -pidfile $PID_FILE -heart \ + >> $STDOUT_FILE 2>> $STDERR_FILE` || true + PID=`_get_pid` + if test -n "$PID"; then + if kill -0 $PID 2> /dev/null; then + return $SCRIPT_ERROR + fi + else + return $SCRIPT_OK + fi + if test "$RESPAWN_TIMEOUT" = "0"; then + return $SCRIPT_OK + fi + if test "$RESPAWN_TIMEOUT" != "1"; then + plural_ending="s" + fi + cat << EOF +Apache CouchDB crashed, restarting in $RESPAWN_TIMEOUT second$plural_ending. +EOF + sleep $RESPAWN_TIMEOUT + done + else + eval exec $command + fi + fi +} + +stop_couchdb () { + PID=`_get_pid` + if test -n "$PID"; then + if test "$1" = "false"; then + echo > $PID_FILE + fi + if kill -0 $PID 2> /dev/null; then + if kill -1 $PID 2> /dev/null; then + if test "$1" = "false"; then + echo "Apache CouchDB has been shutdown." + else + echo "Apache CouchDB has been killed." + fi + return $SCRIPT_OK + else + echo "Apache CouchDB could not be killed." >&2 + return $SCRIPT_ERROR + fi + if test "$1" = "false"; then + echo "Stale PID file exists but Apache CouchDB is not running." + else + echo "Stale PID file existed but Apache CouchDB is not running." + fi + fi + else + echo "Apache CouchDB is not running." + fi +} + +parse_script_option_list () { + _load_config + set +e + options=`getopt hVa:A:ncibp:r:Ro:e:skd $@` + if test ! $? -eq 0; then + display_error + fi + set -e + eval set -- $options + while [ $# -gt 0 ]; do + case "$1" in + -h) shift; display_help; exit;; + -V) shift; display_version; exit;; + -a) shift; _add_config_file "$1"; shift;; + -A) shift; _add_config_dir "$1"; shift;; + -n) shift; _reset_config;; + -c) shift; _print_config; exit;; + -i) shift; INTERACTIVE=true;; + -b) shift; BACKGROUND=true;; + -r) shift; RESPAWN_TIMEOUT=$1; shift;; + -R) shift; RECURSED=true;; + -p) shift; PID_FILE=$1; shift;; + -o) shift; STDOUT_FILE=$1; shift;; + -e) shift; STDERR_FILE=$1; shift;; + -s) shift; check_status; exit;; + -k) shift; KILL=true;; + -d) shift; SHUTDOWN=true;; + --) shift; break;; + *) display_error "Unknown option: $1" >&2;; + esac + done + if test "$KILL" = "true" -o "$SHUTDOWN" = "true"; then + stop_couchdb $KILL + else + start_couchdb + fi +} + +parse_script_option_list $@ diff --git a/1.1.x/bin/couchjs.tpl.in b/1.1.x/bin/couchjs.tpl.in new file mode 100644 index 00000000..6927a0d4 --- /dev/null +++ b/1.1.x/bin/couchjs.tpl.in @@ -0,0 +1,92 @@ +#! /bin/sh -e + +# Licensed under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. + +SCRIPT_OK=0 +SCRIPT_ERROR=1 + +DEFAULT_VERSION=170 + +basename=`basename $0` + +display_version () { + cat << EOF +$basename - %package_name% %version% + +Licensed under the Apache License, Version 2.0 (the "License"); you may not use +this file except in compliance with the License. You may obtain a copy of the +License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed +under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +CONDITIONS OF ANY KIND, either express or implied. See the License for the +specific language governing permissions and limitations under the License. +EOF +} + +display_help () { + cat << EOF +Usage: $basename [FILE] + +The $basename command runs the %package_name% JavaScript interpreter. + +The exit status is 0 for success or 1 for failure. + +Options: + + -h display a short help message and exit + -V display version information and exit + +Report bugs at <%bug_uri%>. +EOF +} + +display_error () { + if test -n "$1"; then + echo $1 >&2 + fi + echo >&2 + echo "Try \`"$basename" -h' for more information." >&2 + exit $SCRIPT_ERROR +} + +run_couchjs () { + exec %locallibbindir%/%couchjs_command_name% $@ +} + +parse_script_option_list () { + set +e + options=`getopt hV $@` + if test ! $? -eq 0; then + display_error + fi + set -e + eval set -- $options + while [ $# -gt 0 ]; do + case "$1" in + -h) shift; display_help; exit $SCRIPT_OK;; + -V) shift; display_version; exit $SCRIPT_OK;; + --) shift; break;; + *) break;; + esac + done + option_list=`echo $@ | sed 's/--//'` + if test -z "$option_list"; then + display_error "You must specify a FILE." + fi + run_couchjs $option_list +} + +parse_script_option_list $@ diff --git a/1.1.x/bootstrap b/1.1.x/bootstrap new file mode 100755 index 00000000..0c576c40 --- /dev/null +++ b/1.1.x/bootstrap @@ -0,0 +1,68 @@ +#!/bin/sh -e + +# Licensed under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. + +get () { + variable_name=$1 + echo "changequote(\`[', \`]')" > acinclude.m4.tmp + sed -e "s/m4_//" < acinclude.m4.in >> acinclude.m4.tmp + echo $variable_name >> acinclude.m4.tmp + if test -x "`which gm4 2> /dev/null || true`"; then + gm4 acinclude.m4.tmp | grep -v "^$" || true + else + if test -x "`which m4 2> /dev/null || true`"; then + m4 acinclude.m4.tmp | grep -v "^$" || true + else + echo unknown + fi + fi + rm -f acinclude.m4.tmp +} + +mkdir -p build-aux + +if test -z "$REVISION"; then + if test -d .git; then + REVISION=`git log --pretty="format:%h" | head -1`-git + else + # default to svn + REVISION=`\`which svn\` info . 2> /dev/null | awk "/Revision:/{print \\$2}"` + fi +fi +if test -z "`get LOCAL_VERSION_STAGE`" -o -z "$REVISION"; then + sed "s/%release%//" < acinclude.m4.in > acinclude.m4 +else + sed "s/%release%/$REVISION/" < acinclude.m4.in > acinclude.m4 +fi + +gunzip -c m4/ac_check_icu.m4.gz > m4/ac_check_icu.m4 +gunzip -c m4/ac_check_curl.m4.gz > m4/ac_check_curl.m4 + +if test -x "`which glibtoolize 2> /dev/null || true`"; then + glibtoolize -f -c --automake +else + libtoolize -f -c --automake +fi + +aclocal -I m4 +autoheader -f +automake -f -a 2>&1 | sed -e "/install/d" +autoconf -f + +ln -f -s "`dirname \`readlink build-aux/missing\``/INSTALL" + +cat << EOF +You have bootstrapped Apache CouchDB, time to relax. + +Run \`./configure' to configure the source before you install. +EOF diff --git a/1.1.x/configure.ac b/1.1.x/configure.ac new file mode 100644 index 00000000..b776a258 --- /dev/null +++ b/1.1.x/configure.ac @@ -0,0 +1,440 @@ +dnl Licensed under the Apache License, Version 2.0 (the "License"); you may not +dnl use this file except in compliance with the License. dnl You may obtain a +dnl copy of the License at +dnl +dnl http://www.apache.org/licenses/LICENSE-2.0 +dnl +dnl Unless required by applicable law or agreed to in writing, software +dnl distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +dnl WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +dnl License for the specific language governing permissions and limitations +dnl under the License. + +AC_INIT([LOCAL_PACKAGE_NAME], [LOCAL_VERSION], [], [LOCAL_PACKAGE_TARNAME]) + +AC_PREREQ([2.59]) + +AC_CONFIG_SRCDIR([CHANGES]) +AC_CONFIG_AUX_DIR([build-aux]) +AC_CONFIG_MACRO_DIR([m4]) + +AM_CONFIG_HEADER([config.h]) + +AM_INIT_AUTOMAKE([1.6.3 foreign]) + +AC_GNU_SOURCE +AC_ENABLE_SHARED +AC_DISABLE_STATIC + +AC_PROG_CC +AC_PROG_LIBTOOL +AC_PROG_LN_S + +AC_MSG_CHECKING([for pthread_create in -lpthread]) + +original_LIBS="$LIBS" +LIBS="-lpthread $original_LIBS" + +AC_TRY_LINK([#include], + [pthread_create((void *)0, (void *)0, (void *)0, (void *)0)], + [pthread=yes], [pthread=no]) + +if test x${pthread} = xyes; then + AC_MSG_RESULT([yes]) +else + LIBS="$original_LIBS" + AC_MSG_RESULT([no]) +fi + +AC_ARG_WITH([erlang], [AC_HELP_STRING([--with-erlang=PATH], + [set PATH to the Erlang include directory])], [ + ERLANG_FLAGS="-I$withval" +], [ + ERLANG_FLAGS="-I${libdir}/erlang/usr/include" + ERLANG_FLAGS="$ERLANG_FLAGS -I/usr/lib/erlang/usr/include" + ERLANG_FLAGS="$ERLANG_FLAGS -I/usr/local/lib/erlang/usr/include" + ERLANG_FLAGS="$ERLANG_FLAGS -I/opt/local/lib/erlang/usr/include" +]) + +AC_ARG_WITH([js-include], [AC_HELP_STRING([--with-js-include=PATH], + [set PATH to the SpiderMonkey include directory])], [ + JS_INCLUDE="$withval" + JS_FLAGS="-I$JS_INCLUDE" +], [ + JS_FLAGS="-I/usr/include" + JS_FLAGS="$JS_FLAGS -I/usr/include/js" + JS_FLAGS="$JS_FLAGS -I/usr/include/mozjs" + JS_FLAGS="$JS_FLAGS -I/usr/local/include" + JS_FLAGS="$JS_FLAGS -I/opt/local/include" + JS_FLAGS="$JS_FLAGS -I/usr/local/include/js" + JS_FLAGS="$JS_FLAGS -I/opt/local/include/js" +]) + +AC_ARG_WITH([js-lib], [AC_HELP_STRING([--with-js-lib=PATH], + [set PATH to the SpiderMonkey library directory])], + [ + JS_LIB_DIR=$withval + JS_LIB_FLAGS="-L$withval" +], [ + JS_LIB_DIR= +]) +AC_SUBST(JS_LIB_DIR) + +AC_ARG_VAR([ERLC_FLAGS], [general flags to prepend to ERLC_FLAGS]) +AC_ARG_VAR([FLAGS], [general flags to prepend to LDFLAGS and CPPFLAGS]) + +LIB_FLAGS="$JS_LIB_FLAGS -L/usr/local/lib -L/opt/local/lib" +LIBS="$LIB_FLAGS $LIBS" + +case "$(uname -s)" in + CYGWIN*) + FLAGS="$LIB_FLAGS $ERLANG_FLAGS $JS_FLAGS -DXP_WIN $FLAGS" + CPPFLAGS="$FLAGS $CPPFLAGS" + LDFLAGS="$FLAGS $LDFLAGS" + IS_WINDOWS="TRUE" + # The erlang cc.sh/ld.sh scripts will convert a -O option + # into the same optimization flags erlang itself uses. + CFLAGS="-O2" + LTCFLAGS="$CFLAGS" + ;; + *) + # XP_UNIX required for jsapi.h and has been tested to work on Linux and Darwin. + FLAGS="$LIB_FLAGS $ERLANG_FLAGS $JS_FLAGS -DXP_UNIX $FLAGS" + CPPFLAGS="$FLAGS $CPPFLAGS" + # manually linking libm is requred for FreeBSD 7.0 + LDFLAGS="$FLAGS -lm $LDFLAGS" + ;; +esac + +AM_CONDITIONAL([WINDOWS], [test x$IS_WINDOWS = xTRUE]) + +AC_CHECK_LIB([mozjs], [JS_NewContext], [JS_LIB_BASE=mozjs], [ + AC_CHECK_LIB([js], [JS_NewContext], [JS_LIB_BASE=js], [ + AC_CHECK_LIB([js3250], [JS_NewContext], [JS_LIB_BASE=js3250], [ + AC_CHECK_LIB([js32], [JS_NewContext], [JS_LIB_BASE=js32], [ + AC_MSG_ERROR([Could not find the js library. + +Is the Mozilla SpiderMonkey library installed?])])])])]) + +AC_SUBST(JS_LIB_BASE) + +if test x${IS_WINDOWS} = xTRUE; then + if test -f "$JS_LIB_DIR/$JS_LIB_BASE.dll"; then + # seamonkey 1.7- build layout on Windows + JS_LIB_BINARY="$JS_LIB_DIR/$JS_LIB_BASE.dll" + else + # seamonkey 1.8+ build layout on Windows + if test -f "$JS_LIB_DIR/../bin/$JS_LIB_BASE.dll"; then + JS_LIB_BINARY="$JS_LIB_DIR/../bin/$JS_LIB_BASE.dll" + else + AC_MSG_ERROR([Could not find $JS_LIB_BASE.dll.]) + fi + fi + AC_SUBST(JS_LIB_BINARY) + + # On windows we need to know the path to the openssl binaries. + AC_ARG_WITH([openssl-bin-dir], [AC_HELP_STRING([--with-openssl-bin-dir=PATH], + [path to the open ssl binaries for distribution on Windows])], [ + openssl_bin_dir=`cygpath -m "$withval"` + AC_SUBST(openssl_bin_dir) + ], []) + + # Windows uses Inno setup - look for its compiler. + AC_PATH_PROG([INNO_COMPILER_EXECUTABLE], [iscc]) + if test x${INNO_COMPILER_EXECUTABLE} = x; then + AC_MSG_WARN([You will be unable to build the Windows installer.]) + fi + + # We need the msvc redistributables for this platform too + # (in theory we could just install the assembly locally - but + # there are at least 4 directories with binaries, meaning 4 copies; + # so using the redist .exe means it ends up installed globally...) + AC_ARG_WITH([msvc-redist-dir], [AC_HELP_STRING([--with-msvc-redist-dir=PATH], + [path to the msvc redistributables for the Windows platform])], [ + msvc_redist_dir=`cygpath -m "$withval"` + msvc_redist_name="vcredist_x86.exe" + AC_SUBST(msvc_redist_dir) + AC_SUBST(msvc_redist_name) + ], []) + if test ! -f ${msvc_redist_dir}/${msvc_redist_name}; then + AC_MSG_WARN([The MSVC redistributable seems to be missing; expect the installer to fail.]) + fi +fi + +JSLIB=-l$JS_LIB_BASE + +AC_CHECK_HEADER([jsapi.h], [], [ + AC_CHECK_HEADER([js/jsapi.h], + [ + CPPFLAGS="$CPPFLAGS -I$JS_INCLUDE/js" + ], + [ + AC_MSG_ERROR([Could not find the jsapi header. + +Are the Mozilla SpiderMonkey headers installed?]) + ])]) + +AC_SUBST(JSLIB) + +AC_LANG_PUSH(C) +OLD_CFLAGS="$CFLAGS" +CFLAGS="-Werror-implicit-function-declaration" +AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[#include ]], + [[JS_SetOperationCallback(0, 0);]] + )], + AC_DEFINE([USE_JS_SETOPCB], [], [Use new JS_SetOperationCallback]) +) +CFLAGS="$OLD_CFLAGS" +AC_LANG_POP(C) + +AC_ARG_WITH([win32-icu-binaries], [AC_HELP_STRING([--with-win32-icu-binaries=PATH], + [set PATH to the Win32 native ICU binaries directory])], [ + ICU_CONFIG="" # supposed to be a command to query options... + ICU_LOCAL_CFLAGS="-I$withval/include" + ICU_LOCAL_LDFLAGS="-L$withval/lib" + ICU_LOCAL_BIN=$withval/bin +], [ + AC_CHECK_ICU([3.4.1]) + ICU_LOCAL_CFLAGS=`$ICU_CONFIG --cppflags-searchpath` + ICU_LOCAL_LDFLAGS=`$ICU_CONFIG --ldflags-searchpath` + ICU_LOCAL_BIN= +]) + +AC_SUBST(ICU_CONFIG) +AC_SUBST(ICU_LOCAL_CFLAGS) +AC_SUBST(ICU_LOCAL_LDFLAGS) +AC_SUBST(ICU_LOCAL_BIN) + +AC_ARG_WITH([win32-curl], [AC_HELP_STRING([--with-win32-curl=PATH], + [set PATH to the Win32 native curl directory])], [ + # default build on windows is a static lib, and that's what we want too + CURL_CFLAGS="-I$withval/include -DCURL_STATICLIB" + CURL_LIBS="$withval/lib/libcurl" + CURL_LDFLAGS="-l$CURL_LIBS -lWs2_32 -lkernel32 -luser32 -ladvapi32 -lWldap32" +], [ + AC_CHECK_CURL([7.18.0]) + CURL_LDFLAGS=-lcurl +]) + +AC_SUBST(CURL_CFLAGS) +AC_SUBST(CURL_LIBS) +AC_SUBST(CURL_LDFLAGS) + +case "$(uname -s)" in + Linux) + LIBS="$LIBS -lcrypt" + CPPFLAGS="-D_XOPEN_SOURCE $CPPFLAGS" + ;; + FreeBSD) + LIBS="$LIBS -lcrypt" + ;; + OpenBSD) + LIBS="$LIBS -lcrypto" + ;; +esac + +AC_PATH_PROG([ERL], [erl]) + +if test x${ERL} = x; then + AC_MSG_ERROR([Could not find the `erl' executable. Is Erlang installed?]) +fi + +erlang_version_error="The installed Erlang version is less than 5.6.5 (R12B05)." + +version="`${ERL} -version 2>&1 | ${SED} "s/[[^0-9]]/ /g"`" + +if test `echo $version | ${AWK} "{print \\$1}"` -lt 5; then + AC_MSG_ERROR([$erlang_version_error]) +fi + +if test `echo $version | ${AWK} "{print \\$2}"` -lt 6; then + AC_MSG_ERROR([$erlang_version_error]) +fi + +if test `echo $version | ${AWK} "{print \\$2}"` -eq 6; then + if test `echo $version | ${AWK} "{print \\$3}"` -lt 5; then + AC_MSG_ERROR([$erlang_version_error]) + fi +fi + +has_crypto=`${ERL} -eval "case application:load(crypto) of ok -> ok; _ -> exit(no_crypto) end." -noshell -s init stop` + +if test -n "$has_crypto"; then + AC_MSG_ERROR([Could not find the Erlang crypto library. Has Erlang been compiled with OpenSSL support?]) +fi + +AC_PATH_PROG([ERLC], [erlc]) + +if test x${ERLC} = x; then + AC_MSG_ERROR([Could not find the `erlc' executable. Is Erlang installed?]) +fi + +AC_CHECK_HEADER([erl_driver.h], [], [ + AC_MSG_ERROR([Could not find the `erl_driver.h' header. + +Are the Erlang headers installed? Use the `--with-erlang' option to specify the +path to the Erlang include directory.])]) + +AC_PATH_PROG([HELP2MAN_EXECUTABLE], [help2man]) +if test x${HELP2MAN_EXECUTABLE} = x; then + AC_MSG_WARN([You will be unable to regenerate any man pages.]) +fi + +use_init=yes +use_launchd=yes + +AC_ARG_ENABLE([init], [AC_HELP_STRING([--disable-init], + [don't install init script where applicable])], [ + use_init=$enableval +], []) + +AC_ARG_ENABLE([launchd], [AC_HELP_STRING([--disable-launchd], + [don't install launchd configuration where applicable])], [ + use_launchd=$enableval +], []) + +init_enabled=false +launchd_enabled=false + +if test "$use_init" = "yes"; then + AC_MSG_CHECKING(location of init directory) + if test -d /etc/rc.d; then + init_enabled=true + AC_SUBST([initdir], ['${sysconfdir}/rc.d']) + AC_MSG_RESULT(${initdir}) + else + if test -d /etc/init.d; then + init_enabled=true + AC_SUBST([initdir], ['${sysconfdir}/init.d']) + AC_MSG_RESULT(${initdir}) + else + AC_MSG_RESULT(not found) + fi + fi +fi + +if test "$use_launchd" = "yes"; then + AC_MSG_CHECKING(location of launchd directory) + if test -d /Library/LaunchDaemons; then + init_enabled=false + launchd_enabled=true + AC_SUBST([launchddir], ['${prefix}/Library/LaunchDaemons']) + AC_MSG_RESULT(${launchddir}) + else + AC_MSG_RESULT(not found) + fi +fi + +AC_ARG_VAR([ERL], [path to the `erl' executable]) +AC_ARG_VAR([ERLC], [path to the `erlc' executable]) +AC_ARG_VAR([HELP2MAN_EXECUTABLE], [path to the `help2man' program]) + +if test -n "$HELP2MAN_EXECUTABLE"; then + help2man_enabled=true +else + if test -f "$srcdir/bin/couchdb.1" -a -f "$srcdir/bin/couchjs.1"; then + help2man_enabled=true + else + help2man_enabled=false + fi +fi + +AM_CONDITIONAL([INIT], [test x${init_enabled} = xtrue]) +AM_CONDITIONAL([LAUNCHD], [test x${launchd_enabled} = xtrue]) +AM_CONDITIONAL([HELP2MAN], [test x${help2man_enabled} = xtrue]) + +AC_SUBST([package_author_name], ["LOCAL_PACKAGE_AUTHOR_NAME"]) +AC_SUBST([package_author_address], ["LOCAL_PACKAGE_AUTHOR_ADDRESS"]) +AC_SUBST([package_identifier], ["LOCAL_PACKAGE_IDENTIFIER"]) +AC_SUBST([package_tarname], ["LOCAL_PACKAGE_TARNAME"]) +AC_SUBST([package_name], ["LOCAL_PACKAGE_NAME"]) + +AC_SUBST([version], ["LOCAL_VERSION"]) +AC_SUBST([version_major], ["LOCAL_VERSION_MAJOR"]) +AC_SUBST([version_minor], ["LOCAL_VERSION_MINOR"]) +AC_SUBST([version_revision], ["LOCAL_VERSION_REVISION"]) +AC_SUBST([version_stage], ["LOCAL_VERSION_STAGE"]) +AC_SUBST([version_release], ["LOCAL_VERSION_RELEASE"]) + +AC_SUBST([bug_uri], ["LOCAL_BUG_URI"]) + +AC_SUBST([localconfdir], [${sysconfdir}/${package_identifier}]) +AC_SUBST([localdatadir], [${datadir}/${package_identifier}]) +AC_SUBST([localdocdir], [${datadir}/doc/${package_identifier}]) +AC_SUBST([locallibdir], [${libdir}/${package_identifier}]) +AC_SUBST([localstatelibdir], [${localstatedir}/lib/${package_identifier}]) +AC_SUBST([localstatelogdir], [${localstatedir}/log/${package_identifier}]) +AC_SUBST([localstaterundir], [${localstatedir}/run/${package_identifier}]) + +# On Windows we install directly into our erlang distribution. +if test x${IS_WINDOWS} = xTRUE; then + AC_SUBST([locallibbindir], [${prefix}/bin]) + AC_SUBST([localerlanglibdir], [${libdir}]) +else + AC_SUBST([locallibbindir], [${locallibdir}/bin]) + AC_SUBST([localerlanglibdir], [${locallibdir}/erlang/lib]) +fi + +# fix for older autotools that don't define "abs_top_YYY" by default +AC_SUBST(abs_top_srcdir) +AC_SUBST(abs_top_builddir) + +AC_REVISION([LOCAL_VERSION]) + +AC_CONFIG_FILES([Makefile]) +AC_CONFIG_FILES([bin/couchjs.tpl]) +AC_CONFIG_FILES([bin/couchdb.tpl]) +AC_CONFIG_FILES([bin/couchdb.bat.tpl]) +AC_CONFIG_FILES([bin/Makefile]) +AC_CONFIG_FILES([etc/couchdb/Makefile]) +AC_CONFIG_FILES([etc/couchdb/default.ini.tpl]) +AC_CONFIG_FILES([etc/default/Makefile]) +AC_CONFIG_FILES([etc/init/couchdb.tpl]) +AC_CONFIG_FILES([etc/init/Makefile]) +AC_CONFIG_FILES([etc/launchd/org.apache.couchdb.plist.tpl]) +AC_CONFIG_FILES([etc/launchd/Makefile]) +AC_CONFIG_FILES([etc/logrotate.d/couchdb.tpl]) +AC_CONFIG_FILES([etc/logrotate.d/Makefile]) +AC_CONFIG_FILES([etc/windows/Makefile]) +AC_CONFIG_FILES([etc/Makefile]) +AC_CONFIG_FILES([share/Makefile]) +AC_CONFIG_FILES([src/Makefile]) +AC_CONFIG_FILES([src/couchdb/couch.app.tpl]) +AC_CONFIG_FILES([src/couchdb/Makefile]) +AC_CONFIG_FILES([src/couchdb/priv/Makefile]) +AC_CONFIG_FILES([src/erlang-oauth/Makefile]) +AC_CONFIG_FILES([src/etap/Makefile]) +AC_CONFIG_FILES([src/ibrowse/Makefile]) +AC_CONFIG_FILES([src/mochiweb/Makefile]) +AC_CONFIG_FILES([test/Makefile]) +AC_CONFIG_FILES([test/bench/Makefile]) +AC_CONFIG_FILES([test/etap/Makefile]) +AC_CONFIG_FILES([test/etap/test_util.erl]) +AC_CONFIG_FILES([test/javascript/Makefile]) +AC_CONFIG_FILES([test/view_server/Makefile]) +AC_CONFIG_FILES([utils/Makefile]) +AC_CONFIG_FILES([var/Makefile]) + +AC_OUTPUT + +# *sob* - on Windows libtool fails as 'libname_spec' isn't correct (it +# expects GNU style lib names). I can't work out how to configure this +# option sanely, so we pass the script through sed to modify it. +# Also, the erlang cc.sh script doesn't cope well with the '-link' command +# line option libtool provides. +# PLEASE, someone help put this out of its misery!! +# This hackery is being tracked via COUCHDB-440. +if test x${IS_WINDOWS} = xTRUE; then + sed -e 's,libname_spec="lib\\$name",libname_spec="\\\$name",' \ + -e 's,-link,,' \ + < libtool > libtool.tmp + mv libtool.tmp libtool + # probably would chmod +x if we weren't on windows... +fi + +echo +echo "You have configured Apache CouchDB, time to relax." +echo +echo "Run \`make && sudo make install' to install." diff --git a/1.1.x/etc/Makefile.am b/1.1.x/etc/Makefile.am new file mode 100644 index 00000000..148f7015 --- /dev/null +++ b/1.1.x/etc/Makefile.am @@ -0,0 +1,117 @@ +## Licensed under the Apache License, Version 2.0 (the "License"); you may not +## use this file except in compliance with the License. You may obtain a copy of +## the License at +## +## http://www.apache.org/licenses/LICENSE-2.0 +## +## Unless required by applicable law or agreed to in writing, software +## distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +## WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +## License for the specific language governing permissions and limitations under +## the License. + +SUBDIRS = couchdb default init launchd logrotate.d windows + +default_sysconf_data = logrotate.d/couchdb + +if INIT +init_sysconf_data = default/couchdb +init_DATA = init/couchdb +endif + +if LAUNCHD +launchd_DATA = launchd/org.apache.couchdb.plist +endif + +nobase_sysconf_DATA = $(default_sysconf_data) $(init_sysconf_data) + +EXTRA_DIST = \ + default/couchdb \ + windows/couchdb.iss.tpl \ + windows/README.txt.tpl + +if WINDOWS +EXTRA_DIST += \ + windows/setup-couchdb-@version@.exe.md5 \ + windows/setup-couchdb-@version@.exe.sha +endif + +CLEANFILES = $(init_DATA) $(default_sysconf_data) $(launchd_DATA) + +transform = @program_transform_name@ +couchdb_command_name = `echo couchdb | sed '$(transform)'` + +init/couchdb: init/couchdb.tpl + if test "$(mkdir_p)"; then \ + $(mkdir_p) init; \ + else \ + if test ! -d init; then \ + mkdir init; \ + fi \ + fi + sed -e "s|%configure_input%|$@. Generated from $< by configure.|" \ + -e "s|%bindir%|$(bindir)|" \ + -e "s|%sysconfdir%|$(sysconfdir)|" \ + -e "s|%localstaterundir%|$(localstaterundir)|" \ + -e "s|%couchdb_command_name%|$(couchdb_command_name)|" \ + < $< > $@ + +logrotate.d/couchdb: logrotate.d/couchdb.tpl + sed -e "s|%localstatelogdir%|@localstatelogdir@|g" < $< > $@ + +launchd/org.apache.couchdb.plist: launchd/org.apache.couchdb.plist.tpl + if test "$(mkdir_p)"; then \ + $(mkdir_p) launchd; \ + else \ + if test ! -d launchd; then \ + mkdir launchd; \ + fi \ + fi + sed -e "s|%configure_input%|$@. Generated from $< by configure.|" \ + -e "s|%bindir%|$(bindir)|" \ + -e "s|%couchdb_command_name%|$(couchdb_command_name)|" \ + < $< > $@ + +if WINDOWS + +# README.txt has \n line endings in the repo and must have \r\n +# when installed as notepad is used to view it. +# Also: the targets below don't seem to update after an svn-up (which +# changes the version string in the generated files) so we trick make +# into always building it with the FORCE pattern... +windows/README.txt: windows/README.txt.tpl FORCE + sed -e "s|%package_name%|@package_name@|g" \ + -e "s|%version%|@version@|g" \ + < $< | unix2dos > $@ + +windows/couchdb.iss: windows/couchdb.iss.tpl FORCE + sed -e "s|%configure_input%|$@. Generated from $< by configure.|" \ + -e "s|%package_name%|@package_name@|g" \ + -e "s|%locallibbindir%|`cygpath -m @locallibbindir@`|g" \ + -e "s|%version%|@version@|g" \ + -e "s|%erts_version%|`$(ERL) -version 2>&1 | $(SED) 's/[^0-9\.]//g'`|g" \ + -e "s|%openssl_bin_dir%|@openssl_bin_dir@|g" \ + -e "s|%msvc_redist_dir%|@msvc_redist_dir@|g" \ + -e "s|%msvc_redist_name%|@msvc_redist_name@|g" \ + < $< > $@ + +# The installer depends on all files, not just the source .iss file, +# so we trick make into always building it with the FORCE pattern... +windows/setup-couchdb-@version@.exe: windows/couchdb.iss windows/README.txt FORCE + "$(INNO_COMPILER_EXECUTABLE)" /q $< + @echo Windows Installer is at: `cygpath -a -w windows/setup-couchdb-@version@.exe` + +windows/setup-couchdb-@version@.exe.md5: windows/setup-couchdb-@version@.exe + cd windows && md5sum ./$( $(@F) + +windows/setup-couchdb-@version@.exe.sha: windows/setup-couchdb-@version@.exe + cd windows && sha1sum ./$( $(@F) + +FORCE: + +endif + +install-data-hook: + if test -n "$(init_DATA)"; then \ + chmod +x "$(DESTDIR)$(initdir)/couchdb"; \ + fi diff --git a/1.1.x/etc/couchdb/Makefile.am b/1.1.x/etc/couchdb/Makefile.am new file mode 100644 index 00000000..9367ceac --- /dev/null +++ b/1.1.x/etc/couchdb/Makefile.am @@ -0,0 +1,86 @@ +## Licensed under the Apache License, Version 2.0 (the "License"); you may not +## use this file except in compliance with the License. You may obtain a copy of +## the License at +## +## http://www.apache.org/licenses/LICENSE-2.0 +## +## Unless required by applicable law or agreed to in writing, software +## distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +## WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +## License for the specific language governing permissions and limitations under +## the License. + +couchprivlibdir = $(localerlanglibdir)/couch-$(version)/priv/lib +devcouchprivlibdir = $(abs_top_builddir)/src/couchdb/priv/.libs + +localconf_DATA = default.ini +noinst_DATA = default_dev.ini local_dev.ini + +EXTRA_DIST = local.ini + +CLEANFILES = $(localconf_DATA) $(noinst_DATA) + +transform = @program_transform_name@ +couchjs_command_name = `echo couchjs | sed '$(transform)'` +couchjs_dev_command_name = `echo couchjs_dev | sed '$(transform)'` + +if WINDOWS +default.ini: default.ini.tpl + sed -e "s|%bindir%|.|g" \ + -e "s|%localconfdir%|$(localconfdir)|g" \ + -e "s|%localdatadir%|../share/couchdb|g" \ + -e "s|%localbuilddatadir%|../share/couchdb|g" \ + -e "s|%localstatelibdir%|../var/lib/couchdb|g" \ + -e "s|%localstatelogdir%|../var/log/couchdb|g" \ + -e "s|%localstaterundir%|../var/run/couchdb|g" \ + -e "s|%couchprivlibdir%|../lib/couch-$(version)/priv/lib|g" \ + -e "s|%couchjs_command_name%|couchjs.exe|g" \ + < $< > $@ +else +default.ini: default.ini.tpl + sed -e "s|%bindir%|$(bindir)|g" \ + -e "s|%localconfdir%|$(localconfdir)|g" \ + -e "s|%localdatadir%|$(localdatadir)|g" \ + -e "s|%localbuilddatadir%|$(localdatadir)|g" \ + -e "s|%localstatelibdir%|$(localstatelibdir)|g" \ + -e "s|%localstatelogdir%|$(localstatelogdir)|g" \ + -e "s|%localstaterundir%|$(localstaterundir)|g" \ + -e "s|%couchprivlibdir%|$(couchprivlibdir)|g" \ + -e "s|%couchjs_command_name%|$(couchjs_command_name)|g" \ + < $< > $@ +endif + +default_dev.ini: default.ini.tpl + sed -e "s|%bindir%|$(abs_top_builddir)/bin|g" \ + -e "s|%localconfdir%|$(abs_top_builddir)/etc/couchdb|g" \ + -e "s|%localdatadir%|$(abs_top_srcdir)/share|g" \ + -e "s|%localbuilddatadir%|$(abs_top_builddir)/share|g" \ + -e "s|%localstatelibdir%|$(abs_top_builddir)/tmp/lib|g" \ + -e "s|%localstatelogdir%|$(abs_top_builddir)/tmp/log|g" \ + -e "s|%localstaterundir%|$(abs_top_builddir)/tmp/run|g" \ + -e "s|%couchprivlibdir%|$(devcouchprivlibdir)|g" \ + -e "s|%couchjs_command_name%|$(couchjs_dev_command_name)|g" \ + < $< > $@ + +# Noah said to not specify local.ini but it borks +# VPATH builds that make distcheck uses. +local_dev.ini: local.ini + if test ! -f "$@"; then \ + cp $< $@; \ + fi + +install-data-hook: + if test ! -f "$(DESTDIR)$(localconfdir)/local.ini"; then \ + cp $(srcdir)/local.ini "$(DESTDIR)$(localconfdir)/local.ini"; \ + fi + if test ! "$(mkdir_p)" = ""; then \ + $(mkdir_p) "$(DESTDIR)$(localconfdir)/default.d"; \ + $(mkdir_p) "$(DESTDIR)$(localconfdir)/local.d"; \ + else \ + echo "WARNING: You may have to create these directories by hand."; \ + mkdir -p "$(DESTDIR)$(localconfdir)/default.d"; \ + mkdir -p "$(DESTDIR)$(localconfdir)/local.d"; \ + fi + +uninstall-local: + rm -f "$(DESTDIR)/$(localconfdir)/local.ini" diff --git a/1.1.x/etc/couchdb/default.ini.tpl.in b/1.1.x/etc/couchdb/default.ini.tpl.in new file mode 100644 index 00000000..f5dc24af --- /dev/null +++ b/1.1.x/etc/couchdb/default.ini.tpl.in @@ -0,0 +1,148 @@ +; @configure_input@ + +; Upgrading CouchDB will overwrite this file. + +[couchdb] +database_dir = %localstatelibdir% +view_index_dir = %localstatelibdir% +util_driver_dir = %couchprivlibdir% +max_document_size = 4294967296 ; 4 GB +os_process_timeout = 5000 ; 5 seconds. for view and external servers. +max_dbs_open = 100 +delayed_commits = true ; set this to false to ensure an fsync before 201 Created is returned +uri_file = %localstaterundir%/couch.uri + +[httpd] +port = 5984 +bind_address = 127.0.0.1 +authentication_handlers = {couch_httpd_oauth, oauth_authentication_handler}, {couch_httpd_auth, cookie_authentication_handler}, {couch_httpd_auth, default_authentication_handler} +default_handler = {couch_httpd_db, handle_request} +secure_rewrites = true +vhost_global_handlers = _utils, _uuids, _session, _oauth, _users +allow_jsonp = false +; Options for the MochiWeb HTTP server. +;server_options = [{backlog, 128}, {acceptor_pool_size, 16}] +; For more socket options, consult Erlang's module 'inet' man page. +;socket_options = [{recbuf, 262144}, {sndbuf, 262144}, {nodelay, true}] + +[ssl] +port = 6984 + +[log] +file = %localstatelogdir%/couch.log +level = info +include_sasl = true + +[couch_httpd_auth] +authentication_db = _users +authentication_redirect = /_utils/session.html +require_valid_user = false +timeout = 43200 ; (default to 12 hours) number of seconds before automatic logout +auth_cache_size = 50 ; size is number of cache entries + +[query_servers] +javascript = %bindir%/%couchjs_command_name% %localbuilddatadir%/server/main.js + +; Changing reduce_limit to false will disable reduce_limit. +; If you think you're hitting reduce_limit with a "good" reduce function, +; please let us know on the mailing list so we can fine tune the heuristic. +[query_server_config] +reduce_limit = true +os_process_limit = 25 + +[daemons] +view_manager={couch_view, start_link, []} +external_manager={couch_external_manager, start_link, []} +db_update_notifier={couch_db_update_notifier_sup, start_link, []} +query_servers={couch_query_servers, start_link, []} +httpd={couch_httpd, start_link, []} +stats_aggregator={couch_stats_aggregator, start, []} +stats_collector={couch_stats_collector, start, []} +uuids={couch_uuids, start, []} +auth_cache={couch_auth_cache, start_link, []} +replication_manager={couch_replication_manager, start_link, []} +vhosts={couch_httpd_vhost, start_link, []} +os_daemons={couch_os_daemons, start_link, []} + +[httpd_global_handlers] +/ = {couch_httpd_misc_handlers, handle_welcome_req, <<"Welcome">>} +favicon.ico = {couch_httpd_misc_handlers, handle_favicon_req, "%localdatadir%/www"} + +_utils = {couch_httpd_misc_handlers, handle_utils_dir_req, "%localdatadir%/www"} +_all_dbs = {couch_httpd_misc_handlers, handle_all_dbs_req} +_active_tasks = {couch_httpd_misc_handlers, handle_task_status_req} +_config = {couch_httpd_misc_handlers, handle_config_req} +_replicate = {couch_httpd_misc_handlers, handle_replicate_req} +_uuids = {couch_httpd_misc_handlers, handle_uuids_req} +_restart = {couch_httpd_misc_handlers, handle_restart_req} +_stats = {couch_httpd_stats_handlers, handle_stats_req} +_log = {couch_httpd_misc_handlers, handle_log_req} +_session = {couch_httpd_auth, handle_session_req} +_oauth = {couch_httpd_oauth, handle_oauth_req} + +[httpd_db_handlers] +_view_cleanup = {couch_httpd_db, handle_view_cleanup_req} +_compact = {couch_httpd_db, handle_compact_req} +_design = {couch_httpd_db, handle_design_req} +_temp_view = {couch_httpd_view, handle_temp_view_req} +_changes = {couch_httpd_db, handle_changes_req} + +; The external module takes an optional argument allowing you to narrow it to a +; single script. Otherwise the script name is inferred from the first path section +; after _external's own path. +; _mypath = {couch_httpd_external, handle_external_req, <<"mykey">>} +; _external = {couch_httpd_external, handle_external_req} + +[httpd_design_handlers] +_view = {couch_httpd_view, handle_view_req} +_show = {couch_httpd_show, handle_doc_show_req} +_list = {couch_httpd_show, handle_view_list_req} +_info = {couch_httpd_db, handle_design_info_req} +_rewrite = {couch_httpd_rewrite, handle_rewrite_req} +_update = {couch_httpd_show, handle_doc_update_req} + +; enable external as an httpd handler, then link it with commands here. +; note, this api is still under consideration. +; [external] +; mykey = /path/to/mycommand + +; Here you can setup commands for CouchDB to manage +; while it is alive. It will attempt to keep each command +; alive if it exits. +; [os_daemons] +; some_daemon_name = /path/to/script -with args + + +[uuids] +; Known algorithms: +; random - 128 bits of random awesome +; All awesome, all the time. +; sequential - monotonically increasing ids with random increments +; First 26 hex characters are random. Last 6 increment in +; random amounts until an overflow occurs. On overflow, the +; random prefix is regenerated and the process starts over. +; utc_random - Time since Jan 1, 1970 UTC with microseconds +; First 14 characters are the time in hex. Last 18 are random. +algorithm = sequential + +[stats] +; rate is in milliseconds +rate = 1000 +; sample intervals are in seconds +samples = [0, 60, 300, 900] + +[attachments] +compression_level = 8 ; from 1 (lowest, fastest) to 9 (highest, slowest), 0 to disable compression +compressible_types = text/*, application/javascript, application/json, application/xml + +[replicator] +db = _replicator +max_replication_retry_count = 10 +max_http_sessions = 20 +max_http_pipeline_size = 50 +; set to true to validate peer certificates +verify_ssl_certificates = false +; file containing a list of peer trusted certificates (PEM format) +; ssl_trusted_certificates_file = /etc/ssl/certs/ca-certificates.crt +; maximum peer certificate depth (must be set even if certificate validation is off) +ssl_certificate_max_depth = 3 diff --git a/1.1.x/etc/couchdb/local.ini b/1.1.x/etc/couchdb/local.ini new file mode 100644 index 00000000..33380a32 --- /dev/null +++ b/1.1.x/etc/couchdb/local.ini @@ -0,0 +1,74 @@ +; CouchDB Configuration Settings + +; Custom settings should be made in this file. They will override settings +; in default.ini, but unlike changes made to default.ini, this file won't be +; overwritten on server upgrade. + +[couchdb] +;max_document_size = 4294967296 ; bytes + +[httpd] +;port = 5984 +;bind_address = 127.0.0.1 +; Options for the MochiWeb HTTP server. +;server_options = [{backlog, 128}, {acceptor_pool_size, 16}] +; For more socket options, consult Erlang's module 'inet' man page. +;socket_options = [{recbuf, 262144}, {sndbuf, 262144}, {nodelay, true}] + +; Uncomment next line to trigger basic-auth popup on unauthorized requests. +;WWW-Authenticate = Basic realm="administrator" + +; Uncomment next line to set the configuration modification whitelist. Only +; whitelisted values may be changed via the /_config URLs. To allow the admin +; to change this value over HTTP, remember to include {httpd,config_whitelist} +; itself. Excluding it from the list would require editing this file to update +; the whitelist. +;config_whitelist = [{httpd,config_whitelist}, {log,level}, {etc,etc}] + +[httpd_global_handlers] +;_google = {couch_httpd_proxy, handle_proxy_req, <<"http://www.google.com">>} + +[couch_httpd_auth] +; If you set this to true, you should also uncomment the WWW-Authenticate line +; above. If you don't configure a WWW-Authenticate header, CouchDB will send +; Basic realm="server" in order to prevent you getting logged out. +; require_valid_user = false + +[log] +;level = debug + +[os_daemons] +; For any commands listed here, CouchDB will attempt to ensure that +; the process remains alive while CouchDB runs as well as shut them +; down when CouchDB exits. +;foo = /path/to/command -with args + +[daemons] +; enable SSL support by uncommenting the following line and supply the PEM's below. +; the default ssl port CouchDB listens on is 6984 +; httpsd = {couch_httpd, start_link, [https]} + +[ssl] +;cert_file = /full/path/to/server_cert.pem +;key_file = /full/path/to/server_key.pem + +; To enable Virtual Hosts in CouchDB, add a vhost = path directive. All requests to +; the Virual Host will be redirected to the path. In the example below all requests +; to http://example.com/ are redirected to /database. +; If you run CouchDB on a specific port, include the port number in the vhost: +; example.com:5984 = /database + +[vhosts] +;example.com = /database/ + +[update_notification] +;unique notifier name=/full/path/to/exe -with "cmd line arg" + +; To create an admin account uncomment the '[admins]' section below and add a +; line in the format 'username = password'. When you next start CouchDB, it +; will change the password to a hash (so that your passwords don't linger +; around in plain-text files). You can add more admin accounts with more +; 'username = password' lines. Don't forget to restart CouchDB after +; changing this. +[admins] +;admin = mysecretpassword diff --git a/1.1.x/etc/default/Makefile.am b/1.1.x/etc/default/Makefile.am new file mode 100644 index 00000000..5b4faae0 --- /dev/null +++ b/1.1.x/etc/default/Makefile.am @@ -0,0 +1,13 @@ +## Licensed under the Apache License, Version 2.0 (the "License"); you may not +## use this file except in compliance with the License. You may obtain a copy of +## the License at +## +## http://www.apache.org/licenses/LICENSE-2.0 +## +## Unless required by applicable law or agreed to in writing, software +## distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +## WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +## License for the specific language governing permissions and limitations under +## the License. + +## This file intentionally left blank. diff --git a/1.1.x/etc/default/couchdb b/1.1.x/etc/default/couchdb new file mode 100644 index 00000000..c2a3f2ae --- /dev/null +++ b/1.1.x/etc/default/couchdb @@ -0,0 +1,7 @@ +# Sourced by init script for configuration. + +COUCHDB_USER=couchdb +COUCHDB_STDOUT_FILE=/dev/null +COUCHDB_STDERR_FILE=/dev/null +COUCHDB_RESPAWN_TIMEOUT=5 +COUCHDB_OPTIONS= diff --git a/1.1.x/etc/init/Makefile.am b/1.1.x/etc/init/Makefile.am new file mode 100644 index 00000000..5b4faae0 --- /dev/null +++ b/1.1.x/etc/init/Makefile.am @@ -0,0 +1,13 @@ +## Licensed under the Apache License, Version 2.0 (the "License"); you may not +## use this file except in compliance with the License. You may obtain a copy of +## the License at +## +## http://www.apache.org/licenses/LICENSE-2.0 +## +## Unless required by applicable law or agreed to in writing, software +## distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +## WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +## License for the specific language governing permissions and limitations under +## the License. + +## This file intentionally left blank. diff --git a/1.1.x/etc/init/couchdb.tpl.in b/1.1.x/etc/init/couchdb.tpl.in new file mode 100644 index 00000000..3b8d17ea --- /dev/null +++ b/1.1.x/etc/init/couchdb.tpl.in @@ -0,0 +1,168 @@ +#!/bin/sh -e + +# Licensed under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. + +### BEGIN INIT INFO +# Provides: couchdb +# Required-Start: $local_fs $remote_fs +# Required-Stop: $local_fs $remote_fs +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Apache CouchDB init script +# Description: Apache CouchDB init script for the database server. +### END INIT INFO + +SCRIPT_OK=0 +SCRIPT_ERROR=1 + +DESCRIPTION="database server" +NAME=couchdb +SCRIPT_NAME=`basename $0` +COUCHDB=%bindir%/%couchdb_command_name% +CONFIGURATION_FILE=%sysconfdir%/default/couchdb +RUN_DIR=%localstaterundir% +LSB_LIBRARY=/lib/lsb/init-functions + +if test ! -x $COUCHDB; then + exit $SCRIPT_ERROR +fi + +if test -r $CONFIGURATION_FILE; then + . $CONFIGURATION_FILE +fi + +log_daemon_msg () { + # Dummy function to be replaced by LSB library. + + echo $@ +} + +log_end_msg () { + # Dummy function to be replaced by LSB library. + + if test "$1" != "0"; then + echo "Error with $DESCRIPTION: $NAME" + fi + return $1 +} + +if test -r $LSB_LIBRARY; then + . $LSB_LIBRARY +fi + +start_couchdb () { + # Start Apache CouchDB as a background process. + + command="$COUCHDB -b" + if test -n "$COUCHDB_STDOUT_FILE"; then + command="$command -o $COUCHDB_STDOUT_FILE" + fi + if test -n "$COUCHDB_STDERR_FILE"; then + command="$command -e $COUCHDB_STDERR_FILE" + fi + if test -n "$COUCHDB_RESPAWN_TIMEOUT"; then + command="$command -r $COUCHDB_RESPAWN_TIMEOUT" + fi + if test -n "$COUCHDB_OPTIONS"; then + command="$command $COUCHDB_OPTIONS" + fi + mkdir -p "$RUN_DIR" + if test -n "$COUCHDB_USER"; then + chown $COUCHDB_USER "$RUN_DIR" + if su $COUCHDB_USER -c "$command" > /dev/null; then + return $SCRIPT_OK + else + return $SCRIPT_ERROR + fi + else + if $command > /dev/null; then + return $SCRIPT_OK + else + return $SCRIPT_ERROR + fi + fi +} + +stop_couchdb () { + # Stop the running Apache CouchDB process. + + command="$COUCHDB -d" + if test -n "$COUCHDB_OPTIONS"; then + command="$command $COUCHDB_OPTIONS" + fi + if test -n "$COUCHDB_USER"; then + if su $COUCHDB_USER -c "$command" > /dev/null; then + return $SCRIPT_OK + else + return $SCRIPT_ERROR + fi + else + if $command > /dev/null; then + return $SCRIPT_OK + else + return $SCRIPT_ERROR + fi + fi +} + +display_status () { + # Display the status of the running Apache CouchDB process. + + $COUCHDB -s +} + +parse_script_option_list () { + # Parse arguments passed to the script and take appropriate action. + + case "$1" in + start) + log_daemon_msg "Starting $DESCRIPTION" $NAME + if start_couchdb; then + log_end_msg $SCRIPT_OK + else + log_end_msg $SCRIPT_ERROR + fi + ;; + stop) + log_daemon_msg "Stopping $DESCRIPTION" $NAME + if stop_couchdb; then + log_end_msg $SCRIPT_OK + else + log_end_msg $SCRIPT_ERROR + fi + ;; + restart) + log_daemon_msg "Restarting $DESCRIPTION" $NAME + if stop_couchdb; then + if start_couchdb; then + log_end_msg $SCRIPT_OK + else + log_end_msg $SCRIPT_ERROR + fi + else + log_end_msg $SCRIPT_ERROR + fi + ;; + status) + display_status + ;; + *) + cat << EOF >&2 +Usage: $SCRIPT_NAME {start|stop|restart|status} +EOF + exit $SCRIPT_ERROR + ;; + esac +} + +parse_script_option_list $@ diff --git a/1.1.x/etc/launchd/Makefile.am b/1.1.x/etc/launchd/Makefile.am new file mode 100644 index 00000000..5b4faae0 --- /dev/null +++ b/1.1.x/etc/launchd/Makefile.am @@ -0,0 +1,13 @@ +## Licensed under the Apache License, Version 2.0 (the "License"); you may not +## use this file except in compliance with the License. You may obtain a copy of +## the License at +## +## http://www.apache.org/licenses/LICENSE-2.0 +## +## Unless required by applicable law or agreed to in writing, software +## distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +## WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +## License for the specific language governing permissions and limitations under +## the License. + +## This file intentionally left blank. diff --git a/1.1.x/etc/launchd/org.apache.couchdb.plist.tpl.in b/1.1.x/etc/launchd/org.apache.couchdb.plist.tpl.in new file mode 100644 index 00000000..c72f3480 --- /dev/null +++ b/1.1.x/etc/launchd/org.apache.couchdb.plist.tpl.in @@ -0,0 +1,30 @@ + + + + + Label + org.apache.couchdb + EnvironmentVariables + + HOME + ~ + DYLD_LIBRARY_PATH + /opt/local/lib:$DYLD_LIBRARY_PATH + + ProgramArguments + + %bindir%/%couchdb_command_name% + + UserName + couchdb + StandardOutPath + /dev/null + StandardErrorPath + /dev/null + RunAtLoad + + KeepAlive + + + diff --git a/1.1.x/etc/logrotate.d/Makefile.am b/1.1.x/etc/logrotate.d/Makefile.am new file mode 100644 index 00000000..5b4faae0 --- /dev/null +++ b/1.1.x/etc/logrotate.d/Makefile.am @@ -0,0 +1,13 @@ +## Licensed under the Apache License, Version 2.0 (the "License"); you may not +## use this file except in compliance with the License. You may obtain a copy of +## the License at +## +## http://www.apache.org/licenses/LICENSE-2.0 +## +## Unless required by applicable law or agreed to in writing, software +## distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +## WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +## License for the specific language governing permissions and limitations under +## the License. + +## This file intentionally left blank. diff --git a/1.1.x/etc/logrotate.d/couchdb.tpl.in b/1.1.x/etc/logrotate.d/couchdb.tpl.in new file mode 100644 index 00000000..0bb07e13 --- /dev/null +++ b/1.1.x/etc/logrotate.d/couchdb.tpl.in @@ -0,0 +1,9 @@ +%localstatelogdir%/*.log { + weekly + rotate 10 + copytruncate + delaycompress + compress + notifempty + missingok +} diff --git a/1.1.x/etc/windows/Makefile.am b/1.1.x/etc/windows/Makefile.am new file mode 100644 index 00000000..5b4faae0 --- /dev/null +++ b/1.1.x/etc/windows/Makefile.am @@ -0,0 +1,13 @@ +## Licensed under the Apache License, Version 2.0 (the "License"); you may not +## use this file except in compliance with the License. You may obtain a copy of +## the License at +## +## http://www.apache.org/licenses/LICENSE-2.0 +## +## Unless required by applicable law or agreed to in writing, software +## distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +## WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +## License for the specific language governing permissions and limitations under +## the License. + +## This file intentionally left blank. diff --git a/1.1.x/etc/windows/README.txt.tpl b/1.1.x/etc/windows/README.txt.tpl new file mode 100644 index 00000000..791bcc85 --- /dev/null +++ b/1.1.x/etc/windows/README.txt.tpl @@ -0,0 +1,29 @@ +This is the README for the %package_name% binary distribution for +Windows, version %version%. + +* Although CouchDB defaults to installing into your "Program Files" directory, + the permissions on the 'var' and 'etc' sub-directories have been adjusted + to allow modification by any authorized user so the couchdb databases, logs + and .ini files can be written. You may like to further restrict these + permissions to only the user who will be running couchdb. + +* The installer offers to install CouchDB as a Windows Service. If you select + this option, the service will run as the "LocalSystem" user and be + configured to start automatically. You can configure the service properties + via the Windows 'Services' applet. + +* To start CouchDB in a "console" environment, execute couchdb.bat in the + 'bin' directory. A shortcut to this batch file should have been installed. + Don't try and start couchdb this way if the service is running - it will + fail. + +* The Futon application which comes with CouchDB does not work with + Internet Explorer - Mozilla Firefox is generally recommended. + +* The test suite is known to fail on Windows due to what appear to be + permissions errors; this is due to couch being unable to delete a + file while it is in use on Windows. + See also https://issues.apache.org/jira/browse/COUCHDB-326 + +* Additional help with the Windows support is needed - please contact the + couchdb-dev list if you can help. diff --git a/1.1.x/etc/windows/couchdb.iss.tpl b/1.1.x/etc/windows/couchdb.iss.tpl new file mode 100644 index 00000000..8a32561d --- /dev/null +++ b/1.1.x/etc/windows/couchdb.iss.tpl @@ -0,0 +1,87 @@ +; Licensed under the Apache License, Version 2.0 (the "License"); you may not +; use this file except in compliance with the License. You may obtain a copy of +; the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, software +; distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +; WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +; License for the specific language governing permissions and limitations under +; the License. + +; CouchDB inno installer script +; %configure_input% + +[Setup] +AppID=ApacheCouchDB +AppName=%package_name% +AppVerName=%package_name% %version% +AppPublisher=Apache Software Foundation +AppPublisherURL=http://couchdb.apache.org/ +LicenseFile=../../LICENSE +DefaultDirName={pf}\Apache Software Foundation\CouchDB +DefaultGroupName=%package_name% +OutputBaseFilename=setup-couchdb-%version% +OutputDir=. + +[Files] +Source: "%locallibbindir%\..\*.*"; DestDir: "{app}"; Flags: ignoreversion uninsrestartdelete restartreplace +; bin dir +Source: "%locallibbindir%\*.*"; DestDir: "{app}\bin"; Flags: ignoreversion uninsrestartdelete restartreplace recursesubdirs +; other dirs copied '*.*' +Source: "%locallibbindir%\..\erts-%erts_version%\*.*"; DestDir: "{app}\erts-%erts_version%"; Flags: ignoreversion uninsrestartdelete restartreplace recursesubdirs +Source: "%locallibbindir%\..\lib\*.*"; DestDir: "{app}\lib"; Flags: ignoreversion uninsrestartdelete restartreplace recursesubdirs +Source: "%locallibbindir%\..\share\*.*"; DestDir: "{app}\share"; Flags: ignoreversion uninsrestartdelete restartreplace recursesubdirs +Source: "%locallibbindir%\..\releases\*.*"; DestDir: "{app}\releases"; Flags: ignoreversion uninsrestartdelete restartreplace recursesubdirs +; skip ./usr, ./var + +; custom stuff... +; ./etc/default.ini is unconditional +Source: "%locallibbindir%\..\etc\couchdb\default.ini"; DestDir: "{app}\etc\couchdb"; Flags: ignoreversion uninsrestartdelete restartreplace +; ./etc/local.ini is preserved and should not be updated if it exists +Source: "%locallibbindir%\..\etc\couchdb\local.ini"; DestDir: "{app}\etc\couchdb"; Flags: onlyifdoesntexist uninsneveruninstall +; readme +Source: "README.txt"; DestDir: "{app}"; Flags: isreadme + +; msvc redists - see comments in configure.ac for notes about these... +; ( deleteafterinstall - not needed - {tmp} auto cleaned???? +Source: "%msvc_redist_dir%\%msvc_redist_name%"; DestDir: "{tmp}"; Flags: deleteafterinstall + +; These are erlang requirements and not copied by our makefiles. +Source: "%openssl_bin_dir%\ssleay32.dll"; DestDir: "{app}\bin"; Flags: ignoreversion uninsrestartdelete restartreplace +Source: "%openssl_bin_dir%\libeay32.dll"; DestDir: "{app}\bin"; Flags: ignoreversion uninsrestartdelete restartreplace + +[Dirs] +Name: "{app}\var\lib\couchdb"; Permissions: authusers-modify +Name: "{app}\var\log\couchdb"; Permissions: authusers-modify +Name: "{app}\etc\couchdb"; Permissions: authusers-modify + +[Icons] +Name: "{group}\Start CouchDB"; Filename: "{app}\bin\couchdb.bat" +Name: "{group}\Futon (CouchDB web interface)"; Filename: "http://127.0.0.1:5984/_utils" +Name: "{group}\CouchDB Web Site"; Filename: "http://couchdb.apache.org/" + +[Tasks] +Name: service; Description: "Install couchdb as a Windows service" +Name: service\start; Description: "Start the service after installation" + +[Run] +Filename: "{tmp}\%msvc_redist_name%"; Parameters: "/q" +; This is erlang's Install.exe which updates erl.ini correctly. +Filename: "{app}\Install.exe"; Parameters: "-s"; Flags: runhidden + +; Commands for a service +; First attempt to nuke an existing service of this name, incase they are +; reinstalling without uninstalling +Filename: "{app}\erts-%erts_version%\bin\erlsrv.exe"; Parameters: "remove ""%package_name%"""; Flags: runhidden; Tasks: service +; add a new service, including automatic restart by default on failure +Filename: "{app}\erts-%erts_version%\bin\erlsrv.exe"; Parameters: "add ""%package_name%"" -workdir ""{app}\bin"" -onfail restart_always -args ""-sasl errlog_type error -s couch +A 4 +W w"" -comment ""%package_name% %version%"""; Flags: runhidden; Tasks: service +; and start it if requested +Filename: "{app}\erts-%erts_version%\bin\erlsrv.exe"; Parameters: "start ""%package_name%"""; Flags: runhidden; Tasks: service\start + +[UninstallRun] +; erlsrv stops services prior to removing them +Filename: "{app}\erts-%erts_version%\bin\erlsrv.exe"; Parameters: "remove ""%package_name%"""; Flags: runhidden; Tasks: service +; kill epmd.exe if running to ensure uninstaller is not prevented from removing all binaries +Filename: "{app}\erts-%erts_version%\bin\epmd.exe"; Parameters: "-kill"; Flags: runhidden diff --git a/1.1.x/license.skip b/1.1.x/license.skip new file mode 100644 index 00000000..151ccc08 --- /dev/null +++ b/1.1.x/license.skip @@ -0,0 +1,111 @@ +\.svn +^AUTHORS +^BUGS +^CHANGES +^DEVELOPERS +^DEVELOPERS.gz +^INSTALL +^INSTALL.Unix +^INSTALL.Unix.gz +^INSTALL.Windows +^INSTALL.Windows.gz +^INSTALL.gz +^LICENSE.gz +^Makefile +^Makefile.in +^NEWS +^NOTICE +^README +^THANKS +^aclocal.m4 +^apache-couchdb-* +^autom4te.cache/* +^bin/Makefile +^bin/Makefile.in +^bin/couchdb.1 +^bin/couchjs.1 +^build-aux/* +^config.* +^configure +^couchdb.stderr +^couchdb.stdout +^cover/.*\.coverdata +^cover/.*\.html +^erl_crash.dump +^etc/Makefile +^etc/Makefile.in +^etc/couchdb/Makefile +^etc/couchdb/Makefile.in +^etc/couchdb/default* +^etc/couchdb/local* +^etc/default/Makefile +^etc/default/Makefile.in +^etc/default/couchdb +^etc/init/Makefile +^etc/init/Makefile.in +^etc/launchd/Makefile +^etc/launchd/Makefile.in +^etc/launchd/org.apache.couchdb.plist.* +^etc/logrotate.d/Makefile +^etc/logrotate.d/Makefile.in +^etc/logrotate.d/couchdb* +^etc/windows/Makefile +^etc/windows/README.txt.tpl +^libtool +^license.skip +^m4/* +^share/Makefile +^share/Makefile.in +^share/server/json2.js +^share/server/mimeparse.js +^share/www/favicon.ico +^share/www/image/* +^share/www/script/jquery.* +^share/www/script/json2.js +^share/www/script/jspec/* +^share/www/script/sha1.js +^share/www/script/base64.js +^share/www/script/test/lorem* +^share/www/style/jquery-ui-1.8.11.custom.css +^src/Makefile +^src/Makefile.in +^src/couchdb/.*beam +^src/couchdb/.deps/* +^src/couchdb/Makefile +^src/couchdb/Makefile.in +^src/couchdb/couch.app* +^src/couchdb/couch.app.tpl.in +^src/couchdb/priv/.*o +^src/couchdb/priv/.deps/* +^src/couchdb/priv/Makefile +^src/couchdb/priv/Makefile.in +^src/couchdb/priv/couch_icu_driver.la +^src/couchdb/priv/couchjs +^src/couchdb/priv/couchspawnkillable +^src/couchdb/priv/stat_descriptions.cfg +^src/erlang-oauth/* +^src/etap/* +^src/ibrowse/* +^src/mochiweb/* +^stamp-h1 +^test/Makefile +^test/Makefile.in +^test/bench/Makefile +^test/bench/Makefile.in +^test/etap/.*beam +^test/etap/.*\.o +^test/etap/.deps/* +^test/etap/test_cfg_register +^test/etap/Makefile +^test/etap/Makefile.in +^test/etap/temp.* +^test/javascript/Makefile +^test/javascript/Makefile.in +^test/local.ini +^test/view_server/Makefile +^test/view_server/Makefile.in +^tmp/* +^utils/Makefile +^utils/Makefile.in +^var/Makefile +^var/Makefile.in diff --git a/1.1.x/m4/ac_check_curl.m4.gz b/1.1.x/m4/ac_check_curl.m4.gz new file mode 100644 index 00000000..020e646f Binary files /dev/null and b/1.1.x/m4/ac_check_curl.m4.gz differ diff --git a/1.1.x/m4/ac_check_icu.m4.gz b/1.1.x/m4/ac_check_icu.m4.gz new file mode 100644 index 00000000..8af50ff9 Binary files /dev/null and b/1.1.x/m4/ac_check_icu.m4.gz differ diff --git a/1.1.x/share/Makefile.am b/1.1.x/share/Makefile.am new file mode 100644 index 00000000..968660ff --- /dev/null +++ b/1.1.x/share/Makefile.am @@ -0,0 +1,201 @@ +## Licensed under the Apache License, Version 2.0 (the "License"); you may not +## use this file except in compliance with the License. You may obtain a copy of +## the License at +## +## http://www.apache.org/licenses/LICENSE-2.0 +## +## Unless required by applicable law or agreed to in writing, software +## distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +## WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +## License for the specific language governing permissions and limitations under +## the License. + +JS_FILE = server/main.js + +JS_FILE_COMPONENTS = \ + server/json2.js \ + server/filter.js \ + server/mimeparse.js \ + server/render.js \ + server/state.js \ + server/util.js \ + server/validate.js \ + server/views.js + +JS_FILE_COMPONENTS_LAST = server/loop.js + +$(JS_FILE): $(JS_FILE_COMPONENTS) $(JS_FILE_COMPONENTS_LAST) + mkdir -p `dirname $(JS_FILE)` + echo "// DO NOT EDIT THIS FILE BY HAND" > $@ + echo >> $@ + cat $^ >> $@ + +CLEANFILES = $(JS_FILE) + +EXTRA_DIST = $(JS_FILE_COMPONENTS) $(JS_FILE_COMPONENTS_LAST) + +nobase_localdata_SCRIPTS = \ + $(JS_FILE) + +nobase_dist_localdata_DATA = \ + www/config.html \ + www/couch_tests.html \ + www/custom_test.html \ + www/database.html \ + www/session.html \ + www/dialog/_admin_party.html \ + www/dialog/_compact_cleanup.html \ + www/dialog/_create_admin.html \ + www/dialog/_login.html \ + www/dialog/_signup.html \ + www/dialog/_create_database.html \ + www/dialog/_create_config.html \ + www/dialog/_delete_database.html \ + www/dialog/_delete_document.html \ + www/dialog/_database_security.html \ + www/dialog/_share_test_reports.html \ + www/dialog/_save_view_as.html \ + www/dialog/_upload_attachment.html \ + www/document.html \ + www/favicon.ico \ + www/image/add.png \ + www/image/apply.gif \ + www/image/bg.png \ + www/image/cancel.gif \ + www/image/compact.png \ + www/image/delete-mini.png \ + www/image/delete.png \ + www/image/grippie.gif \ + www/image/hgrad.gif \ + www/image/key.png \ + www/image/load.png \ + www/image/logo.png \ + www/image/order-asc.gif \ + www/image/order-desc.gif \ + www/image/path.gif \ + www/image/progress.gif \ + www/image/rarrow.png \ + www/image/run-mini.png \ + www/image/run.png \ + www/image/running.png \ + www/image/save.png \ + www/image/sidebar-toggle.png \ + www/image/spinner.gif \ + www/image/spinner_33.gif \ + www/image/spinner_6b.gif \ + www/image/test_failure.gif \ + www/image/test_success.gif \ + www/image/thead-key.gif \ + www/image/thead.gif \ + www/image/toggle-collapse.gif \ + www/image/toggle-expand.gif \ + www/image/twisty.gif \ + www/index.html \ + www/replicator.html \ + www/script/couch.js \ + www/script/couch_tests.js \ + www/script/couch_test_runner.js \ + www/script/futon.browse.js \ + www/script/futon.format.js \ + www/script/futon.js \ + www/script/jquery.couch.js \ + www/script/jquery.dialog.js \ + www/script/jquery.editinline.js \ + www/script/jquery.form.js \ + www/script/jquery.js \ + www/script/jquery-ui-1.8.11.custom.min.js \ + www/script/jquery.resizer.js \ + www/script/jquery.suggest.js \ + www/script/json2.js \ + www/script/jspec/jspec.css \ + www/script/jspec/jspec.jquery.js \ + www/script/jspec/jspec.js \ + www/script/jspec/jspec.xhr.js \ + www/script/oauth.js \ + www/script/sha1.js \ + www/script/base64.js \ + www/script/test/all_docs.js \ + www/script/test/attachments.js \ + www/script/test/attachments_multipart.js \ + www/script/test/attachment_conflicts.js \ + www/script/test/attachment_names.js \ + www/script/test/attachment_paths.js \ + www/script/test/attachment_ranges.js \ + www/script/test/attachment_views.js \ + www/script/test/auth_cache.js \ + www/script/test/basics.js \ + www/script/test/batch_save.js \ + www/script/test/bulk_docs.js \ + www/script/test/changes.js \ + www/script/test/compact.js \ + www/script/test/config.js \ + www/script/test/conflicts.js \ + www/script/test/content_negotiation.js \ + www/script/test/cookie_auth.js \ + www/script/test/copy_doc.js \ + www/script/test/delayed_commits.js \ + www/script/test/design_docs.js \ + www/script/test/design_options.js \ + www/script/test/design_paths.js \ + www/script/test/erlang_views.js \ + www/script/test/etags_head.js \ + www/script/test/etags_views.js \ + www/script/test/form_submit.js \ + www/script/test/http.js \ + www/script/test/invalid_docids.js \ + www/script/test/jsonp.js \ + www/script/test/large_docs.js \ + www/script/test/list_views.js \ + www/script/test/lorem.txt \ + www/script/test/lorem_b64.txt \ + www/script/test/lots_of_docs.js \ + www/script/test/method_override.js \ + www/script/test/multiple_rows.js \ + www/script/test/oauth.js \ + www/script/test/proxyauth.js \ + www/script/test/purge.js \ + www/script/test/reader_acl.js \ + www/script/test/recreate_doc.js \ + www/script/test/reduce.js \ + www/script/test/reduce_builtin.js \ + www/script/test/reduce_false.js \ + www/script/test/reduce_false_temp.js \ + www/script/test/replication.js \ + www/script/test/replicator_db.js \ + www/script/test/rev_stemming.js \ + www/script/test/rewrite.js \ + www/script/test/security_validation.js \ + www/script/test/show_documents.js \ + www/script/test/stats.js \ + www/script/test/update_documents.js \ + www/script/test/users_db.js \ + www/script/test/utf8.js \ + www/script/test/uuids.js \ + www/script/test/view_collation.js \ + www/script/test/view_collation_raw.js \ + www/script/test/view_conflicts.js \ + www/script/test/view_compaction.js \ + www/script/test/view_errors.js \ + www/script/test/view_include_docs.js \ + www/script/test/view_multi_key_all_docs.js \ + www/script/test/view_multi_key_design.js \ + www/script/test/view_multi_key_temp.js \ + www/script/test/view_offsets.js \ + www/script/test/view_update_seq.js \ + www/script/test/view_pagination.js \ + www/script/test/view_sandboxing.js \ + www/script/test/view_xml.js \ + www/spec/couch_js_class_methods_spec.js \ + www/spec/couch_js_instance_methods_1_spec.js \ + www/spec/couch_js_instance_methods_2_spec.js \ + www/spec/couch_js_instance_methods_3_spec.js \ + www/spec/custom_helpers.js \ + www/spec/jquery_couch_js_class_methods_spec.js \ + www/spec/jquery_couch_js_instance_methods_1_spec.js \ + www/spec/jquery_couch_js_instance_methods_2_spec.js \ + www/spec/jquery_couch_js_instance_methods_3_spec.js \ + www/spec/run.html \ + www/status.html \ + www/style/jquery-ui-1.8.11.custom.css \ + www/style/layout.css \ + www/_sidebar.html diff --git a/1.1.x/share/server/filter.js b/1.1.x/share/server/filter.js new file mode 100644 index 00000000..1e8556a4 --- /dev/null +++ b/1.1.x/share/server/filter.js @@ -0,0 +1,23 @@ +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy of +// the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations under +// the License. + +var Filter = { + filter : function(fun, ddoc, args) { + var results = []; + var docs = args[0]; + var req = args[1]; + for (var i=0; i < docs.length; i++) { + results.push((fun.apply(ddoc, [docs[i], req]) && true) || false); + }; + respond([true, results]); + } +}; diff --git a/1.1.x/share/server/json2.js b/1.1.x/share/server/json2.js new file mode 100644 index 00000000..a1a3b170 --- /dev/null +++ b/1.1.x/share/server/json2.js @@ -0,0 +1,482 @@ +/* + http://www.JSON.org/json2.js + 2010-03-20 + + Public Domain. + + NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. + + See http://www.JSON.org/js.html + + + This code should be minified before deployment. + See http://javascript.crockford.com/jsmin.html + + USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO + NOT CONTROL. + + + This file creates a global JSON object containing two methods: stringify + and parse. + + JSON.stringify(value, replacer, space) + value any JavaScript value, usually an object or array. + + replacer an optional parameter that determines how object + values are stringified for objects. It can be a + function or an array of strings. + + space an optional parameter that specifies the indentation + of nested structures. If it is omitted, the text will + be packed without extra whitespace. If it is a number, + it will specify the number of spaces to indent at each + level. If it is a string (such as '\t' or ' '), + it contains the characters used to indent at each level. + + This method produces a JSON text from a JavaScript value. + + When an object value is found, if the object contains a toJSON + method, its toJSON method will be called and the result will be + stringified. A toJSON method does not serialize: it returns the + value represented by the name/value pair that should be serialized, + or undefined if nothing should be serialized. The toJSON method + will be passed the key associated with the value, and this will be + bound to the value + + For example, this would serialize Dates as ISO strings. + + Date.prototype.toJSON = function (key) { + function f(n) { + // Format integers to have at least two digits. + return n < 10 ? '0' + n : n; + } + + return this.getUTCFullYear() + '-' + + f(this.getUTCMonth() + 1) + '-' + + f(this.getUTCDate()) + 'T' + + f(this.getUTCHours()) + ':' + + f(this.getUTCMinutes()) + ':' + + f(this.getUTCSeconds()) + 'Z'; + }; + + You can provide an optional replacer method. It will be passed the + key and value of each member, with this bound to the containing + object. The value that is returned from your method will be + serialized. If your method returns undefined, then the member will + be excluded from the serialization. + + If the replacer parameter is an array of strings, then it will be + used to select the members to be serialized. It filters the results + such that only members with keys listed in the replacer array are + stringified. + + Values that do not have JSON representations, such as undefined or + functions, will not be serialized. Such values in objects will be + dropped; in arrays they will be replaced with null. You can use + a replacer function to replace those with JSON values. + JSON.stringify(undefined) returns undefined. + + The optional space parameter produces a stringification of the + value that is filled with line breaks and indentation to make it + easier to read. + + If the space parameter is a non-empty string, then that string will + be used for indentation. If the space parameter is a number, then + the indentation will be that many spaces. + + Example: + + text = JSON.stringify(['e', {pluribus: 'unum'}]); + // text is '["e",{"pluribus":"unum"}]' + + + text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t'); + // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]' + + text = JSON.stringify([new Date()], function (key, value) { + return this[key] instanceof Date ? + 'Date(' + this[key] + ')' : value; + }); + // text is '["Date(---current time---)"]' + + + JSON.parse(text, reviver) + This method parses a JSON text to produce an object or array. + It can throw a SyntaxError exception. + + The optional reviver parameter is a function that can filter and + transform the results. It receives each of the keys and values, + and its return value is used instead of the original value. + If it returns what it received, then the structure is not modified. + If it returns undefined then the member is deleted. + + Example: + + // Parse the text. Values that look like ISO date strings will + // be converted to Date objects. + + myData = JSON.parse(text, function (key, value) { + var a; + if (typeof value === 'string') { + a = +/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value); + if (a) { + return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4], + +a[5], +a[6])); + } + } + return value; + }); + + myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) { + var d; + if (typeof value === 'string' && + value.slice(0, 5) === 'Date(' && + value.slice(-1) === ')') { + d = new Date(value.slice(5, -1)); + if (d) { + return d; + } + } + return value; + }); + + + This is a reference implementation. You are free to copy, modify, or + redistribute. +*/ + +/*jslint evil: true, strict: false */ + +/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply, + call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours, + getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join, + lastIndex, length, parse, prototype, push, replace, slice, stringify, + test, toJSON, toString, valueOf +*/ + + +// Create a JSON object only if one does not already exist. We create the +// methods in a closure to avoid creating global variables. + +if (!this.JSON) { + this.JSON = {}; +} + +(function () { + + function f(n) { + // Format integers to have at least two digits. + return n < 10 ? '0' + n : n; + } + + if (typeof Date.prototype.toJSON !== 'function') { + + Date.prototype.toJSON = function (key) { + + return isFinite(this.valueOf()) ? + this.getUTCFullYear() + '-' + + f(this.getUTCMonth() + 1) + '-' + + f(this.getUTCDate()) + 'T' + + f(this.getUTCHours()) + ':' + + f(this.getUTCMinutes()) + ':' + + f(this.getUTCSeconds()) + 'Z' : null; + }; + + String.prototype.toJSON = + Number.prototype.toJSON = + Boolean.prototype.toJSON = function (key) { + return this.valueOf(); + }; + } + + var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, + escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, + gap, + indent, + meta = { // table of character substitutions + '\b': '\\b', + '\t': '\\t', + '\n': '\\n', + '\f': '\\f', + '\r': '\\r', + '"' : '\\"', + '\\': '\\\\' + }, + rep; + + + function quote(string) { + +// If the string contains no control characters, no quote characters, and no +// backslash characters, then we can safely slap some quotes around it. +// Otherwise we must also replace the offending characters with safe escape +// sequences. + + escapable.lastIndex = 0; + return escapable.test(string) ? + '"' + string.replace(escapable, function (a) { + var c = meta[a]; + return typeof c === 'string' ? c : + '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); + }) + '"' : + '"' + string + '"'; + } + + + function str(key, holder) { + +// Produce a string from holder[key]. + + var i, // The loop counter. + k, // The member key. + v, // The member value. + length, + mind = gap, + partial, + value = holder[key]; + +// If the value has a toJSON method, call it to obtain a replacement value. + + if (value && typeof value === 'object' && + typeof value.toJSON === 'function') { + value = value.toJSON(key); + } + +// If we were called with a replacer function, then call the replacer to +// obtain a replacement value. + + if (typeof rep === 'function') { + value = rep.call(holder, key, value); + } + +// What happens next depends on the value's type. + + switch (typeof value) { + case 'string': + return quote(value); + + case 'number': + +// JSON numbers must be finite. Encode non-finite numbers as null. + + return isFinite(value) ? String(value) : 'null'; + + case 'boolean': + case 'null': + +// If the value is a boolean or null, convert it to a string. Note: +// typeof null does not produce 'null'. The case is included here in +// the remote chance that this gets fixed someday. + + return String(value); + +// If the type is 'object', we might be dealing with an object or an array or +// null. + + case 'object': + +// Due to a specification blunder in ECMAScript, typeof null is 'object', +// so watch out for that case. + + if (!value) { + return 'null'; + } + +// Make an array to hold the partial results of stringifying this object value. + + gap += indent; + partial = []; + +// Is the value an array? + + if (Object.prototype.toString.apply(value) === '[object Array]') { + +// The value is an array. Stringify every element. Use null as a placeholder +// for non-JSON values. + + length = value.length; + for (i = 0; i < length; i += 1) { + partial[i] = str(i, value) || 'null'; + } + +// Join all of the elements together, separated with commas, and wrap them in +// brackets. + + v = partial.length === 0 ? '[]' : + gap ? '[\n' + gap + + partial.join(',\n' + gap) + '\n' + + mind + ']' : + '[' + partial.join(',') + ']'; + gap = mind; + return v; + } + +// If the replacer is an array, use it to select the members to be stringified. + + if (rep && typeof rep === 'object') { + length = rep.length; + for (i = 0; i < length; i += 1) { + k = rep[i]; + if (typeof k === 'string') { + v = str(k, value); + if (v) { + partial.push(quote(k) + (gap ? ': ' : ':') + v); + } + } + } + } else { + +// Otherwise, iterate through all of the keys in the object. + + for (k in value) { + if (Object.hasOwnProperty.call(value, k)) { + v = str(k, value); + if (v) { + partial.push(quote(k) + (gap ? ': ' : ':') + v); + } + } + } + } + +// Join all of the member texts together, separated with commas, +// and wrap them in braces. + + v = partial.length === 0 ? '{}' : + gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' + + mind + '}' : '{' + partial.join(',') + '}'; + gap = mind; + return v; + } + } + +// If the JSON object does not yet have a stringify method, give it one. + + if (typeof JSON.stringify !== 'function') { + JSON.stringify = function (value, replacer, space) { + +// The stringify method takes a value and an optional replacer, and an optional +// space parameter, and returns a JSON text. The replacer can be a function +// that can replace values, or an array of strings that will select the keys. +// A default replacer method can be provided. Use of the space parameter can +// produce text that is more easily readable. + + var i; + gap = ''; + indent = ''; + +// If the space parameter is a number, make an indent string containing that +// many spaces. + + if (typeof space === 'number') { + for (i = 0; i < space; i += 1) { + indent += ' '; + } + +// If the space parameter is a string, it will be used as the indent string. + + } else if (typeof space === 'string') { + indent = space; + } + +// If there is a replacer, it must be a function or an array. +// Otherwise, throw an error. + + rep = replacer; + if (replacer && typeof replacer !== 'function' && + (typeof replacer !== 'object' || + typeof replacer.length !== 'number')) { + throw new Error('JSON.stringify'); + } + +// Make a fake root object containing our value under the key of ''. +// Return the result of stringifying the value. + + return str('', {'': value}); + }; + } + + +// If the JSON object does not yet have a parse method, give it one. + + if (typeof JSON.parse !== 'function') { + JSON.parse = function (text, reviver) { + +// The parse method takes a text and an optional reviver function, and returns +// a JavaScript value if the text is a valid JSON text. + + var j; + + function walk(holder, key) { + +// The walk method is used to recursively walk the resulting structure so +// that modifications can be made. + + var k, v, value = holder[key]; + if (value && typeof value === 'object') { + for (k in value) { + if (Object.hasOwnProperty.call(value, k)) { + v = walk(value, k); + if (v !== undefined) { + value[k] = v; + } else { + delete value[k]; + } + } + } + } + return reviver.call(holder, key, value); + } + + +// Parsing happens in four stages. In the first stage, we replace certain +// Unicode characters with escape sequences. JavaScript handles many characters +// incorrectly, either silently deleting them, or treating them as line endings. + + text = String(text); + cx.lastIndex = 0; + if (cx.test(text)) { + text = text.replace(cx, function (a) { + return '\\u' + + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); + }); + } + +// In the second stage, we run the text against regular expressions that look +// for non-JSON patterns. We are especially concerned with '()' and 'new' +// because they can cause invocation, and '=' because it can cause mutation. +// But just to be safe, we want to reject all unexpected forms. + +// We split the second stage into 4 regexp operations in order to work around +// crippling inefficiencies in IE's and Safari's regexp engines. First we +// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we +// replace all simple value tokens with ']' characters. Third, we delete all +// open brackets that follow a colon or comma or that begin the text. Finally, +// we look to see that the remaining characters are only whitespace or ']' or +// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval. + + if (/^[\],:{}\s]*$/. +test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@'). +replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']'). +replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) { + +// In the third stage we use the eval function to compile the text into a +// JavaScript structure. The '{' operator is subject to a syntactic ambiguity +// in JavaScript: it can begin a block or an object literal. We wrap the text +// in parens to eliminate the ambiguity. + + j = eval('(' + text + ')'); + +// In the optional fourth stage, we recursively walk the new structure, passing +// each name/value pair to a reviver function for possible transformation. + + return typeof reviver === 'function' ? + walk({'': j}, '') : j; + } + +// If the text is not JSON parseable, then a SyntaxError is thrown. + + throw new SyntaxError('JSON.parse'); + }; + } +}()); diff --git a/1.1.x/share/server/loop.js b/1.1.x/share/server/loop.js new file mode 100644 index 00000000..d2a07f61 --- /dev/null +++ b/1.1.x/share/server/loop.js @@ -0,0 +1,142 @@ +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy of +// the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations under +// the License. + +var sandbox = null; + +function init_sandbox() { + try { + // if possible, use evalcx (not always available) + sandbox = evalcx(''); + sandbox.emit = Views.emit; + sandbox.sum = Views.sum; + sandbox.log = log; + sandbox.toJSON = Couch.toJSON; + sandbox.JSON = JSON; + sandbox.provides = Mime.provides; + sandbox.registerType = Mime.registerType; + sandbox.start = Render.start; + sandbox.send = Render.send; + sandbox.getRow = Render.getRow; + sandbox.isArray = isArray; + } catch (e) { + log(e.toSource()); + } +}; +init_sandbox(); + +// Commands are in the form of json arrays: +// ["commandname",..optional args...]\n +// +// Responses are json values followed by a new line ("\n") + +var DDoc = (function() { + var ddoc_dispatch = { + "lists" : Render.list, + "shows" : Render.show, + "filters" : Filter.filter, + "updates" : Render.update, + "validate_doc_update" : Validate.validate + }; + var ddocs = {}; + return { + ddoc : function() { + var args = []; + for (var i=0; i < arguments.length; i++) { + args.push(arguments[i]); + }; + var ddocId = args.shift(); + if (ddocId == "new") { + // get the real ddocId. + ddocId = args.shift(); + // store the ddoc, functions are lazily compiled. + ddocs[ddocId] = args.shift(); + print("true"); + } else { + // Couch makes sure we know this ddoc already. + var ddoc = ddocs[ddocId]; + if (!ddoc) throw(["fatal", "query_protocol_error", "uncached design doc: "+ddocId]); + var funPath = args.shift(); + var cmd = funPath[0]; + // the first member of the fun path determines the type of operation + var funArgs = args.shift(); + if (ddoc_dispatch[cmd]) { + // get the function, call the command with it + var point = ddoc; + for (var i=0; i < funPath.length; i++) { + if (i+1 == funPath.length) { + fun = point[funPath[i]] + if (typeof fun != "function") { + fun = Couch.compileFunction(fun, ddoc); + // cache the compiled fun on the ddoc + point[funPath[i]] = fun + }; + } else { + point = point[funPath[i]] + } + }; + + // run the correct responder with the cmd body + ddoc_dispatch[cmd].apply(null, [fun, ddoc, funArgs]); + } else { + // unknown command, quit and hope the restarted version is better + throw(["fatal", "unknown_command", "unknown ddoc command '" + cmd + "'"]); + } + } + } + }; +})(); + +var Loop = function() { + var line, cmd, cmdkey, dispatch = { + "ddoc" : DDoc.ddoc, + // "view" : Views.handler, + "reset" : State.reset, + "add_fun" : State.addFun, + "add_lib" : State.addLib, + "map_doc" : Views.mapDoc, + "reduce" : Views.reduce, + "rereduce" : Views.rereduce + }; + function handleError(e) { + var type = e[0]; + if (type == "fatal") { + e[0] = "error"; // we tell the client it was a fatal error by dying + respond(e); + quit(-1); + } else if (type == "error") { + respond(e); + } else if (e.error && e.reason) { + // compatibility with old error format + respond(["error", e.error, e.reason]); + } else { + respond(["error","unnamed_error",e.toSource()]); + } + }; + while (line = readline()) { + cmd = eval('('+line+')'); + State.line_length = line.length; + try { + cmdkey = cmd.shift(); + if (dispatch[cmdkey]) { + // run the correct responder with the cmd body + dispatch[cmdkey].apply(null, cmd); + } else { + // unknown command, quit and hope the restarted version is better + throw(["fatal", "unknown_command", "unknown command '" + cmdkey + "'"]); + } + } catch(e) { + handleError(e); + } + }; +}; + +Loop(); diff --git a/1.1.x/share/server/mimeparse.js b/1.1.x/share/server/mimeparse.js new file mode 100644 index 00000000..3642a194 --- /dev/null +++ b/1.1.x/share/server/mimeparse.js @@ -0,0 +1,158 @@ +// mimeparse.js +// +// This module provides basic functions for handling mime-types. It can +// handle matching mime-types against a list of media-ranges. See section +// 14.1 of the HTTP specification [RFC 2616] for a complete explanation. +// +// http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1 +// +// A port to JavaScript of Joe Gregorio's MIME-Type Parser: +// +// http://code.google.com/p/mimeparse/ +// +// Ported by J. Chris Anderson , targeting the Spidermonkey runtime. +// +// To run the tests, open mimeparse-js-test.html in a browser. +// Ported from version 0.1.2 +// Comments are mostly excerpted from the original. + +var Mimeparse = (function() { + // private helpers + function strip(string) { + return string.replace(/^\s+/, '').replace(/\s+$/, '') + }; + + function parseRanges(ranges) { + var parsedRanges = [], rangeParts = ranges.split(","); + for (var i=0; i < rangeParts.length; i++) { + parsedRanges.push(publicMethods.parseMediaRange(rangeParts[i])) + }; + return parsedRanges; + }; + + var publicMethods = { + // Carves up a mime-type and returns an Array of the + // [type, subtype, params] where "params" is a Hash of all + // the parameters for the media range. + // + // For example, the media range "application/xhtml;q=0.5" would + // get parsed into: + // + // ["application", "xhtml", { "q" : "0.5" }] + parseMimeType : function(mimeType) { + var fullType, typeParts, params = {}, parts = mimeType.split(';'); + for (var i=0; i < parts.length; i++) { + var p = parts[i].split('='); + if (p.length == 2) { + params[strip(p[0])] = strip(p[1]); + } + }; + fullType = parts[0].replace(/^\s+/, '').replace(/\s+$/, ''); + if (fullType == '*') fullType = '*/*'; + typeParts = fullType.split('/'); + return [typeParts[0], typeParts[1], params]; + }, + + // Carves up a media range and returns an Array of the + // [type, subtype, params] where "params" is a Object with + // all the parameters for the media range. + // + // For example, the media range "application/*;q=0.5" would + // get parsed into: + // + // ["application", "*", { "q" : "0.5" }] + // + // In addition this function also guarantees that there + // is a value for "q" in the params dictionary, filling it + // in with a proper default if necessary. + parseMediaRange : function(range) { + var q, parsedType = this.parseMimeType(range); + if (!parsedType[2]['q']) { + parsedType[2]['q'] = '1'; + } else { + q = parseFloat(parsedType[2]['q']); + if (isNaN(q)) { + parsedType[2]['q'] = '1'; + } else if (q > 1 || q < 0) { + parsedType[2]['q'] = '1'; + } + } + return parsedType; + }, + + // Find the best match for a given mime-type against + // a list of media_ranges that have already been + // parsed by parseMediaRange(). Returns an array of + // the fitness value and the value of the 'q' quality + // parameter of the best match, or (-1, 0) if no match + // was found. Just as for qualityParsed(), 'parsed_ranges' + // must be a list of parsed media ranges. + fitnessAndQualityParsed : function(mimeType, parsedRanges) { + var bestFitness = -1, bestFitQ = 0, target = this.parseMediaRange(mimeType); + var targetType = target[0], targetSubtype = target[1], targetParams = target[2]; + + for (var i=0; i < parsedRanges.length; i++) { + var parsed = parsedRanges[i]; + var type = parsed[0], subtype = parsed[1], params = parsed[2]; + if ((type == targetType || type == "*" || targetType == "*") && + (subtype == targetSubtype || subtype == "*" || targetSubtype == "*")) { + var matchCount = 0; + for (param in targetParams) { + if (param != 'q' && params[param] && params[param] == targetParams[param]) { + matchCount += 1; + } + } + + var fitness = (type == targetType) ? 100 : 0; + fitness += (subtype == targetSubtype) ? 10 : 0; + fitness += matchCount; + + if (fitness > bestFitness) { + bestFitness = fitness; + bestFitQ = params["q"]; + } + } + }; + return [bestFitness, parseFloat(bestFitQ)]; + }, + + // Find the best match for a given mime-type against + // a list of media_ranges that have already been + // parsed by parseMediaRange(). Returns the + // 'q' quality parameter of the best match, 0 if no + // match was found. This function bahaves the same as quality() + // except that 'parsedRanges' must be a list of + // parsed media ranges. + qualityParsed : function(mimeType, parsedRanges) { + return this.fitnessAndQualityParsed(mimeType, parsedRanges)[1]; + }, + + // Returns the quality 'q' of a mime-type when compared + // against the media-ranges in ranges. For example: + // + // >>> Mimeparse.quality('text/html','text/*;q=0.3, text/html;q=0.7, text/html;level=1, text/html;level=2;q=0.4, */*;q=0.5') + // 0.7 + quality : function(mimeType, ranges) { + return this.qualityParsed(mimeType, parseRanges(ranges)); + }, + + // Takes a list of supported mime-types and finds the best + // match for all the media-ranges listed in header. The value of + // header must be a string that conforms to the format of the + // HTTP Accept: header. The value of 'supported' is a list of + // mime-types. + // + // >>> bestMatch(['application/xbel+xml', 'text/xml'], 'text/*;q=0.5,*/*; q=0.1') + // 'text/xml' + bestMatch : function(supported, header) { + var parsedHeader = parseRanges(header); + var weighted = []; + for (var i=0; i < supported.length; i++) { + weighted.push([publicMethods.fitnessAndQualityParsed(supported[i], parsedHeader), i, supported[i]]) + }; + weighted.sort(); + return weighted[weighted.length-1][0][1] ? weighted[weighted.length-1][2] : ''; + } + } + return publicMethods; +})(); diff --git a/1.1.x/share/server/render.js b/1.1.x/share/server/render.js new file mode 100644 index 00000000..d207db41 --- /dev/null +++ b/1.1.x/share/server/render.js @@ -0,0 +1,352 @@ +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy of +// the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations under +// the License. + + +var Mime = (function() { + // registerType(name, mime-type, mime-type, ...) + // + // Available in query server sandbox. TODO: The list is cleared on reset. + // This registers a particular name with the set of mimetypes it can handle. + // Whoever registers last wins. + // + // Example: + // registerType("html", "text/html; charset=utf-8"); + + var mimesByKey = {}; + var keysByMime = {}; + function registerType() { + var mimes = [], key = arguments[0]; + for (var i=1; i < arguments.length; i++) { + mimes.push(arguments[i]); + }; + mimesByKey[key] = mimes; + for (var i=0; i < mimes.length; i++) { + keysByMime[mimes[i]] = key; + }; + } + + // Some default types + // Ported from Ruby on Rails + // Build list of Mime types for HTTP responses + // http://www.iana.org/assignments/media-types/ + // http://dev.rubyonrails.org/svn/rails/trunk/actionpack/lib/action_controller/mime_types.rb + + registerType("all", "*/*"); + registerType("text", "text/plain; charset=utf-8", "txt"); + registerType("html", "text/html; charset=utf-8"); + registerType("xhtml", "application/xhtml+xml", "xhtml"); + registerType("xml", "application/xml", "text/xml", "application/x-xml"); + registerType("js", "text/javascript", "application/javascript", "application/x-javascript"); + registerType("css", "text/css"); + registerType("ics", "text/calendar"); + registerType("csv", "text/csv"); + registerType("rss", "application/rss+xml"); + registerType("atom", "application/atom+xml"); + registerType("yaml", "application/x-yaml", "text/yaml"); + // just like Rails + registerType("multipart_form", "multipart/form-data"); + registerType("url_encoded_form", "application/x-www-form-urlencoded"); + // http://www.ietf.org/rfc/rfc4627.txt + registerType("json", "application/json", "text/x-json"); + + + var mimeFuns = []; + function provides(type, fun) { + Mime.providesUsed = true; + mimeFuns.push([type, fun]); + }; + + function resetProvides() { + // set globals + Mime.providesUsed = false; + mimeFuns = []; + Mime.responseContentType = null; + }; + + function runProvides(req, ddoc) { + var supportedMimes = [], bestFun, bestKey = null, accept = req.headers["Accept"]; + if (req.query && req.query.format) { + bestKey = req.query.format; + Mime.responseContentType = mimesByKey[bestKey][0]; + } else if (accept) { + // log("using accept header: "+accept); + mimeFuns.reverse().forEach(function(mimeFun) { + var mimeKey = mimeFun[0]; + if (mimesByKey[mimeKey]) { + supportedMimes = supportedMimes.concat(mimesByKey[mimeKey]); + } + }); + Mime.responseContentType = Mimeparse.bestMatch(supportedMimes, accept); + bestKey = keysByMime[Mime.responseContentType]; + } else { + // just do the first one + bestKey = mimeFuns[0][0]; + Mime.responseContentType = mimesByKey[bestKey][0]; + } + + if (bestKey) { + for (var i=0; i < mimeFuns.length; i++) { + if (mimeFuns[i][0] == bestKey) { + bestFun = mimeFuns[i][1]; + break; + } + }; + }; + + if (bestFun) { + return bestFun.call(ddoc); + } else { + var supportedTypes = mimeFuns.map(function(mf) {return mimesByKey[mf[0]].join(', ') || mf[0]}); + throw(["error","not_acceptable", + "Content-Type "+(accept||bestKey)+" not supported, try one of: "+supportedTypes.join(', ')]); + } + }; + + + return { + registerType : registerType, + provides : provides, + resetProvides : resetProvides, + runProvides : runProvides + } +})(); + + + + +//// +//// Render dispatcher +//// +//// +//// +//// + +var Render = (function() { + var chunks = []; + + + // Start chunks + var startResp = {}; + function start(resp) { + startResp = resp || {}; + }; + + function sendStart() { + startResp = applyContentType((startResp || {}), Mime.responseContentType); + respond(["start", chunks, startResp]); + chunks = []; + startResp = {}; + } + + function applyContentType(resp, responseContentType) { + resp["headers"] = resp["headers"] || {}; + if (responseContentType) { + resp["headers"]["Content-Type"] = resp["headers"]["Content-Type"] || responseContentType; + } + return resp; + } + + function send(chunk) { + chunks.push(chunk.toString()); + }; + + function blowChunks(label) { + respond([label||"chunks", chunks]); + chunks = []; + }; + + var gotRow = false, lastRow = false; + function getRow() { + if (lastRow) return null; + if (!gotRow) { + gotRow = true; + sendStart(); + } else { + blowChunks(); + } + var line = readline(); + var json = eval('('+line+')'); + if (json[0] == "list_end") { + lastRow = true; + return null; + } + if (json[0] != "list_row") { + throw(["fatal", "list_error", "not a row '" + json[0] + "'"]); + } + return json[1]; + }; + + + function maybeWrapResponse(resp) { + var type = typeof resp; + if ((type == "string") || (type == "xml")) { + return {body:resp}; + } else { + return resp; + } + }; + + // from http://javascript.crockford.com/remedial.html + function typeOf(value) { + var s = typeof value; + if (s === 'object') { + if (value) { + if (value instanceof Array) { + s = 'array'; + } + } else { + s = 'null'; + } + } + return s; + }; + + function isDocRequestPath(info) { + var path = info.path; + return path.length > 5; + }; + + function runShow(fun, ddoc, args) { + try { + resetList(); + Mime.resetProvides(); + var resp = fun.apply(ddoc, args) || {}; + + // handle list() style API + if (chunks.length && chunks.length > 0) { + resp = maybeWrapResponse(resp); + resp.headers = resp.headers || {}; + for(var header in startResp) { + resp.headers[header] = startResp[header] + } + resp.body = chunks.join("") + (resp.body || ""); + resetList(); + } + + if (Mime.providesUsed) { + resp = Mime.runProvides(args[1], ddoc); + resp = applyContentType(maybeWrapResponse(resp), Mime.responseContentType); + } + + var type = typeOf(resp); + if (type == 'object' || type == 'string') { + respond(["resp", maybeWrapResponse(resp)]); + } else { + throw(["error", "render_error", "undefined response from show function"]); + } + } catch(e) { + if (args[0] === null && isDocRequestPath(args[1])) { + throw(["error", "not_found", "document not found"]); + } else { + renderError(e, fun.toSource()); + } + } + }; + + function runUpdate(fun, ddoc, args) { + try { + var method = args[1].method; + // for analytics logging applications you might want to remove the next line + if (method == "GET") throw(["error","method_not_allowed","Update functions do not allow GET"]); + var result = fun.apply(ddoc, args); + var doc = result[0]; + var resp = result[1]; + var type = typeOf(resp); + if (type == 'object' || type == 'string') { + respond(["up", doc, maybeWrapResponse(resp)]); + } else { + throw(["error", "render_error", "undefined response from update function"]); + } + } catch(e) { + renderError(e, fun.toSource()); + } + }; + + function resetList() { + gotRow = false; + lastRow = false; + chunks = []; + startResp = {}; + }; + + function runList(listFun, ddoc, args) { + try { + Mime.resetProvides(); + resetList(); + head = args[0] + req = args[1] + var tail = listFun.apply(ddoc, args); + + if (Mime.providesUsed) { + tail = Mime.runProvides(req, ddoc); + } + if (!gotRow) getRow(); + if (typeof tail != "undefined") { + chunks.push(tail); + } + blowChunks("end"); + } catch(e) { + renderError(e, listFun.toSource()); + } + }; + + function renderError(e, funSrc) { + if (e.error && e.reason || e[0] == "error" || e[0] == "fatal") { + throw(e); + } else { + var logMessage = "function raised error: "+e.toSource()+" \nstacktrace: "+e.stack; + log(logMessage); + throw(["error", "render_error", logMessage]); + } + }; + + function escapeHTML(string) { + return string && string.replace(/&/g, "&") + .replace(//g, ">"); + }; + + + return { + start : start, + send : send, + getRow : getRow, + show : function(fun, ddoc, args) { + // var showFun = Couch.compileFunction(funSrc); + runShow(fun, ddoc, args); + }, + update : function(fun, ddoc, args) { + // var upFun = Couch.compileFunction(funSrc); + runUpdate(fun, ddoc, args); + }, + list : function(fun, ddoc, args) { + runList(fun, ddoc, args); + } + }; +})(); + +// send = Render.send; +// getRow = Render.getRow; +// start = Render.start; + +// unused. this will be handled in the Erlang side of things. +// function htmlRenderError(e, funSrc) { +// var msg = ["

Render Error

", +// "

JavaScript function raised error: ", +// e.toString(), +// "

Stacktrace:

",
+//     escapeHTML(e.stack),
+//     "

Function source:

",
+//     escapeHTML(funSrc),
+//     "
"].join(''); +// return {body:msg}; +// }; diff --git a/1.1.x/share/server/state.js b/1.1.x/share/server/state.js new file mode 100644 index 00000000..e6416382 --- /dev/null +++ b/1.1.x/share/server/state.js @@ -0,0 +1,32 @@ +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy of +// the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations under +// the License. + +var State = { + reset : function(config) { + // clear the globals and run gc + State.funs = []; + State.lib = null; + State.query_config = config || {}; + init_sandbox(); + gc(); + print("true"); // indicates success + }, + addFun : function(newFun) { + // Compile to a function and add it to funs array + State.funs.push(Couch.compileFunction(newFun, {views : {lib : State.lib}})); + print("true"); + }, + addLib : function(lib) { + State.lib = lib; + print("true"); + } +} diff --git a/1.1.x/share/server/util.js b/1.1.x/share/server/util.js new file mode 100644 index 00000000..e4386701 --- /dev/null +++ b/1.1.x/share/server/util.js @@ -0,0 +1,146 @@ +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy of +// the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations under +// the License. + +var resolveModule = function(names, mod, root) { + if (names.length == 0) { + if (typeof mod.current != "string") { + throw ["error","invalid_require_path", + 'Must require a JavaScript string, not: '+(typeof mod.current)]; + } + return { + current : mod.current, + parent : mod.parent, + id : mod.id, + exports : {} + } + } + // we need to traverse the path + var n = names.shift(); + if (n == '..') { + if (!(mod.parent && mod.parent.parent)) { + throw ["error", "invalid_require_path", 'Object has no parent '+JSON.stringify(mod.current)]; + } + return resolveModule(names, { + id : mod.id.slice(0, mod.id.lastIndexOf('/')), + parent : mod.parent.parent, + current : mod.parent.current + }); + } else if (n == '.') { + if (!mod.parent) { + throw ["error", "invalid_require_path", 'Object has no parent '+JSON.stringify(mod.current)]; + } + return resolveModule(names, { + parent : mod.parent, + current : mod.current, + id : mod.id + }); + } else if (root) { + mod = {current : root}; + } + if (!mod.current[n]) { + throw ["error", "invalid_require_path", 'Object has no property "'+n+'". '+JSON.stringify(mod.current)]; + } + return resolveModule(names, { + current : mod.current[n], + parent : mod, + id : mod.id ? mod.id + '/' + n : n + }); +}; + +var Couch = { + // moving this away from global so we can move to json2.js later + toJSON : function (val) { + return JSON.stringify(val); + }, + compileFunction : function(source, ddoc) { + if (!source) throw(["error","not_found","missing function"]); + try { + if (sandbox) { + if (ddoc) { + if (!ddoc._module_cache) { + ddoc._module_cache = {}; + } + var require = function(name, module) { + module = module || {}; + var newModule = resolveModule(name.split('/'), module.parent, ddoc); + if (!ddoc._module_cache.hasOwnProperty(newModule.id)) { + // create empty exports object before executing the module, + // stops circular requires from filling the stack + ddoc._module_cache[newModule.id] = {}; + var s = "function (module, exports, require) { " + newModule.current + " }"; + try { + var func = sandbox ? evalcx(s, sandbox) : eval(s); + func.apply(sandbox, [newModule, newModule.exports, function(name) { + return require(name, newModule); + }]); + } catch(e) { + throw ["error","compilation_error","Module require('"+name+"') raised error "+e.toSource()]; + } + ddoc._module_cache[newModule.id] = newModule.exports; + } + return ddoc._module_cache[newModule.id]; + } + sandbox.require = require; + } + var functionObject = evalcx(source, sandbox); + } else { + var functionObject = eval(source); + } + } catch (err) { + throw(["error", "compilation_error", err.toSource() + " (" + source + ")"]); + }; + if (typeof(functionObject) == "function") { + return functionObject; + } else { + throw(["error","compilation_error", + "Expression does not eval to a function. (" + source.toSource() + ")"]); + }; + }, + recursivelySeal : function(obj) { + // seal() is broken in current Spidermonkey + try { + seal(obj); + } catch (x) { + // Sealing of arrays broken in some SpiderMonkey versions. + // https://bugzilla.mozilla.org/show_bug.cgi?id=449657 + } + for (var propname in obj) { + if (typeof obj[propname] == "object") { + arguments.callee(obj[propname]); + } + } + } +} + +// prints the object as JSON, and rescues and logs any toJSON() related errors +function respond(obj) { + try { + print(Couch.toJSON(obj)); + } catch(e) { + log("Error converting object to JSON: " + e.toString()); + log("error on obj: "+ obj.toSource()); + } +}; + +function log(message) { + // idea: query_server_config option for log level + if (typeof message == "xml") { + message = message.toXMLString(); + } else if (typeof message != "string") { + message = Couch.toJSON(message); + } + respond(["log", String(message)]); +}; + +function isArray(obj) { + return toString.call(obj) === "[object Array]"; +} diff --git a/1.1.x/share/server/validate.js b/1.1.x/share/server/validate.js new file mode 100644 index 00000000..76a14129 --- /dev/null +++ b/1.1.x/share/server/validate.js @@ -0,0 +1,22 @@ +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy of +// the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations under +// the License. + +var Validate = { + validate : function(fun, ddoc, args) { + try { + fun.apply(ddoc, args); + print("1"); + } catch (error) { + respond(error); + } + } +}; diff --git a/1.1.x/share/server/views.js b/1.1.x/share/server/views.js new file mode 100644 index 00000000..2a15ee56 --- /dev/null +++ b/1.1.x/share/server/views.js @@ -0,0 +1,126 @@ +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy of +// the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations under +// the License. + + + +var Views = (function() { + + var map_results = []; // holds temporary emitted values during doc map + + function runReduce(reduceFuns, keys, values, rereduce) { + for (var i in reduceFuns) { + reduceFuns[i] = Couch.compileFunction(reduceFuns[i]); + }; + var reductions = new Array(reduceFuns.length); + for(var i = 0; i < reduceFuns.length; i++) { + try { + reductions[i] = reduceFuns[i](keys, values, rereduce); + } catch (err) { + handleViewError(err); + // if the error is not fatal, ignore the results and continue + reductions[i] = null; + } + }; + var reduce_line = Couch.toJSON(reductions); + var reduce_length = reduce_line.length; + // TODO make reduce_limit config into a number + if (State.query_config && State.query_config.reduce_limit && + reduce_length > 200 && ((reduce_length * 2) > State.line_length)) { + var reduce_preview = "Current output: '"+(reduce_line.substring(0,100) + "'... (first 100 of "+reduce_length+" bytes)"); + throw(["error", + "reduce_overflow_error", + "Reduce output must shrink more rapidly: "+reduce_preview]); + } else { + print("[true," + reduce_line + "]"); + } + }; + + function handleViewError(err, doc) { + if (err == "fatal_error") { + // Only if it's a "fatal_error" do we exit. What's a fatal error? + // That's for the query to decide. + // + // This will make it possible for queries to completely error out, + // by catching their own local exception and rethrowing a + // fatal_error. But by default if they don't do error handling we + // just eat the exception and carry on. + // + // In this case we abort map processing but don't destroy the + // JavaScript process. If you need to destroy the JavaScript + // process, throw the error form matched by the block below. + throw(["error", "map_runtime_error", "function raised 'fatal_error'"]); + } else if (err[0] == "fatal") { + // Throwing errors of the form ["fatal","error_key","reason"] + // will kill the OS process. This is not normally what you want. + throw(err); + } + var message = "function raised exception " + err.toSource(); + if (doc) message += " with doc._id " + doc._id; + log(message); + }; + + return { + // view helper functions + emit : function(key, value) { + map_results.push([key, value]); + }, + sum : function(values) { + var rv = 0; + for (var i in values) { + rv += values[i]; + } + return rv; + }, + reduce : function(reduceFuns, kvs) { + var keys = new Array(kvs.length); + var values = new Array(kvs.length); + for(var i = 0; i < kvs.length; i++) { + keys[i] = kvs[i][0]; + values[i] = kvs[i][1]; + } + runReduce(reduceFuns, keys, values, false); + }, + rereduce : function(reduceFuns, values) { + runReduce(reduceFuns, null, values, true); + }, + mapDoc : function(doc) { + // Compute all the map functions against the document. + // + // Each function can output multiple key/value pairs for each document. + // + // Example output of map_doc after three functions set by add_fun cmds: + // [ + // [["Key","Value"]], <- fun 1 returned 1 key value + // [], <- fun 2 returned 0 key values + // [["Key1","Value1"],["Key2","Value2"]] <- fun 3 returned 2 key values + // ] + // + + Couch.recursivelySeal(doc); + + var buf = []; + for (var i = 0; i < State.funs.length; i++) { + map_results = []; + try { + State.funs[i](doc); + buf.push(Couch.toJSON(map_results)); + } catch (err) { + handleViewError(err, doc); + // If the error is not fatal, we treat the doc as if it + // did not emit anything, by buffering an empty array. + buf.push("[]"); + } + } + print("[" + buf.join(", ") + "]"); + } + } +})(); diff --git a/1.1.x/share/www/_sidebar.html b/1.1.x/share/www/_sidebar.html new file mode 100644 index 00000000..563a85c8 --- /dev/null +++ b/1.1.x/share/www/_sidebar.html @@ -0,0 +1,59 @@ + + diff --git a/1.1.x/share/www/config.html b/1.1.x/share/www/config.html new file mode 100644 index 00000000..9863c8b5 --- /dev/null +++ b/1.1.x/share/www/config.html @@ -0,0 +1,135 @@ + + + + + Configuration + + + + + + + + + + + +
+

+ Overview + Configuration +

+
+

+ Note: Some configuration options may require + restarting the server to take effect after modification. +

+

+ For the strongest consistency guarantees, delayed_commits should be set to false. The default value of true is designed for single-user performance. For more details see a discussion of durability on the CouchDB wiki. +

+ + + + + + + + + +
Configuration
SectionOptionValueDelete
+ +
+
+ diff --git a/1.1.x/share/www/couch_tests.html b/1.1.x/share/www/couch_tests.html new file mode 100644 index 00000000..f10bad23 --- /dev/null +++ b/1.1.x/share/www/couch_tests.html @@ -0,0 +1,98 @@ + + + + + Test Suite + + + + + + + + + + + + +
+

+ Overview + Test Suite +

+
+
    +
  • +
  • +
  • +
  • +
  • +
+

+ Note: Each of the tests will block the browser. If the + connection to your CouchDB server is slow, running the tests will take + some time, and you'll not be able to do much with your browser while + a test is being executed. Also: The test suite is designed + to work with Firefox (with Firebug disabled). Patches are welcome for + convenience compatibility with other browsers, but official support is + for Firefox (latest stable version) only. +

+ + + + + + + + + + + + + + + + + + +
Tests
NameStatusElapsed TimeDetails
+ +
+
+ diff --git a/1.1.x/share/www/custom_test.html b/1.1.x/share/www/custom_test.html new file mode 100644 index 00000000..2566a000 --- /dev/null +++ b/1.1.x/share/www/custom_test.html @@ -0,0 +1,112 @@ + + + + + Custom Test + + + + + + + + + + + + + + +
+

+ Overview + Test Suite + Custom Test +

+ +
+
+
+ Test Function +
+ + +
+ +
+
+ +    +
+
+
+
+ diff --git a/1.1.x/share/www/database.html b/1.1.x/share/www/database.html new file mode 100644 index 00000000..9a9f121e --- /dev/null +++ b/1.1.x/share/www/database.html @@ -0,0 +1,267 @@ + + + + + Browse Database + + + + + + + + + + + + + + + +
+

+ Overview + ? + +

+
+
+ +
+
+ +
+
+ +
+
    +
  • +
  • +
  • +
  • +
+ + +

+ Warning: Please note that temporary views are not + suitable for use in production, as they are really slow for any + database with more than a few dozen documents. You can use a temporary + view to experiment with view functions, but switch to a permanent view + before using them in an application. +

+ + + + + + + + + + + + + + + + +
Documents
+ + Key + + + Value +
+
+ | + | + +
+ +
+
+
+ diff --git a/1.1.x/share/www/dialog/_admin_party.html b/1.1.x/share/www/dialog/_admin_party.html new file mode 100644 index 00000000..ea9fb15a --- /dev/null +++ b/1.1.x/share/www/dialog/_admin_party.html @@ -0,0 +1,33 @@ + +
+

Admin Party!

+
+

+ The test suite requires CouchDB to be in Admin Party mode. This + mode give all users admin capabilities. This is the least secure mode of + operation. Do not run the tests on production servers, as you'll impact + both performance and security. +

+

+ Clicking ā€œRemove Adminsā€ will remove all admins from the configuration. You will + have to recreate any admins by hand after the tests have finished. +

+
+
+ + +
+
diff --git a/1.1.x/share/www/dialog/_change_password.html b/1.1.x/share/www/dialog/_change_password.html new file mode 100644 index 00000000..40601d9a --- /dev/null +++ b/1.1.x/share/www/dialog/_change_password.html @@ -0,0 +1,31 @@ + +
+

Change Password

+
+ + + + + + + +
+
+
+ + +
+
diff --git a/1.1.x/share/www/dialog/_compact_cleanup.html b/1.1.x/share/www/dialog/_compact_cleanup.html new file mode 100644 index 00000000..506417f4 --- /dev/null +++ b/1.1.x/share/www/dialog/_compact_cleanup.html @@ -0,0 +1,51 @@ + +
+

Compact & Cleanup

+
+ +

+ Compacting a database removes deleted documents and previous revisions. + It is an irreversible operation and may take + a while to complete for large databases. +

+
+ +

+ View compaction will affect all views in this design document. This + operation may take some time to complete. Your views will still operate + normally during compaction. +

+
+ +

+ Cleaning up views in a database removes old view files still stored + on the filesystem. It is an irreversible operation. +

+
+
+ + +
+
diff --git a/1.1.x/share/www/dialog/_create_admin.html b/1.1.x/share/www/dialog/_create_admin.html new file mode 100644 index 00000000..d4aec95a --- /dev/null +++ b/1.1.x/share/www/dialog/_create_admin.html @@ -0,0 +1,50 @@ + +
+

Create Server Admin

+
+

+ Before a server admin is configured, all clients have admin privileges. + This is fine when HTTP access is restricted + to trusted users. If end-users will be accessing this CouchDB, you must + create an admin account to prevent accidental (or malicious) data loss. +

+

Server admins can create and destroy databases, install + and update _design documents, run the test suite, and edit all aspects of CouchDB + configuration. +

+ + + + + + + +
+

Non-admin users have read and write access to all databases, which + are controlled by validation functions. CouchDB can be configured to block all + access to anonymous users. +

+

About Authentication

+

+ Couch has a pluggable authentication mechanism. Futon exposes a user friendly cookie-auth which handles login and logout, so app developers can relax. Just use $.couch.session() to load the current user's info. +

+ +
+
+ + +
+
diff --git a/1.1.x/share/www/dialog/_create_config.html b/1.1.x/share/www/dialog/_create_config.html new file mode 100644 index 00000000..79e08b08 --- /dev/null +++ b/1.1.x/share/www/dialog/_create_config.html @@ -0,0 +1,42 @@ + +
+

Create New Config Option

+
+

+ Please enter the section, option, and value. +

+ + + + + + + + + + + + + + + +
+
+
+ + +
+
diff --git a/1.1.x/share/www/dialog/_create_database.html b/1.1.x/share/www/dialog/_create_database.html new file mode 100644 index 00000000..74e7ea61 --- /dev/null +++ b/1.1.x/share/www/dialog/_create_database.html @@ -0,0 +1,33 @@ + +
+

Create New Database

+
+

+ Please enter the name of the database. Note that only lowercase + characters (a-z), digits (0-9), or any of the + characters _, $, (, ), +, + -, and / are allowed. +

+ + + +
+
+
+ + +
+
diff --git a/1.1.x/share/www/dialog/_database_security.html b/1.1.x/share/www/dialog/_database_security.html new file mode 100644 index 00000000..d63fa787 --- /dev/null +++ b/1.1.x/share/www/dialog/_database_security.html @@ -0,0 +1,50 @@ + +
+

Security

+
+

+ Each database contains lists of admins and readers. + Admins and readers are each defined by names and roles, which are lists of strings. +

+ +

Admins

+

Database admins can update design documents and edit the readers list.

+ + + + + + + +
+ +

Readers

+

Database readers can access the database. If no readers are defined, the database is public.

+ + + + + + + +
+ +
+
+ + +
+
diff --git a/1.1.x/share/www/dialog/_delete_database.html b/1.1.x/share/www/dialog/_delete_database.html new file mode 100644 index 00000000..039ba39b --- /dev/null +++ b/1.1.x/share/www/dialog/_delete_database.html @@ -0,0 +1,27 @@ + +
+

Delete Database

+
+

+ Are you sure you want to delete this database? Note that this is an + irreversible operation! +

+
+
+ + +
+
diff --git a/1.1.x/share/www/dialog/_delete_document.html b/1.1.x/share/www/dialog/_delete_document.html new file mode 100644 index 00000000..8ae89710 --- /dev/null +++ b/1.1.x/share/www/dialog/_delete_document.html @@ -0,0 +1,26 @@ + +
+

Delete Document

+
+

+ Are you sure you want to delete this document? +

+
+
+ + +
+
diff --git a/1.1.x/share/www/dialog/_login.html b/1.1.x/share/www/dialog/_login.html new file mode 100644 index 00000000..f05a5fdc --- /dev/null +++ b/1.1.x/share/www/dialog/_login.html @@ -0,0 +1,34 @@ + +
+

Login

+
+

+ Login to CouchDB with your name and password. +

+ + + + + + + +
+
+
+ + +
+
diff --git a/1.1.x/share/www/dialog/_save_view_as.html b/1.1.x/share/www/dialog/_save_view_as.html new file mode 100644 index 00000000..d59122bf --- /dev/null +++ b/1.1.x/share/www/dialog/_save_view_as.html @@ -0,0 +1,35 @@ + +
+

Save View As…

+
+

+ You can save this function code as a permanent view in the database. Just + enter or select the design document and the name of the view below. Note + that if you choose an existing view, it will be overwritten! +

+ + + + + + +
_design/
+
+
+ + +
+
diff --git a/1.1.x/share/www/dialog/_share_test_reports.html b/1.1.x/share/www/dialog/_share_test_reports.html new file mode 100644 index 00000000..82b49a74 --- /dev/null +++ b/1.1.x/share/www/dialog/_share_test_reports.html @@ -0,0 +1,42 @@ + +
+

Share Test Reports

+
+

+ After each test run, a results summary document is stored in + your local + test_suite_reports database. The data has no personally + identifying information, just details about the test run and your CouchDB + and browser versions. (Click the red link above to see what's stored.) + The data remains private until you click the "share" button below. +

+

+ Test reports are very valuable to the CouchDB community, and are easy to share. + Clicking the "share" button below triggers replication from + your local test_suite_reports database, to a database hosted by the + project. +

+

+ + Browse test reports shared by other users. + Thank you for sharing! +

+
+
+ + +
+
diff --git a/1.1.x/share/www/dialog/_signup.html b/1.1.x/share/www/dialog/_signup.html new file mode 100644 index 00000000..7ba3448a --- /dev/null +++ b/1.1.x/share/www/dialog/_signup.html @@ -0,0 +1,35 @@ + +
+

Create User Account

+
+

+ Create a user document on this CouchDB. You will be logged in as this + user after the document is created. +

+ + + + + + + +
+
+
+ + +
+
diff --git a/1.1.x/share/www/dialog/_upload_attachment.html b/1.1.x/share/www/dialog/_upload_attachment.html new file mode 100644 index 00000000..50b7e1fa --- /dev/null +++ b/1.1.x/share/www/dialog/_upload_attachment.html @@ -0,0 +1,36 @@ + +
+

Upload Attachment

+
+

+ Please select the file you want to upload as an attachment to this + document. Please note that this will result in the immediate creation of + a new revision of the document, so it's not necessary to save the + document after the upload. +

+ + + + + +
 
+
+
+ + + +
+
diff --git a/1.1.x/share/www/document.html b/1.1.x/share/www/document.html new file mode 100644 index 00000000..b6f42018 --- /dev/null +++ b/1.1.x/share/www/document.html @@ -0,0 +1,114 @@ + + + + + View Document + + + + + + + + + + + + + + + + + +
+

+ Overview + ? + ? + +

+
+
    +
  • +
  • +
  • +
  • +
+ + + + + + + + + + + + + + + + + + + + + +
Fields
FieldValue
+ + +
+ +
+
+ diff --git a/1.1.x/share/www/favicon.ico b/1.1.x/share/www/favicon.ico new file mode 100644 index 00000000..34bfaa86 Binary files /dev/null and b/1.1.x/share/www/favicon.ico differ diff --git a/1.1.x/share/www/image/add.png b/1.1.x/share/www/image/add.png new file mode 100644 index 00000000..34e8c7d7 Binary files /dev/null and b/1.1.x/share/www/image/add.png differ diff --git a/1.1.x/share/www/image/apply.gif b/1.1.x/share/www/image/apply.gif new file mode 100644 index 00000000..63de0d53 Binary files /dev/null and b/1.1.x/share/www/image/apply.gif differ diff --git a/1.1.x/share/www/image/bg.png b/1.1.x/share/www/image/bg.png new file mode 100644 index 00000000..ec815244 Binary files /dev/null and b/1.1.x/share/www/image/bg.png differ diff --git a/1.1.x/share/www/image/cancel.gif b/1.1.x/share/www/image/cancel.gif new file mode 100644 index 00000000..4329076e Binary files /dev/null and b/1.1.x/share/www/image/cancel.gif differ diff --git a/1.1.x/share/www/image/compact.png b/1.1.x/share/www/image/compact.png new file mode 100644 index 00000000..ea8985dc Binary files /dev/null and b/1.1.x/share/www/image/compact.png differ diff --git a/1.1.x/share/www/image/delete-mini.png b/1.1.x/share/www/image/delete-mini.png new file mode 100644 index 00000000..ad5588d9 Binary files /dev/null and b/1.1.x/share/www/image/delete-mini.png differ diff --git a/1.1.x/share/www/image/delete.png b/1.1.x/share/www/image/delete.png new file mode 100644 index 00000000..e8384017 Binary files /dev/null and b/1.1.x/share/www/image/delete.png differ diff --git a/1.1.x/share/www/image/grippie.gif b/1.1.x/share/www/image/grippie.gif new file mode 100644 index 00000000..a8807896 Binary files /dev/null and b/1.1.x/share/www/image/grippie.gif differ diff --git a/1.1.x/share/www/image/hgrad.gif b/1.1.x/share/www/image/hgrad.gif new file mode 100644 index 00000000..08aa80ca Binary files /dev/null and b/1.1.x/share/www/image/hgrad.gif differ diff --git a/1.1.x/share/www/image/key.png b/1.1.x/share/www/image/key.png new file mode 100644 index 00000000..e04ed108 Binary files /dev/null and b/1.1.x/share/www/image/key.png differ diff --git a/1.1.x/share/www/image/load.png b/1.1.x/share/www/image/load.png new file mode 100644 index 00000000..07b4f791 Binary files /dev/null and b/1.1.x/share/www/image/load.png differ diff --git a/1.1.x/share/www/image/logo.png b/1.1.x/share/www/image/logo.png new file mode 100644 index 00000000..d21ac025 Binary files /dev/null and b/1.1.x/share/www/image/logo.png differ diff --git a/1.1.x/share/www/image/order-asc.gif b/1.1.x/share/www/image/order-asc.gif new file mode 100644 index 00000000..d2a237ae Binary files /dev/null and b/1.1.x/share/www/image/order-asc.gif differ diff --git a/1.1.x/share/www/image/order-desc.gif b/1.1.x/share/www/image/order-desc.gif new file mode 100644 index 00000000..1043b499 Binary files /dev/null and b/1.1.x/share/www/image/order-desc.gif differ diff --git a/1.1.x/share/www/image/path.gif b/1.1.x/share/www/image/path.gif new file mode 100644 index 00000000..01ec717e Binary files /dev/null and b/1.1.x/share/www/image/path.gif differ diff --git a/1.1.x/share/www/image/progress.gif b/1.1.x/share/www/image/progress.gif new file mode 100644 index 00000000..d84f6537 Binary files /dev/null and b/1.1.x/share/www/image/progress.gif differ diff --git a/1.1.x/share/www/image/rarrow.png b/1.1.x/share/www/image/rarrow.png new file mode 100644 index 00000000..507e87e7 Binary files /dev/null and b/1.1.x/share/www/image/rarrow.png differ diff --git a/1.1.x/share/www/image/run-mini.png b/1.1.x/share/www/image/run-mini.png new file mode 100644 index 00000000..b2fcbd82 Binary files /dev/null and b/1.1.x/share/www/image/run-mini.png differ diff --git a/1.1.x/share/www/image/run.png b/1.1.x/share/www/image/run.png new file mode 100644 index 00000000..a1d79f65 Binary files /dev/null and b/1.1.x/share/www/image/run.png differ diff --git a/1.1.x/share/www/image/running.png b/1.1.x/share/www/image/running.png new file mode 100644 index 00000000..9b50cd67 Binary files /dev/null and b/1.1.x/share/www/image/running.png differ diff --git a/1.1.x/share/www/image/save.png b/1.1.x/share/www/image/save.png new file mode 100644 index 00000000..a04e4bcc Binary files /dev/null and b/1.1.x/share/www/image/save.png differ diff --git a/1.1.x/share/www/image/sidebar-toggle.png b/1.1.x/share/www/image/sidebar-toggle.png new file mode 100644 index 00000000..3ea32ffe Binary files /dev/null and b/1.1.x/share/www/image/sidebar-toggle.png differ diff --git a/1.1.x/share/www/image/spinner.gif b/1.1.x/share/www/image/spinner.gif new file mode 100644 index 00000000..6239655e Binary files /dev/null and b/1.1.x/share/www/image/spinner.gif differ diff --git a/1.1.x/share/www/image/spinner_33.gif b/1.1.x/share/www/image/spinner_33.gif new file mode 100644 index 00000000..5ad51927 Binary files /dev/null and b/1.1.x/share/www/image/spinner_33.gif differ diff --git a/1.1.x/share/www/image/spinner_6b.gif b/1.1.x/share/www/image/spinner_6b.gif new file mode 100644 index 00000000..4e3d9725 Binary files /dev/null and b/1.1.x/share/www/image/spinner_6b.gif differ diff --git a/1.1.x/share/www/image/test_failure.gif b/1.1.x/share/www/image/test_failure.gif new file mode 100644 index 00000000..2a873b24 Binary files /dev/null and b/1.1.x/share/www/image/test_failure.gif differ diff --git a/1.1.x/share/www/image/test_success.gif b/1.1.x/share/www/image/test_success.gif new file mode 100644 index 00000000..6df8bae2 Binary files /dev/null and b/1.1.x/share/www/image/test_success.gif differ diff --git a/1.1.x/share/www/image/thead-key.gif b/1.1.x/share/www/image/thead-key.gif new file mode 100644 index 00000000..42a43b58 Binary files /dev/null and b/1.1.x/share/www/image/thead-key.gif differ diff --git a/1.1.x/share/www/image/thead.gif b/1.1.x/share/www/image/thead.gif new file mode 100644 index 00000000..1587b1f2 Binary files /dev/null and b/1.1.x/share/www/image/thead.gif differ diff --git a/1.1.x/share/www/image/toggle-collapse.gif b/1.1.x/share/www/image/toggle-collapse.gif new file mode 100644 index 00000000..f0979304 Binary files /dev/null and b/1.1.x/share/www/image/toggle-collapse.gif differ diff --git a/1.1.x/share/www/image/toggle-expand.gif b/1.1.x/share/www/image/toggle-expand.gif new file mode 100644 index 00000000..03fa8360 Binary files /dev/null and b/1.1.x/share/www/image/toggle-expand.gif differ diff --git a/1.1.x/share/www/image/twisty.gif b/1.1.x/share/www/image/twisty.gif new file mode 100644 index 00000000..5ba57a1a Binary files /dev/null and b/1.1.x/share/www/image/twisty.gif differ diff --git a/1.1.x/share/www/index.html b/1.1.x/share/www/index.html new file mode 100644 index 00000000..975f5986 --- /dev/null +++ b/1.1.x/share/www/index.html @@ -0,0 +1,94 @@ + + + + + Overview + + + + + + + + + + + + + +
+

Overview

+
+
    +
  • +
+ + + + + + + + + + + + + + + + + + +
Databases
NameSizeNumber of DocumentsUpdate Seq
+
+ | + | + +
+ +
+
+ +
+ + diff --git a/1.1.x/share/www/replicator.html b/1.1.x/share/www/replicator.html new file mode 100644 index 00000000..16c0940b --- /dev/null +++ b/1.1.x/share/www/replicator.html @@ -0,0 +1,184 @@ + + + + + Replicator + + + + + + + + + + + + +
+

+ Overview + Replicator +

+
+ +
+
+ Replicate changes from: +

+ + + +

+ + + +

+
+

+
+ to: +

+ + + +

+ + + +

+
+

+ + +

+
+ + + + + + + + + + +
Replication History
Event
No replication
+ +
+
+ diff --git a/1.1.x/share/www/script/base64.js b/1.1.x/share/www/script/base64.js new file mode 100644 index 00000000..e0aab303 --- /dev/null +++ b/1.1.x/share/www/script/base64.js @@ -0,0 +1,124 @@ +/* Copyright (C) 1999 Masanao Izumo + * Version: 1.0 + * LastModified: Dec 25 1999 + * This library is free. You can redistribute it and/or modify it. + */ + /* Modified by Chris Anderson to not use CommonJS */ + /* Modified by Dan Webb not to require Narwhal's binary library */ + +var Base64 = {}; +(function(exports) { + + var encodeChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + var decodeChars = [ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, + -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, + -1, 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, -1, -1, -1, -1, -1 + ]; + + exports.encode = function (str) { + var out, i, length; + var c1, c2, c3; + + length = len(str); + i = 0; + out = []; + while(i < length) { + c1 = str.charCodeAt(i++) & 0xff; + if(i == length) + { + out.push(encodeChars.charCodeAt(c1 >> 2)); + out.push(encodeChars.charCodeAt((c1 & 0x3) << 4)); + out.push("=".charCodeAt(0)); + out.push("=".charCodeAt(0)); + break; + } + c2 = str.charCodeAt(i++); + if(i == length) + { + out.push(encodeChars.charCodeAt(c1 >> 2)); + out.push(encodeChars.charCodeAt(((c1 & 0x3)<< 4) | ((c2 & 0xF0) >> 4))); + out.push(encodeChars.charCodeAt((c2 & 0xF) << 2)); + out.push("=".charCodeAt(0)); + break; + } + c3 = str.charCodeAt(i++); + out.push(encodeChars.charCodeAt(c1 >> 2)); + out.push(encodeChars.charCodeAt(((c1 & 0x3)<< 4) | ((c2 & 0xF0) >> 4))); + out.push(encodeChars.charCodeAt(((c2 & 0xF) << 2) | ((c3 & 0xC0) >>6))); + out.push(encodeChars.charCodeAt(c3 & 0x3F)); + } + + var str = ""; + out.forEach(function(chr) { str += String.fromCharCode(chr) }); + return str; + }; + + exports.decode = function (str) { + var c1, c2, c3, c4; + var i, length, out; + + length = len(str); + i = 0; + out = []; + while(i < length) { + /* c1 */ + do { + c1 = decodeChars[str.charCodeAt(i++) & 0xff]; + } while(i < length && c1 == -1); + if(c1 == -1) + break; + + /* c2 */ + do { + c2 = decodeChars[str.charCodeAt(i++) & 0xff]; + } while(i < length && c2 == -1); + if(c2 == -1) + break; + + out.push(String.fromCharCode((c1 << 2) | ((c2 & 0x30) >> 4))); + + /* c3 */ + do { + c3 = str.charCodeAt(i++) & 0xff; + if(c3 == 61) + return out.join(''); + c3 = decodeChars[c3]; + } while(i < length && c3 == -1); + if(c3 == -1) + break; + + out.push(String.fromCharCode(((c2 & 0xF) << 4) | ((c3 & 0x3C) >> 2))); + + /* c4 */ + do { + c4 = str.charCodeAt(i++) & 0xff; + if(c4 == 61) + return out.join(''); + c4 = decodeChars[c4]; + } while(i < length && c4 == -1); + + if(c4 == -1) + break; + + out.push(String.fromCharCode(((c3 & 0x03) << 6) | c4)); + } + + return out.join(''); + }; + + var len = function (object) { + if (object.length !== undefined) { + return object.length; + } else if (object.getLength !== undefined) { + return object.getLength(); + } else { + return undefined; + } + }; +})(Base64); diff --git a/1.1.x/share/www/script/couch.js b/1.1.x/share/www/script/couch.js new file mode 100644 index 00000000..bcc19652 --- /dev/null +++ b/1.1.x/share/www/script/couch.js @@ -0,0 +1,473 @@ +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy of +// the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations under +// the License. + +// A simple class to represent a database. Uses XMLHttpRequest to interface with +// the CouchDB server. + +function CouchDB(name, httpHeaders) { + this.name = name; + this.uri = "/" + encodeURIComponent(name) + "/"; + + // The XMLHttpRequest object from the most recent request. Callers can + // use this to check result http status and headers. + this.last_req = null; + + this.request = function(method, uri, requestOptions) { + requestOptions = requestOptions || {}; + requestOptions.headers = combine(requestOptions.headers, httpHeaders); + return CouchDB.request(method, uri, requestOptions); + }; + + // Creates the database on the server + this.createDb = function() { + this.last_req = this.request("PUT", this.uri); + CouchDB.maybeThrowError(this.last_req); + return JSON.parse(this.last_req.responseText); + }; + + // Deletes the database on the server + this.deleteDb = function() { + this.last_req = this.request("DELETE", this.uri); + if (this.last_req.status == 404) { + return false; + } + CouchDB.maybeThrowError(this.last_req); + return JSON.parse(this.last_req.responseText); + }; + + // Save a document to the database + this.save = function(doc, options) { + if (doc._id == undefined) { + doc._id = CouchDB.newUuids(1)[0]; + } + + this.last_req = this.request("PUT", this.uri + + encodeURIComponent(doc._id) + encodeOptions(options), + {body: JSON.stringify(doc)}); + CouchDB.maybeThrowError(this.last_req); + var result = JSON.parse(this.last_req.responseText); + doc._rev = result.rev; + return result; + }; + + // Open a document from the database + this.open = function(docId, options) { + this.last_req = this.request("GET", this.uri + encodeURIComponent(docId) + + encodeOptions(options)); + if (this.last_req.status == 404) { + return null; + } + CouchDB.maybeThrowError(this.last_req); + return JSON.parse(this.last_req.responseText); + }; + + // Deletes a document from the database + this.deleteDoc = function(doc) { + this.last_req = this.request("DELETE", this.uri + encodeURIComponent(doc._id) + + "?rev=" + doc._rev); + CouchDB.maybeThrowError(this.last_req); + var result = JSON.parse(this.last_req.responseText); + doc._rev = result.rev; //record rev in input document + doc._deleted = true; + return result; + }; + + // Deletes an attachment from a document + this.deleteDocAttachment = function(doc, attachment_name) { + this.last_req = this.request("DELETE", this.uri + encodeURIComponent(doc._id) + + "/" + attachment_name + "?rev=" + doc._rev); + CouchDB.maybeThrowError(this.last_req); + var result = JSON.parse(this.last_req.responseText); + doc._rev = result.rev; //record rev in input document + return result; + }; + + this.bulkSave = function(docs, options) { + // first prepoulate the UUIDs for new documents + var newCount = 0; + for (var i=0; i= n) { + var uuids = CouchDB.uuids_cache.slice(CouchDB.uuids_cache.length - n); + if(CouchDB.uuids_cache.length - n == 0) { + CouchDB.uuids_cache = []; + } else { + CouchDB.uuids_cache = + CouchDB.uuids_cache.slice(0, CouchDB.uuids_cache.length - n); + } + return uuids; + } else { + CouchDB.last_req = CouchDB.request("GET", "/_uuids?count=" + (buf + n)); + CouchDB.maybeThrowError(CouchDB.last_req); + var result = JSON.parse(CouchDB.last_req.responseText); + CouchDB.uuids_cache = + CouchDB.uuids_cache.concat(result.uuids.slice(0, buf)); + return result.uuids.slice(buf); + } +}; + +CouchDB.maybeThrowError = function(req) { + if (req.status >= 400) { + try { + var result = JSON.parse(req.responseText); + } catch (ParseError) { + var result = {error:"unknown", reason:req.responseText}; + } + throw result; + } +} + +CouchDB.params = function(options) { + options = options || {}; + var returnArray = []; + for(var key in options) { + var value = options[key]; + returnArray.push(key + "=" + value); + } + return returnArray.join("&"); +}; diff --git a/1.1.x/share/www/script/couch_test_runner.js b/1.1.x/share/www/script/couch_test_runner.js new file mode 100644 index 00000000..55a6533f --- /dev/null +++ b/1.1.x/share/www/script/couch_test_runner.js @@ -0,0 +1,437 @@ +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy of +// the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations under +// the License. + +// *********************** Test Framework of Sorts ************************* // + + +function loadScript(url) { + // disallow loading remote URLs + if((url.substr(0, 7) == "http://") + || (url.substr(0, 2) == "//") + || (url.substr(0, 5) == "data:") + || (url.substr(0, 11) == "javascript:")) { + throw "Not loading remote test scripts"; + } + if (typeof document != "undefined") document.write(''); +}; + +function patchTest(fun) { + var source = fun.toString(); + var output = ""; + var i = 0; + var testMarker = "T("; + while (i < source.length) { + var testStart = source.indexOf(testMarker, i); + if (testStart == -1) { + output = output + source.substring(i, source.length); + break; + } + var testEnd = source.indexOf(");", testStart); + var testCode = source.substring(testStart + testMarker.length, testEnd); + output += source.substring(i, testStart) + "T(" + testCode + "," + JSON.stringify(testCode); + i = testEnd; + } + try { + return eval("(" + output + ")"); + } catch (e) { + return null; + } +} + +function runAllTests() { + var rows = $("#tests tbody.content tr"); + $("td", rows).text(""); + $("td.status", rows).removeClass("error").removeClass("failure").removeClass("success").text("not run"); + var offset = 0; + function runNext() { + if (offset < rows.length) { + var row = rows.get(offset); + runTest($("th button", row).get(0), function() { + offset += 1; + setTimeout(runNext, 100); + }, false, true); + } else { + saveTestReport(); + } + } + runNext(); +} + +var numFailures = 0; +var currentRow = null; + +function runTest(button, callback, debug, noSave) { + + // offer to save admins + if (currentRow != null) { + alert("Can not run multiple tests simultaneously."); + return; + } + var row = currentRow = $(button).parents("tr").get(0); + $("td.status", row).removeClass("error").removeClass("failure").removeClass("success"); + $("td", row).text(""); + $("#toolbar li.current").text("Running: "+row.id); + var testFun = couchTests[row.id]; + function run() { + numFailures = 0; + var start = new Date().getTime(); + try { + if (debug == undefined || !debug) { + testFun = patchTest(testFun) || testFun; + } + testFun(debug); + var status = numFailures > 0 ? "failure" : "success"; + } catch (e) { + var status = "error"; + if ($("td.details ol", row).length == 0) { + $("
    ").appendTo($("td.details", row)); + } + $("
  1. Exception raised:
  2. ") + .find("code").text(JSON.stringify(e)).end() + .appendTo($("td.details ol", row)); + if (debug) { + currentRow = null; + throw e; + } + } + if ($("td.details ol", row).length) { + $("Run with debugger").click(function() { + runTest(this, undefined, true); + }).prependTo($("td.details ol", row)); + } + var duration = new Date().getTime() - start; + $("td.status", row).removeClass("running").addClass(status).text(status); + $("td.duration", row).text(duration + "ms"); + $("#toolbar li.current").text("Finished: "+row.id); + updateTestsFooter(); + currentRow = null; + if (callback) callback(); + if (!noSave) saveTestReport(); + } + $("td.status", row).addClass("running").text("runningā€¦"); + setTimeout(run, 100); +} + +function showSource(cell) { + var name = $(cell).text(); + var win = window.open("", name, "width=700,height=500,resizable=yes,scrollbars=yes"); + win.document.location = "script/test/" + name + ".js"; +} + +var readyToRun; +function setupAdminParty(fun) { + if (readyToRun) { + fun(); + } else { + function removeAdmins(confs, doneFun) { + // iterate through the config and remove current user last + // current user is at front of list + var remove = confs.pop(); + if (remove) { + $.couch.config({ + success : function() { + removeAdmins(confs, doneFun); + } + }, "admins", remove[0], null); + } else { + doneFun(); + } + }; + $.couch.session({ + success : function(resp) { + var userCtx = resp.userCtx; + if (userCtx.name && userCtx.roles.indexOf("_admin") != -1) { + // admin but not admin party. dialog offering to make admin party + $.showDialog("dialog/_admin_party.html", { + submit: function(data, callback) { + $.couch.config({ + success : function(conf) { + var meAdmin, adminConfs = []; + for (var name in conf) { + if (name == userCtx.name) { + meAdmin = [name, conf[name]]; + } else { + adminConfs.push([name, conf[name]]); + } + } + adminConfs.unshift(meAdmin); + removeAdmins(adminConfs, function() { + callback(); + $.futon.session.sidebar(); + readyToRun = true; + setTimeout(fun, 500); + }); + } + }, "admins"); + } + }); + } else if (userCtx.roles.indexOf("_admin") != -1) { + // admin party! + readyToRun = true; + fun(); + } else { + // not an admin + alert("Error: You need to be an admin to run the tests."); + }; + } + }); + } +}; + +function updateTestsListing() { + for (var name in couchTests) { + var testFunction = couchTests[name]; + var row = $("") + .find("th").text(name).attr("title", "Show source").click(function() { + showSource(this); + }).end() + .find("td:nth(0)").addClass("status").text("not run").end() + .find("td:nth(1)").addClass("duration").end() + .find("td:nth(2)").addClass("details").end(); + $("").click(function() { + this.blur(); + var self = this; + // check for admin party + setupAdminParty(function() { + runTest(self); + }); + return false; + }).prependTo(row.find("th")); + row.attr("id", name).appendTo("#tests tbody.content"); + } + $("#tests tr").removeClass("odd").filter(":odd").addClass("odd"); + updateTestsFooter(); +} + +function updateTestsFooter() { + var tests = $("#tests tbody.content tr td.status"); + var testsRun = tests.filter(".success, .error, .failure"); + var testsFailed = testsRun.not(".success"); + var totalDuration = 0; + $("#tests tbody.content tr td.duration:contains('ms')").each(function() { + var text = $(this).text(); + totalDuration += parseInt(text.substr(0, text.length - 2), 10); + }); + $("#tests tbody.footer td").html(""+testsRun.length + " of " + tests.length + + " test(s) run, " + testsFailed.length + " failures (" + + totalDuration + " ms) "); +} + +// make report and save to local db +// display how many reports need replicating to the mothership +// have button to replicate them + +function saveTestReport(report) { + var report = makeTestReport(); + if (report) { + var db = $.couch.db("test_suite_reports"); + var saveReport = function(db_info) { + report.db = db_info; + $.couch.info({success : function(node_info) { + report.node = node_info; + db.saveDoc(report); + }}); + }; + var createDb = function() { + db.create({success: function() { + db.info({success:saveReport}); + }}); + }; + db.info({error: createDb, success:saveReport}); + } +}; + +function makeTestReport() { + var report = {}; + report.summary = $("#tests tbody.footer td").text(); + report.platform = testPlatform(); + var date = new Date(); + report.timestamp = date.getTime(); + report.timezone = date.getTimezoneOffset(); + report.tests = []; + $("#tests tbody.content tr").each(function() { + var status = $("td.status", this).text(); + if (status != "not run") { + var test = {}; + test.name = this.id; + test.status = status; + test.duration = parseInt($("td.duration", this).text()); + test.details = []; + $("td.details li", this).each(function() { + test.details.push($(this).text()); + }); + if (test.details.length == 0) { + delete test.details; + } + report.tests.push(test); + } + }); + if (report.tests.length > 0) return report; +}; + +function testPlatform() { + var b = $.browser; + var bs = ["mozilla", "msie", "opera", "safari"]; + for (var i=0; i < bs.length; i++) { + if (b[bs[i]]) { + return {"browser" : bs[i], "version" : b.version}; + } + }; + return {"browser" : "undetected"}; +} + + +function reportTests() { + // replicate the database to couchdb.couchdb.org +} + +// Use T to perform a test that returns false on failure and if the test fails, +// display the line that failed. +// Example: +// T(MyValue==1); +function T(arg1, arg2, testName) { + if (!arg1) { + if (currentRow) { + if ($("td.details ol", currentRow).length == 0) { + $("
      ").appendTo($("td.details", currentRow)); + } + var message = (arg2 != null ? arg2 : arg1).toString(); + $("
    1. Assertion " + (testName ? "'" + testName + "'" : "") + " failed:
    2. ") + .find("code").text(message).end() + .appendTo($("td.details ol", currentRow)); + } + numFailures += 1; + } +} + +function TEquals(expected, actual, testName) { + T(equals(expected, actual), "expected '" + repr(expected) + + "', got '" + repr(actual) + "'", testName); +} + +function TEqualsIgnoreCase(expected, actual, testName) { + T(equals(expected.toUpperCase(), actual.toUpperCase()), "expected '" + repr(expected) + + "', got '" + repr(actual) + "'", testName); +} + +function equals(a,b) { + if (a === b) return true; + try { + return repr(a) === repr(b); + } catch (e) { + return false; + } +} + +function repr(val) { + if (val === undefined) { + return null; + } else if (val === null) { + return "null"; + } else { + return JSON.stringify(val); + } +} + +function makeDocs(start, end, templateDoc) { + var templateDocSrc = templateDoc ? JSON.stringify(templateDoc) : "{}"; + if (end === undefined) { + end = start; + start = 0; + } + var docs = []; + for (var i = start; i < end; i++) { + var newDoc = eval("(" + templateDocSrc + ")"); + newDoc._id = (i).toString(); + newDoc.integer = i; + newDoc.string = (i).toString(); + docs.push(newDoc); + } + return docs; +} + +function run_on_modified_server(settings, fun) { + try { + // set the settings + for(var i=0; i < settings.length; i++) { + var s = settings[i]; + var xhr = CouchDB.request("PUT", "/_config/" + s.section + "/" + s.key, { + body: JSON.stringify(s.value), + headers: {"X-Couch-Persist": "false"} + }); + CouchDB.maybeThrowError(xhr); + s.oldValue = xhr.responseText; + } + // run the thing + fun(); + } finally { + // unset the settings + for(var j=0; j < i; j++) { + var s = settings[j]; + if(s.oldValue == "\"\"\n") { // unset value + CouchDB.request("DELETE", "/_config/" + s.section + "/" + s.key, { + headers: {"X-Couch-Persist": "false"} + }); + } else { + CouchDB.request("PUT", "/_config/" + s.section + "/" + s.key, { + body: s.oldValue, + headers: {"X-Couch-Persist": "false"} + }); + } + } + } +} + +function stringFun(fun) { + var string = fun.toSource ? fun.toSource() : "(" + fun.toString() + ")"; + return string; +} + +function waitForSuccess(fun, tag) { + var start = new Date(); + while(true) { + if (new Date() - start > 5000) { + throw("timeout: "+tag); + } else { + try { + fun(); + break; + } catch (e) {} + // sync http req allow async req to happen + CouchDB.request("GET", "/test_suite_db/?tag="+encodeURIComponent(tag)); + } + } +} + +function waitForRestart() { + var waiting = true; + while (waiting) { + try { + CouchDB.request("GET", "/"); + CouchDB.request("GET", "/"); + waiting = false; + } catch(e) { + // the request will fail until restart completes + } + } +}; + +function restartServer() { + var xhr; + try { + CouchDB.request("POST", "/_restart"); + } catch(e) { + // this request may sometimes fail + } + waitForRestart(); +} + diff --git a/1.1.x/share/www/script/couch_tests.js b/1.1.x/share/www/script/couch_tests.js new file mode 100644 index 00000000..eb573526 --- /dev/null +++ b/1.1.x/share/www/script/couch_tests.js @@ -0,0 +1,105 @@ +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy of +// the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations under +// the License. + +// Used by replication test +if (typeof window == 'undefined' || !window) { + CouchDB.host = "127.0.0.1:5984"; + CouchDB.protocol = "http://"; + CouchDB.inBrowser = false; +} else { + CouchDB.host = window.location.host; + CouchDB.inBrowser = true; + CouchDB.protocol = window.location.protocol + "//"; +} + +CouchDB.urlPrefix = ".."; +var couchTests = {}; + +function loadTest(file) { + loadScript("script/test/"+file); +}; +// keep first +loadTest("basics.js"); + +// keep sorted +loadTest("all_docs.js"); +loadTest("attachments.js"); +loadTest("attachments_multipart.js"); +loadTest("attachment_conflicts.js"); +loadTest("attachment_names.js"); +loadTest("attachment_paths.js"); +loadTest("attachment_ranges.js"); +loadTest("attachment_views.js"); +loadTest("auth_cache.js"); +loadTest("batch_save.js"); +loadTest("bulk_docs.js"); +loadTest("changes.js"); +loadTest("compact.js"); +loadTest("config.js"); +loadTest("conflicts.js"); +loadTest("content_negotiation.js"); +loadTest("cookie_auth.js"); +loadTest("copy_doc.js"); +loadTest("delayed_commits.js"); +loadTest("design_docs.js"); +loadTest("design_options.js"); +loadTest("design_paths.js"); +loadTest("erlang_views.js"); +loadTest("etags_head.js"); +loadTest("etags_views.js"); +loadTest("form_submit.js"); +loadTest("http.js"); +loadTest("invalid_docids.js"); +loadTest("jsonp.js"); +loadTest("large_docs.js"); +loadTest("list_views.js"); +loadTest("lots_of_docs.js"); +loadTest("method_override.js"); +loadTest("multiple_rows.js"); +loadScript("script/oauth.js"); +loadScript("script/sha1.js"); +loadTest("oauth.js"); +loadTest("proxyauth.js"); +loadTest("purge.js"); +loadTest("reader_acl.js"); +loadTest("recreate_doc.js"); +loadTest("reduce.js"); +loadTest("reduce_builtin.js"); +loadTest("reduce_false.js"); +loadTest("reduce_false_temp.js"); +loadTest("replication.js"); +loadTest("replicator_db.js"); +loadTest("rev_stemming.js"); +loadTest("rewrite.js"); +loadTest("security_validation.js"); +loadTest("show_documents.js"); +loadTest("stats.js"); +loadTest("update_documents.js"); +loadTest("users_db.js"); +loadTest("utf8.js"); +loadTest("uuids.js"); +loadTest("view_collation.js"); +loadTest("view_collation_raw.js"); +loadTest("view_conflicts.js"); +loadTest("view_compaction.js"); +loadTest("view_errors.js"); +loadTest("view_include_docs.js"); +loadTest("view_multi_key_all_docs.js"); +loadTest("view_multi_key_design.js"); +loadTest("view_multi_key_temp.js"); +loadTest("view_offsets.js"); +loadTest("view_pagination.js"); +loadTest("view_sandboxing.js"); +loadTest("view_update_seq.js"); +loadTest("view_xml.js"); +// keep sorted + diff --git a/1.1.x/share/www/script/futon.browse.js b/1.1.x/share/www/script/futon.browse.js new file mode 100644 index 00000000..56435ae4 --- /dev/null +++ b/1.1.x/share/www/script/futon.browse.js @@ -0,0 +1,1290 @@ +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy of +// the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations under +// the License. + +(function($) { + $.futon = $.futon || {}; + $.extend($.futon, { + + // Page class for browse/index.html + CouchIndexPage: function() { + page = this; + + $.futon.storage.declare("per_page", {defaultValue: 10}); + + this.addDatabase = function() { + $.showDialog("dialog/_create_database.html", { + submit: function(data, callback) { + if (!data.name || data.name.length == 0) { + callback({name: "Please enter a name."}); + return; + } + $.couch.db(data.name).create({ + error: function(status, id, reason) { callback({name: reason}) }, + success: function(resp) { + location.href = "database.html?" + encodeURIComponent(data.name); + callback(); + } + }); + } + }); + return false; + } + + this.updateDatabaseListing = function(offset) { + offset |= 0; + var maxPerPage = parseInt($("#perpage").val(), 10); + + $.couch.allDbs({ + success: function(dbs) { + $("#paging a").unbind(); + $("#databases tbody.content").empty(); + + var dbsOnPage = dbs.slice(offset, offset + maxPerPage); + + $.each(dbsOnPage, function(idx, dbName) { + $("#databases tbody.content").append("" + + "" + + dbName + "" + + "" + + ""); + $.couch.db(dbName).info({ + success: function(info) { + $("#databases tbody.content tr:eq(" + idx + ")") + .find("td.size").text($.futon.formatSize(info.disk_size)).end() + .find("td.count").text(info.doc_count).end() + .find("td.seq").text(info.update_seq); + }, + error : function() {} + }); + }); + $("#databases tbody tr:odd").addClass("odd"); + + if (offset > 0) { + $("#paging a.prev").attr("href", "#" + (offset - maxPerPage)).click(function() { + page.updateDatabaseListing(offset - maxPerPage); + }); + } else { + $("#paging a.prev").removeAttr("href"); + } + if (offset + maxPerPage < dbs.length) { + $("#paging a.next").attr("href", "#" + (offset + maxPerPage)).click(function() { + page.updateDatabaseListing(offset + maxPerPage); + }); + } else { + $("#paging a.next").removeAttr("href"); + } + + var firstNum = offset + 1; + var lastNum = firstNum + dbsOnPage.length - 1; + $("#databases tbody.footer tr td span").text( + "Showing " + firstNum + "-" + lastNum + " of " + dbs.length + + " databases"); + } + }); + } + + }, + + // Page class for browse/database.html + CouchDatabasePage: function() { + var urlParts = location.search.substr(1).split("/"); + var dbName = decodeURIComponent(urlParts.shift()) + + var dbNameRegExp = new RegExp("[^a-z0-9\_\$\(\)\+\/\-]", "g"); + dbName = dbName.replace(dbNameRegExp, ""); + + $.futon.storage.declareWithPrefix(dbName + ".", { + desc: {}, + language: {defaultValue: "javascript"}, + map_fun: {defaultValue: ""}, + reduce_fun: {defaultValue: ""}, + reduce: {}, + group_level: {defaultValue: 100}, + per_page: {defaultValue: 10}, + view: {defaultValue: ""}, + stale: {defaultValue: false} + }); + + var viewName = (urlParts.length > 0) ? urlParts.join("/") : null; + if (viewName) { + $.futon.storage.set("view", decodeURIComponent(viewName)); + } else { + viewName = $.futon.storage.get("view"); + if (viewName) { + this.redirecting = true; + location.href = "database.html?" + encodeURIComponent(dbName) + + "/" + encodeURIComponent(viewName); + } + } + var db = $.couch.db(dbName); + + this.dbName = dbName; + viewName = decodeURIComponent(viewName); + this.viewName = viewName; + this.viewLanguage = "javascript"; + this.db = db; + this.isDirty = false; + this.isTempView = viewName == "_temp_view"; + page = this; + + var templates = { + javascript: "function(doc) {\n emit(null, doc);\n}", + python: "def fun(doc):\n yield None, doc", + ruby: "lambda {|doc|\n emit(nil, doc);\n}" + } + + this.newDocument = function() { + location.href = "document.html?" + encodeURIComponent(db.name); + } + + this.compactAndCleanup = function() { + $.showDialog("dialog/_compact_cleanup.html", { + submit: function(data, callback) { + switch (data.action) { + case "compact_database": + db.compact({success: function(resp) { callback() }}); + break; + case "compact_views": + var idx = page.viewName.indexOf("/_view"); + if (idx == -1) { + alert("Compact Views requires focus on a view!"); + } else { + var groupname = page.viewName.substring(8, idx); + db.compactView(groupname, {success: function(resp) { callback() }}); + } + break; + case "view_cleanup": + db.viewCleanup({success: function(resp) { callback() }}); + break; + } + } + }); + } + + this.deleteDatabase = function() { + $.showDialog("dialog/_delete_database.html", { + submit: function(data, callback) { + db.drop({ + success: function(resp) { + callback(); + location.href = "index.html"; + if (window !== null) { + $("#dbs li").filter(function(index) { + return $("a", this).text() == dbName; + }).remove(); + $.futon.navigation.removeDatabase(dbName); + } + } + }); + } + }); + } + + this.databaseSecurity = function() { + $.showDialog("dialog/_database_security.html", { + load : function(d) { + db.getDbProperty("_security", { + success: function(r) { + ["admin", "reader"].forEach(function(key) { + var names = []; + var roles = []; + + if (r && typeof r[key + "s"] === "object") { + if ($.isArray(r[key + "s"]["names"])) { + names = r[key + "s"]["names"]; + } + if ($.isArray(r[key + "s"]["roles"])) { + roles = r[key + "s"]["roles"]; + } + } + + $("input[name=" + key + "_names]", d).val(JSON.stringify(names)); + $("input[name=" + key + "_roles]", d).val(JSON.stringify(roles)); + }); + } + }); + }, + // maybe this should be 2 forms + submit: function(data, callback) { + var errors = {}; + var secObj = { + admins: { + names: [], + roles: [] + }, + readers: { + names: [], + roles: [] + } + }; + + ["admin", "reader"].forEach(function(key) { + var names, roles; + + try { + names = JSON.parse(data[key + "_names"]); + } catch(e) { } + try { + roles = JSON.parse(data[key + "_roles"]); + } catch(e) { } + + if ($.isArray(names)) { + secObj[key + "s"]["names"] = names; + } else { + errors[key + "_names"] = "The " + key + + " names must be an array of strings"; + } + if ($.isArray(roles)) { + secObj[key + "s"]["roles"] = roles; + } else { + errors[key + "_roles"] = "The " + key + + " roles must be an array of strings"; + } + }); + + if ($.isEmptyObject(errors)) { + db.setDbProperty("_security", secObj); + } + callback(errors); + } + }); + } + + this.populateViewEditor = function() { + if (viewName.match(/^_design\//)) { + page.revertViewChanges(function() { + var dirtyTimeout = null; + function updateDirtyState() { + clearTimeout(dirtyTimeout); + dirtyTimeout = setTimeout(function() { + var buttons = $("#viewcode button.save, #viewcode button.revert"); + var viewCode = { + map: $("#viewcode_map").val(), + reduce: $("#viewcode_reduce").val() + }; + $("#reduce, #grouplevel").toggle(!!viewCode.reduce); + page.isDirty = (viewCode.map != page.storedViewCode.map) + || (viewCode.reduce != (page.storedViewCode.reduce || "")) + || page.viewLanguage != page.storedViewLanguage; + if (page.isDirty) { + buttons.removeAttr("disabled"); + } else { + buttons.attr("disabled", "disabled"); + } + }, 100); + } + $("#viewcode textarea").enableTabInsertion() + .bind("input", updateDirtyState); + if ($.browser.msie || $.browser.safari) { + $("#viewcode textarea").bind("paste", updateDirtyState) + .bind("change", updateDirtyState) + .bind("keydown", updateDirtyState) + .bind("keypress", updateDirtyState) + .bind("keyup", updateDirtyState) + .bind("textInput", updateDirtyState); + } + $("#language").change(updateDirtyState); + page.updateDocumentListing(); + }); + } else if (viewName == "_temp_view") { + $("#viewcode textarea").enableTabInsertion(); + page.viewLanguage = $.futon.storage.get("language"); + page.updateViewEditor( + $.futon.storage.get("map_fun", templates[page.viewLanguage]), + $.futon.storage.get("reduce_fun") + ); + } else { + $("#grouplevel, #reduce").hide(); + page.updateDocumentListing(); + } + page.populateLanguagesMenu(); + if (this.isTempView) { + $("#tempwarn").show(); + } + } + + // Populate the languages dropdown, and listen to selection changes + this.populateLanguagesMenu = function() { + var all_langs = {}; + fill_language = function() { + var select = $("#language"); + for (var language in all_langs) { + var option = $(document.createElement("option")) + .attr("value", language).text(language) + .appendTo(select); + } + if (select[0].options.length == 1) { + select[0].disabled = true; + } else { + select[0].disabled = false; + select.val(page.viewLanguage); + select.change(function() { + var language = $("#language").val(); + if (language != page.viewLanguage) { + var mapFun = $("#viewcode_map").val(); + if (mapFun == "" || mapFun == templates[page.viewLanguage]) { + // no edits made, so change to the new default + $("#viewcode_map").val(templates[language]); + } + page.viewLanguage = language; + $("#viewcode_map")[0].focus(); + } + return false; + }); + } + } + $.couch.config({ + success: function(resp) { + for (var language in resp) { + all_langs[language] = resp[language]; + } + + $.couch.config({ + success: function(resp) { + for (var language in resp) { + all_langs[language] = resp[language]; + } + fill_language(); + } + }, "native_query_servers"); + }, + error : function() {} + }, "query_servers"); + } + + this.populateViewsMenu = function() { + var select = $("#switch select"); + db.allDocs({startkey: "_design/", endkey: "_design0", + include_docs: true, + success: function(resp) { + select[0].options.length = 3; + for (var i = 0; i < resp.rows.length; i++) { + var doc = resp.rows[i].doc; + var optGroup = $(document.createElement("optgroup")) + .attr("label", doc._id.substr(8)).appendTo(select); + var viewNames = []; + for (var name in doc.views) { + viewNames.push(name); + } + viewNames.sort(); + for (var j = 0; j < viewNames.length; j++) { + var path = $.couch.encodeDocId(doc._id) + "/_view/" + + encodeURIComponent(viewNames[j]); + var option = $(document.createElement("option")) + .attr("value", path).text(encodeURIComponent(viewNames[j])) + .appendTo(optGroup); + if (path == viewName) { + option[0].selected = true; + } + } + } + } + }); + if (!viewName.match(/^_design\//)) { + $.each(["_all_docs", "_design_docs", "_temp_view"], function(idx, name) { + if (viewName == name) { + select[0].options[idx].selected = true; + } + }); + } + } + + this.revertViewChanges = function(callback) { + if (!page.storedViewCode) { + var viewNameParts = viewName.split("/"); + var designDocId = decodeURIComponent(viewNameParts[1]); + var localViewName = decodeURIComponent(viewNameParts[3]); + db.openDoc("_design/" + designDocId, { + error: function(status, error, reason) { + if (status == 404) { + $.futon.storage.del("view"); + location.href = "database.html?" + encodeURIComponent(db.name); + } + }, + success: function(resp) { + if(!resp.views || !resp.views[localViewName]) { + $.futon.storage.del("view"); + location.href = "database.html?" + encodeURIComponent(db.name); + } + var viewCode = resp.views[localViewName]; + page.viewLanguage = resp.language || "javascript"; + $("#language").val(encodeURIComponent(page.viewLanguage)); + page.updateViewEditor(viewCode.map, viewCode.reduce || ""); + $("#viewcode button.revert, #viewcode button.save").attr("disabled", "disabled"); + page.storedViewCode = viewCode; + page.storedViewLanguage = page.viewLanguage; + if (callback) callback(); + } + }, {async: false}); + } else { + page.updateViewEditor(page.storedViewCode.map, + page.storedViewCode.reduce || ""); + page.viewLanguage = page.storedViewLanguage; + $("#language").val(encodeURIComponent(page.viewLanguage)); + $("#viewcode button.revert, #viewcode button.save").attr("disabled", "disabled"); + page.isDirty = false; + if (callback) callback(); + } + } + + this.updateViewEditor = function(mapFun, reduceFun) { + if (!mapFun) return; + $("#viewcode_map").val(mapFun); + $("#viewcode_reduce").val(reduceFun); + var lines = Math.max( + mapFun.split("\n").length, + reduceFun.split("\n").length + ); + $("#reduce, #grouplevel").toggle(!!reduceFun); + $("#viewcode textarea").attr("rows", Math.min(15, Math.max(3, lines))); + } + + this.saveViewAs = function() { + if (viewName && /^_design/.test(viewName)) { + var viewNameParts = viewName.split("/"); + var designDocId = decodeURIComponent(viewNameParts[1]); + var localViewName = decodeURIComponent(viewNameParts[3]); + } else { + var designDocId = "", localViewName = ""; + } + $.showDialog("dialog/_save_view_as.html", { + load: function(elem) { + $("#input_docid", elem).val(designDocId).suggest(function(text, callback) { + db.allDocs({ + limit: 10, startkey: "_design/" + text, endkey: "_design0", + success: function(docs) { + var matches = []; + for (var i = 0; i < docs.rows.length; i++) { + var docName = docs.rows[i].id.substr(8); + if (docName.indexOf(text) == 0) { + matches[i] = docName; + } + } + callback(matches); + } + }); + }); + $("#input_name", elem).val(localViewName).suggest(function(text, callback) { + db.openDoc("_design/" + $("#input_docid").val(), { + error: function() {}, // ignore + success: function(doc) { + var matches = []; + if (!doc.views) return; + for (var viewName in doc.views) { + if (viewName.indexOf(text) == 0) { + matches.push(viewName); + } + } + callback(matches); + } + }); + }); + }, + submit: function(data, callback) { + if (!data.docid || !data.name) { + var errors = {}; + if (!data.docid) errors.docid = "Please enter a document ID"; + if (!data.name) errors.name = "Please enter a view name"; + callback(errors); + } else { + var viewCode = { + map: $("#viewcode_map").val(), + reduce: $("#viewcode_reduce").val() || undefined + }; + var docId = ["_design", data.docid].join("/"); + function save(doc) { + if (!doc) { + doc = {_id: docId, language: page.viewLanguage}; + } else { + var numViews = 0; + for (var viewName in (doc.views || {})) { + if (viewName != data.name) numViews++; + } + if (numViews > 0 && page.viewLanguage != doc.language) { + callback({ + docid: "Cannot save to " + data.docid + + " because its language is \"" + doc.language + + "\", not \"" + + encodeURIComponent(page.viewLanguage) + "\"." + }); + return; + } + doc.language = page.viewLanguage; + } + if (doc.views === undefined) doc.views = {}; + doc.views[data.name] = viewCode; + db.saveDoc(doc, { + success: function(resp) { + callback(); + page.isDirty = false; + location.href = "database.html?" + encodeURIComponent(dbName) + + "/" + $.couch.encodeDocId(doc._id) + + "/_view/" + encodeURIComponent(data.name); + } + }); + } + db.openDoc(docId, { + error: function(status, error, reason) { + if (status == 404) save(null); + else alert(reason); + }, + success: function(doc) { + save(doc); + } + }); + } + } + }); + } + + this.saveViewChanges = function() { + var viewNameParts = viewName.split("/"); + var designDocId = decodeURIComponent(viewNameParts[1]); + var localViewName = decodeURIComponent(viewNameParts[3]); + db.openDoc("_design/" + designDocId, { + success: function(doc) { + var numViews = 0; + for (var viewName in (doc.views || {})) { + if (viewName != localViewName) numViews++; + } + if (numViews > 0 && page.viewLanguage != doc.language) { + alert("Cannot save view because the design document language " + + "is \"" + doc.language + "\", not \"" + + page.viewLanguage + "\"."); + return; + } + doc.language = page.viewLanguage; + var viewDef = doc.views[localViewName]; + viewDef.map = $("#viewcode_map").val(); + viewDef.reduce = $("#viewcode_reduce").val() || undefined; + db.saveDoc(doc, { + success: function(resp) { + page.isDirty = false; + $("#viewcode button.revert, #viewcode button.save") + .attr("disabled", "disabled"); + } + }); + } + }); + } + + this.updateDesignDocLink = function() { + if (viewName && /^_design/.test(viewName)) { + var docId = "_design/" + encodeURIComponent(decodeURIComponent(viewName).split("/")[1]); + $("#designdoc-link").attr("href", "document.html?" + + encodeURIComponent(dbName) + "/" + $.couch.encodeDocId(docId)).text(docId); + } else { + $("#designdoc-link").removeAttr("href").text(""); + } + } + + this.jumpToDocument = function(docId) { + if (docId != "") { + location.href = 'document.html?' + encodeURIComponent(db.name) + + "/" + $.couch.encodeDocId(docId); + } + } + + this.updateDocumentListing = function(options) { + if (options === undefined) options = {}; + if (options.limit === undefined) { + var perPage = parseInt($("#perpage").val(), 10) + // Fetch an extra row so we know when we're on the last page for + // reduce views + options.limit = perPage + 1; + } else { + perPage = options.limit - 1; + } + if ($("#documents thead th.key").is(".desc")) { + if (typeof options.descending == 'undefined') options.descending = true; + var descend = true; + $.futon.storage.set("desc", "1"); + } else { + var descend = false; + $.futon.storage.del("desc"); + } + $("#paging a").unbind(); + $("#documents").find("tbody.content").empty().end().show(); + page.updateDesignDocLink(); + + options.success = function(resp) { + if (resp.offset === undefined) { + resp.offset = 0; + } + var descending_reverse = ((options.descending && !descend) || (descend && (options.descending === false))); + var has_reduce_prev = resp.total_rows === undefined && (descending_reverse ? resp.rows.length > perPage : options.startkey !== undefined); + if (descending_reverse && resp.rows) { + resp.rows = resp.rows.reverse(); + if (resp.rows.length > perPage) { + resp.rows.push(resp.rows.shift()); + } + } + if (resp.rows !== null && (has_reduce_prev || (descending_reverse ? + (resp.total_rows - resp.offset > perPage) : + (resp.offset > 0)))) { + $("#paging a.prev").attr("href", "#" + (resp.offset - perPage)).click(function() { + var opt = { + descending: !descend, + limit: options.limit + }; + if (resp.rows.length > 0) { + var firstDoc = resp.rows[0]; + opt.startkey = firstDoc.key !== undefined ? firstDoc.key : null; + if (firstDoc.id !== undefined) { + opt.startkey_docid = firstDoc.id; + } + opt.skip = 1; + } + page.updateDocumentListing(opt); + return false; + }); + } else { + $("#paging a.prev").removeAttr("href"); + } + var has_reduce_next = resp.total_rows === undefined && (descending_reverse ? options.startkey !== undefined : resp.rows.length > perPage); + if (resp.rows !== null && (has_reduce_next || (descending_reverse ? + (resp.offset - resp.total_rows < perPage) : + (resp.total_rows - resp.offset > perPage)))) { + $("#paging a.next").attr("href", "#" + (resp.offset + perPage)).click(function() { + var opt = { + descending: descend, + limit: options.limit + }; + if (resp.rows.length > 0) { + var lastDoc = resp.rows[Math.min(perPage, resp.rows.length) - 1]; + opt.startkey = lastDoc.key !== undefined ? lastDoc.key : null; + if (lastDoc.id !== undefined) { + opt.startkey_docid = lastDoc.id; + } + opt.skip = 1; + } + page.updateDocumentListing(opt); + return false; + }); + } else { + $("#paging a.next").removeAttr("href"); + } + + for (var i = 0; i < Math.min(perPage, resp.rows.length); i++) { + var row = resp.rows[i]; + var tr = $(""); + var key = "null"; + if (row.key !== null) { + key = $.futon.formatJSON(row.key, {indent: 0, linesep: ""}); + } + if (row.id) { + key = key.replace(/\\"/, '"'); + var rowlink = encodeURIComponent(db.name) + + "/" + $.couch.encodeDocId(row.id); + $("" + + $.futon.escape(key) + "
      " + + "ID: " + $.futon.escape(row.id) + "
      ") + .appendTo(tr); + } else { + $("") + .find("strong").text(key).end() + .appendTo(tr); + } + var value = "null"; + if (row.value !== null) { + value = $.futon.formatJSON(row.value, { + html: true, indent: 0, linesep: "", quoteKeys: false + }); + } + $("
      ").find("div").html(value).end() + .appendTo(tr).dblclick(function() { + location.href = this.previousSibling.firstChild.href; + }); + tr.appendTo("#documents tbody.content"); + } + var firstNum = 1; + var lastNum = totalNum = Math.min(perPage, resp.rows.length); + if (resp.total_rows != null) { + if (descending_reverse) { + lastNum = Math.min(resp.total_rows, resp.total_rows - resp.offset); + firstNum = lastNum - totalNum + 1; + } else { + firstNum = Math.min(resp.total_rows, resp.offset + 1); + lastNum = firstNum + totalNum - 1; + } + totalNum = resp.total_rows; + } else { + totalNum = "unknown"; + } + $("#paging").show(); + + $("#documents tbody.footer td span").text( + "Showing " + firstNum + "-" + lastNum + " of " + totalNum + + " row" + (firstNum != lastNum || totalNum == "unknown" ? "s" : "")); + $("#documents tbody tr:odd").addClass("odd"); + } + options.error = function(status, error, reason) { + alert("Error: " + error + "\n\n" + reason); + } + + if (!viewName || viewName == "_all_docs") { + $("#switch select")[0].selectedIndex = 0; + db.allDocs(options); + } else { + if (viewName == "_temp_view") { + $("#viewcode").show().removeClass("collapsed"); + var mapFun = $("#viewcode_map").val(); + $.futon.storage.set("map_fun", mapFun); + var reduceFun = $.trim($("#viewcode_reduce").val()) || null; + if (reduceFun) { + $.futon.storage.set("reduce_fun", reduceFun); + if ($("#reduce :checked").length) { + var level = parseInt($("#grouplevel select").val(), 10); + options.group = level > 0; + if (options.group && level < 100) { + options.group_level = level; + } + } else { + options.reduce = false; + } + } + $.futon.storage.set("language", page.viewLanguage); + db.query(mapFun, reduceFun, page.viewLanguage, options); + } else if (viewName == "_design_docs") { + options.startkey = options.descending ? "_design0" : "_design"; + options.endkey = options.descending ? "_design" : "_design0"; + db.allDocs(options); + } else { + $("button.compactview").show(); + $("#viewcode").show(); + var currentMapCode = $("#viewcode_map").val(); + var currentReduceCode = $.trim($("#viewcode_reduce").val()) || null; + if (currentReduceCode) { + if ($("#reduce :checked").length) { + var level = parseInt($("#grouplevel select").val(), 10); + options.group = level > 0; + if (options.group && level < 100) { + options.group_level = level; + } + } else { + options.reduce = false; + } + } + if (page.isDirty) { + db.query(currentMapCode, currentReduceCode, page.viewLanguage, options); + } else { + var viewParts = decodeURIComponent(viewName).split('/'); + if ($.futon.storage.get("stale")) { + options.stale = "ok"; + } + + db.view(viewParts[1] + "/" + viewParts[3], options); + } + } + } + } + + window.onbeforeunload = function() { + $("#switch select").val(viewName); + if (page.isDirty) { + return "You've made changes to the view code that have not been " + + "saved yet."; + } + } + + }, + + // Page class for browse/document.html + CouchDocumentPage: function() { + var urlParts = location.search.substr(1).split("/"); + var dbName = decodeURIComponent(urlParts.shift()); + if (urlParts.length) { + var idParts = urlParts.join("/").split("@", 2); + var docId = decodeURIComponent(idParts[0]); + var docRev = (idParts.length > 1) ? idParts[1] : null; + this.isNew = false; + } else { + var docId = $.couch.newUUID(); + var docRev = null; + this.isNew = true; + } + var db = $.couch.db(dbName); + + $.futon.storage.declare("tab", {defaultValue: "tabular", scope: "cookie"}); + + this.dbName = dbName; + this.db = db; + this.docId = docId; + this.doc = null; + this.isDirty = this.isNew; + page = this; + + this.activateTabularView = function() { + if ($("#fields tbody.source textarea").length > 0) + return; + + $.futon.storage.set("tab", "tabular"); + $("#tabs li").removeClass("active").filter(".tabular").addClass("active"); + $("#fields thead th:first").text("Field").attr("colspan", 1).next().show(); + $("#fields tbody.content").show(); + $("#fields tbody.source").hide(); + return false; + } + + this.activateSourceView = function() { + $.futon.storage.set("tab", "source"); + $("#tabs li").removeClass("active").filter(".source").addClass("active"); + $("#fields thead th:first").text("Source").attr("colspan", 2).next().hide(); + $("#fields tbody.content").hide(); + $("#fields tbody.source").find("td").each(function() { + $(this).html($("
      ").html($.futon.formatJSON(page.doc, {html: true})))
      +            .makeEditable({allowEmpty: false,
      +              createInput: function(value) {
      +                var rows = value.split("\n").length;
      +                return $("").enableTabInsertion();
      +              },
      +              prepareInput: function(input) {
      +                $(input).makeResizable({vertical: true});
      +              },
      +              end: function() {
      +                $(this).html($("
      ").html($.futon.formatJSON(page.doc, {html: true})));
      +              },
      +              accept: function(newValue) {
      +                page.doc = JSON.parse(newValue);
      +                page.isDirty = true;
      +                page.updateFieldListing(true);
      +              },
      +              populate: function(value) {
      +                return $.futon.formatJSON(page.doc);
      +              },
      +              validate: function(value) {
      +                try {
      +                  var doc = JSON.parse(value);
      +                  if (typeof doc != "object")
      +                    throw new SyntaxError("Please enter a valid JSON document (for example, {}).");
      +                  return true;
      +                } catch (err) {
      +                  var msg = err.message;
      +                  if (msg == "parseJSON" || msg == "JSON.parse") {
      +                    msg = "There is a syntax error in the document.";
      +                  }
      +                  $("
      ").text(msg).appendTo(this); + return false; + } + } + }); + }).end().show(); + return false; + } + + this.addField = function() { + if (!$("#fields tbody.content:visible").length) { + location.hash = "#tabular"; + page.activateTabularView(); + } + var fieldName = "unnamed"; + var fieldIdx = 1; + while (page.doc.hasOwnProperty(fieldName)) { + fieldName = "unnamed " + fieldIdx++; + } + page.doc[fieldName] = null; + var row = _addRowForField(page.doc, fieldName); + page.isDirty = true; + row.find("th b").dblclick(); + } + + var _sortFields = function(a, b) { + var a0 = a.charAt(0), b0 = b.charAt(0); + if (a0 == "_" && b0 != "_") { + return -1; + } else if (a0 != "_" && b0 == "_") { + return 1; + } else if (a == "_attachments" || b == "_attachments") { + return a0 == "_attachments" ? 1 : -1; + } else { + return a < b ? -1 : a != b ? 1 : 0; + } + } + + this.updateFieldListing = function(noReload) { + $("#fields tbody.content").empty(); + + function handleResult(doc, revs) { + page.doc = doc; + var propNames = []; + for (var prop in doc) { + propNames.push(prop); + } + // Order properties alphabetically, but put internal fields first + propNames.sort(_sortFields); + for (var pi = 0; pi < propNames.length; pi++) { + _addRowForField(doc, propNames[pi]); + } + if (revs.length > 1) { + var currentIndex = 0; + for (var i = 0; i < revs.length; i++) { + if (revs[i].rev == doc._rev) { + currentIndex = i; + break; + } + } + if (currentIndex < revs.length - 1) { + var prevRev = revs[currentIndex + 1].rev; + $("#paging a.prev").attr("href", "?" + encodeURIComponent(dbName) + + "/" + $.couch.encodeDocId(docId) + "@" + prevRev); + } + if (currentIndex > 0) { + var nextRev = revs[currentIndex - 1].rev; + $("#paging a.next").attr("href", "?" + encodeURIComponent(dbName) + + "/" + $.couch.encodeDocId(docId) + "@" + nextRev); + } + $("#fields tbody.footer td span").text("Showing revision " + + (revs.length - currentIndex) + " of " + revs.length); + } + if ($.futon.storage.get("tab") == "source") { + page.activateSourceView(); + } + } + + if (noReload) { + handleResult(page.doc, []); + return; + } + + if (!page.isNew) { + db.openDoc(docId, {revs_info: true, + success: function(doc) { + var revs = doc._revs_info || []; + delete doc._revs_info; + if (docRev != null) { + db.openDoc(docId, {rev: docRev, + error: function(status, error, reason) { + alert("The requested revision was not found. You will " + + "be redirected back to the latest revision."); + location.href = "?" + encodeURIComponent(dbName) + + "/" + $.couch.encodeDocId(docId); + }, + success: function(doc) { + handleResult(doc, revs); + } + }); + } else { + handleResult(doc, revs); + } + } + }); + } else { + handleResult({_id: docId}, []); + $("#fields tbody td").dblclick(); + } + } + + this.deleteDocument = function() { + $.showDialog("dialog/_delete_document.html", { + submit: function(data, callback) { + db.removeDoc(page.doc, { + success: function(resp) { + callback(); + location.href = "database.html?" + encodeURIComponent(dbName); + } + }); + } + }); + } + + this.saveDocument = function() { + db.saveDoc(page.doc, { + error: function(status, error, reason) { + alert("Error: " + error + "\n\n" + reason); + }, + success: function(resp) { + page.isDirty = false; + location.href = "?" + encodeURIComponent(dbName) + + "/" + $.couch.encodeDocId(page.docId); + } + }); + } + + this.uploadAttachment = function() { + if (page.isDirty) { + alert("You need to save or revert any changes you have made to the " + + "document before you can attach a new file."); + return false; + } + $.showDialog("dialog/_upload_attachment.html", { + load: function(elem) { + $("input[name='_rev']", elem).val(page.doc._rev); + }, + submit: function(data, callback) { + if (!data._attachments || data._attachments.length == 0) { + callback({_attachments: "Please select a file to upload."}); + return; + } + var form = $("#upload-form"); + form.find("#progress").css("visibility", "visible"); + form.ajaxSubmit({ + url: db.uri + $.couch.encodeDocId(page.docId), + success: function(resp) { + form.find("#progress").css("visibility", "hidden"); + page.isDirty = false; + location.href = "?" + encodeURIComponent(dbName) + + "/" + $.couch.encodeDocId(page.docId); + } + }); + } + }); + } + + window.onbeforeunload = function() { + if (page.isDirty) { + return "You've made changes to this document that have not been " + + "saved yet."; + } + } + + function _addRowForField(doc, fieldName) { + var row = $("") + .find("th").append($("").text(fieldName)).end() + .appendTo("#fields tbody.content"); + if (fieldName == "_attachments") { + row.find("td").append(_renderAttachmentList(doc[fieldName])); + } else { + row.find("td").append(_renderValue(doc[fieldName])); + _initKey(doc, row, fieldName); + _initValue(doc, row, fieldName); + } + $("#fields tbody.content tr").removeClass("odd").filter(":odd").addClass("odd"); + row.data("name", fieldName); + return row; + } + + function _initKey(doc, row, fieldName) { + if (fieldName == "_id" || fieldName == "_rev") { + return; + } + + var cell = row.find("th"); + + $("").click(function() { + delete doc[fieldName]; + row.remove(); + page.isDirty = true; + $("#fields tbody.content tr").removeClass("odd").filter(":odd").addClass("odd"); + }).prependTo(cell); + + cell.find("b").makeEditable({allowEmpty: false, + accept: function(newName, oldName) { + doc[newName] = doc[oldName]; + delete doc[oldName]; + row.data("name", newName); + $(this).text(newName); + page.isDirty = true; + }, + begin: function() { + row.find("th button.delete").hide(); + return true; + }, + end: function(keyCode) { + row.find("th button.delete").show(); + if (keyCode == 9) { // tab, move to editing the value + row.find("td").dblclick(); + } + }, + validate: function(newName, oldName) { + $("div.error", this).remove(); + if (newName != oldName && doc[newName] !== undefined) { + $("
      Already have field with that name.
      ") + .appendTo(this); + return false; + } + return true; + } + }); + } + + function _initValue(doc, row, fieldName) { + if ((fieldName == "_id" && !page.isNew) || fieldName == "_rev") { + return; + } + + row.find("td").makeEditable({acceptOnBlur: false, allowEmpty: true, + createInput: function(value) { + value = doc[row.data("name")]; + var elem = $(this); + if (elem.find("dl").length > 0 || + elem.find("code").is(".array, .object") || + typeof(value) == "string" && (value.length > 60 || value.match(/\n/))) { + return $(""); + } + return $(""); + }, + end: function() { + $(this).children().remove(); + $(this).append(_renderValue(doc[row.data("name")])); + }, + prepareInput: function(input) { + if ($(input).is("textarea")) { + var height = Math.min(input.scrollHeight, document.body.clientHeight - 100); + $(input).height(height).makeResizable({vertical: true}).enableTabInsertion(); + } + }, + accept: function(newValue) { + var fieldName = row.data("name"); + try { + doc[fieldName] = JSON.parse(newValue); + } catch (err) { + doc[fieldName] = newValue; + } + page.isDirty = true; + if (fieldName == "_id") { + page.docId = page.doc._id = doc[fieldName]; + $("h1 strong").text(page.docId); + } + }, + populate: function(value) { + value = doc[row.data("name")]; + if (typeof(value) == "string") { + return value; + } + return $.futon.formatJSON(value); + }, + validate: function(value) { + $("div.error", this).remove(); + try { + var parsed = JSON.parse(value); + if (row.data("name") == "_id" && typeof(parsed) != "string") { + $("
      The document ID must be a string.
      ") + .appendTo(this); + return false; + } + return true; + } catch (err) { + return true; + } + } + }); + } + + function _renderValue(value) { + function isNullOrEmpty(val) { + if (val == null) return true; + for (var i in val) return false; + return true; + } + function render(val) { + var type = typeof(val); + if (type == "object" && !isNullOrEmpty(val)) { + var list = $("
      "); + for (var i in val) { + $("
      ").text(i).appendTo(list); + $("
      ").append(render(val[i])).appendTo(list); + } + return list; + } else { + var html = $.futon.formatJSON(val, { + html: true, + escapeStrings: false + }); + var n = $(html); + if (n.text().length > 140) { + // This code reduces a long string in to a summarized string with a link to expand it. + // Someone, somewhere, is doing something nasty with the event after it leaves these handlers. + // At this time I can't track down the offender, it might actually be a jQuery propogation issue. + var fulltext = n.text(); + var mintext = n.text().slice(0, 140); + var e = $('...'); + var m = $('X'); + var expand = function (evt) { + n.empty(); + n.text(fulltext); + n.append(m); + evt.stopPropagation(); + evt.stopImmediatePropagation(); + evt.preventDefault(); + } + var minimize = function (evt) { + n.empty(); + n.text(mintext); + // For some reason the old element's handler won't fire after removed and added again. + e = $('...'); + e.click(expand); + n.append(e); + evt.stopPropagation(); + evt.stopImmediatePropagation(); + evt.preventDefault(); + } + e.click(expand); + n.click(minimize); + n.text(mintext); + n.append(e) + } + return n; + } + } + var elem = render(value); + + elem.find("dd:has(dl)").hide().prev("dt").addClass("collapsed"); + elem.find("dd:not(:has(dl))").addClass("inline").prev().addClass("inline"); + elem.find("dt.collapsed").click(function() { + $(this).toggleClass("collapsed").next().toggle(); + }); + + return elem; + } + + function _renderAttachmentList(attachments) { + var ul = $("
        ").addClass("attachments"); + $.each(attachments, function(idx, attachment) { + _renderAttachmentItem(idx, attachment).appendTo(ul); + }); + return ul; + } + + function _renderAttachmentItem(name, attachment) { + var attachmentHref = db.uri + $.couch.encodeDocId(page.docId) + + "/" + encodeAttachment(name); + var li = $("
      • "); + $("").text(name) + .attr("href", attachmentHref) + .wrapInner("").appendTo(li); + $("()").text("" + $.futon.formatSize(attachment.length) + + ", " + attachment.content_type).addClass("info").appendTo(li); + if (name == "tests.js") { + li.find('span.info').append(', open in test runner'); + } + _initAttachmentItem(name, attachment, li); + return li; + } + + function _initAttachmentItem(name, attachment, li) { + $("").click(function() { + if (!li.siblings("li").length) { + delete page.doc._attachments; + li.parents("tr").remove(); + $("#fields tbody.content tr").removeClass("odd").filter(":odd").addClass("odd"); + } else { + delete page.doc._attachments[name]; + li.remove(); + } + page.isDirty = true; + return false; + }).prependTo($("a", li)); + } + }, + + }); + + function encodeAttachment(name) { + var encoded = [], parts = name.split('/'); + for (var i=0; i < parts.length; i++) { + encoded.push(encodeURIComponent(parts[i])); + }; + return encoded.join('%2f'); + } + +})(jQuery); diff --git a/1.1.x/share/www/script/futon.format.js b/1.1.x/share/www/script/futon.format.js new file mode 100644 index 00000000..0eb9b104 --- /dev/null +++ b/1.1.x/share/www/script/futon.format.js @@ -0,0 +1,146 @@ +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy of +// the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations under +// the License. + +(function($) { + $.futon = $.futon || {}; + $.extend($.futon, { + escape: function(string) { + return string.replace(/&/g, "&") + .replace(//g, ">") + .replace(/"/g, """) + .replace(/'/g, "'") + ; + }, + + // JSON pretty printing + formatJSON: function(val, options) { + options = $.extend({ + escapeStrings: true, + indent: 4, + linesep: "\n", + quoteKeys: true + }, options || {}); + var itemsep = options.linesep.length ? "," + options.linesep : ", "; + + function format(val, depth) { + var tab = []; + for (var i = 0; i < options.indent * depth; i++) tab.push(""); + tab = tab.join(" "); + + var type = typeof val; + switch (type) { + case "boolean": + case "number": + case "string": + var retval = val; + if (type == "string" && !options.escapeStrings) { + retval = indentLines(retval.replace(/\r\n/g, "\n"), tab.substr(options.indent)); + } else { + if (options.html) { + retval = $.futon.escape(JSON.stringify(val)); + } else { + retval = JSON.stringify(val); + } + } + if (options.html) { + retval = "" + retval + ""; + } + return retval; + + case "object": { + if (val === null) { + if (options.html) { + return "null"; + } + return "null"; + } + if (val.constructor == Date) { + return JSON.stringify(val); + } + + var buf = []; + + if (val.constructor == Array) { + buf.push("["); + for (var index = 0; index < val.length; index++) { + buf.push(index > 0 ? itemsep : options.linesep); + buf.push(tab, format(val[index], depth + 1)); + } + if (index >= 0) { + buf.push(options.linesep, tab.substr(options.indent)); + } + buf.push("]"); + if (options.html) { + return "" + buf.join("") + ""; + } + + } else { + buf.push("{"); + var index = 0; + for (var key in val) { + buf.push(index > 0 ? itemsep : options.linesep); + var keyDisplay = options.quoteKeys ? JSON.stringify(key) : key; + if (options.html) { + if (options.quoteKeys) { + keyDisplay = keyDisplay.substr(1, keyDisplay.length - 2); + } + keyDisplay = "" + $.futon.escape(keyDisplay) + ""; + if (options.quoteKeys) { + keyDisplay = '"' + keyDisplay + '"'; + } + } + buf.push(tab, keyDisplay, + ": ", format(val[key], depth + 1)); + index++; + } + if (index >= 0) { + buf.push(options.linesep, tab.substr(options.indent)); + } + buf.push("}"); + if (options.html) { + return "" + buf.join("") + ""; + } + } + + return buf.join(""); + } + } + } + + function indentLines(text, tab) { + var lines = text.split("\n"); + for (var i in lines) { + lines[i] = (i > 0 ? tab : "") + $.futon.escape(lines[i]); + } + return lines.join("
        "); + } + + return format(val, 1); + }, + + // File size pretty printing + formatSize: function(size) { + var jump = 512; + if (size < jump) return size + " bytes"; + var units = ["KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"]; + var i = 0; + while (size >= jump && i < units.length) { + i += 1; + size /= 1024 + } + return size.toFixed(1) + ' ' + units[i - 1]; + } + + }); + +})(jQuery); diff --git a/1.1.x/share/www/script/futon.js b/1.1.x/share/www/script/futon.js new file mode 100644 index 00000000..fb73e3c9 --- /dev/null +++ b/1.1.x/share/www/script/futon.js @@ -0,0 +1,535 @@ +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy of +// the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations under +// the License. + +// $$ inspired by @wycats: http://yehudakatz.com/2009/04/20/evented-programming-with-jquery/ +function $$(node) { + var data = $(node).data("$$"); + if (data) { + return data; + } else { + data = {}; + $(node).data("$$", data); + return data; + } +}; + +(function($) { + + function Session() { + + function doLogin(name, password, callback) { + $.couch.login({ + name : name, + password : password, + success : function() { + $.futon.session.sidebar(); + callback(); + }, + error : function(code, error, reason) { + $.futon.session.sidebar(); + callback({name : "Error logging in: "+reason}); + } + }); + }; + + function doSignup(name, password, callback, runLogin) { + $.couch.signup({ + name : name + }, password, { + success : function() { + if (runLogin) { + doLogin(name, password, callback); + } else { + callback(); + } + }, + error : function(status, error, reason) { + $.futon.session.sidebar(); + if (error == "conflict") { + callback({name : "Name '"+name+"' is taken"}); + } else { + callback({name : "Signup error: "+reason}); + } + } + }); + }; + + function validateUsernameAndPassword(data, callback) { + if (!data.name || data.name.length == 0) { + callback({name: "Please enter a name."}); + return false; + }; + return validatePassword(data, callback); + }; + + function validatePassword(data, callback) { + if (!data.password || data.password.length == 0) { + callback({password: "Please enter a password."}); + return false; + }; + return true; + }; + + function createAdmin() { + $.showDialog("dialog/_create_admin.html", { + submit: function(data, callback) { + if (!validateUsernameAndPassword(data, callback)) return; + $.couch.config({ + success : function() { + doLogin(data.name, data.password, function(errors) { + if(!$.isEmptyObject(errors)) { + callback(errors); + return; + } + doSignup(data.name, null, function(errors) { + if (errors && errors.name && errors.name.indexOf && errors.name.indexOf("taken") == -1) { + callback(errors); + } else { + callback(); + } + }, false); + }); + } + }, "admins", data.name, data.password); + } + }); + return false; + }; + + function login() { + $.showDialog("dialog/_login.html", { + submit: function(data, callback) { + if (!validateUsernameAndPassword(data, callback)) return; + doLogin(data.name, data.password, callback); + } + }); + return false; + }; + + function logout() { + $.couch.logout({ + success : function(resp) { + $.futon.session.sidebar(); + } + }) + }; + + function signup() { + $.showDialog("dialog/_signup.html", { + submit: function(data, callback) { + if (!validateUsernameAndPassword(data, callback)) return; + doSignup(data.name, data.password, callback, true); + } + }); + return false; + }; + + function changePassword () { + $.showDialog("dialog/_change_password.html", { + submit: function(data, callback) { + if (validatePassword(data, callback)) { + if (data.password != data.verify_password) { + callback({verify_password: "Passwords don't match."}); + return false; + } + } else { + return false; + } + $.couch.session({success: function (resp) { + if (resp.userCtx.roles.indexOf("_admin") > -1) { + $.couch.config({ + success : function () { + doLogin(resp.userCtx.name, data.password, function(errors) { + if(!$.isEmptyObject(errors)) { + callback(errors); + return; + } else { + location.reload(); + } + }); + } + }, "admins", resp.userCtx.name, data.password); + } else { + $.couch.db(resp.info.authentication_db).openDoc("org.couchdb.user:"+resp.userCtx.name, { + success: function (user) { + $.couch.db(resp.info.authentication_db).saveDoc($.couch.prepareUserDoc(user, data.password), { + success: function() { + doLogin(user.name, data.password, function(errors) { + if(!$.isEmptyObject(errors)) { + callback(errors); + return; + } else { + location.reload(); + } + }); + } + }); + } + }); + } + }}); + } + }); + return false; + }; + + this.setupSidebar = function() { + $("#userCtx .login").click(login); + $("#userCtx .logout").click(logout); + $("#userCtx .signup").click(signup); + $("#userCtx .createadmin").click(createAdmin); + $("#userCtx .changepass").click(changePassword); + }; + + this.sidebar = function() { + // get users db info? + $("#userCtx span").hide(); + $.couch.session({ + success : function(r) { + var userCtx = r.userCtx; + $$("#userCtx").userCtx = userCtx; + if (userCtx.name) { + $("#userCtx .name").text(userCtx.name).attr({href : $.couch.urlPrefix + "/_utils/document.html?"+encodeURIComponent(r.info.authentication_db)+"/org.couchdb.user%3A"+encodeURIComponent(userCtx.name)}); + if (userCtx.roles.indexOf("_admin") != -1) { + $("#userCtx .loggedin").show(); + $("#userCtx .loggedinadmin").show(); + } else { + $("#userCtx .loggedin").show(); + } + } else if (userCtx.roles.indexOf("_admin") != -1) { + $("#userCtx .adminparty").show(); + } else { + $("#userCtx .loggedout").show(); + }; + } + }) + }; + }; + + function Navigation() { + var nav = this; + this.loaded = false; + this.eventHandlers = { + load: [] + }; + + this.ready = function(callback) { + if (callback) { + if (this.loaded) { + callback.apply(this); + } + this.eventHandlers["load"].push(callback); + } else { + this.loaded = true; + callbacks = this.eventHandlers["load"]; + for (var i = 0; i < callbacks.length; i++) { + callbacks[i].apply(this); + } + } + } + + this.addDatabase = function(name) { + var current = $.futon.storage.get("recent", ""); + var recentDbs = current ? current.split(",") : []; + if ($.inArray(name, recentDbs) == -1) { + recentDbs.unshift(name); + if (recentDbs.length > 10) recentDbs.length = 10; + $.futon.storage.set("recent", recentDbs.join(",")); + this.updateDatabases(); + } + } + + this.removeDatabase = function(name) { + // remove database from recent databases list + var current = $.futon.storage.get("recent", ""); + var recentDbs = current ? current.split(",") : []; + var recentIdx = $.inArray(name, recentDbs); + if (recentIdx >= 0) { + recentDbs.splice(recentIdx, 1); + $.futon.storage.set("recent", recentDbs.join(",")); + this.updateDatabases(); + } + } + + this.updateDatabases = function() { + var selection = null; + $("#dbs .selected a").each(function() { + selection = [this.pathname, this.search]; + }); + $("#dbs").empty(); + var recentDbs = $.futon.storage.get("recent").split(","); + recentDbs.sort(); + $.each(recentDbs, function(idx, name) { + if (name) { + name = encodeURIComponent(name); + $("#dbs").append("
      • " + + "" + + "" + name + + "
      • "); + } + }); + if (selection) { + this.updateSelection(selection[0], selection[1]); + } + $("#dbs button.remove").click(function() { + nav.removeDatabase(this.value); + return false; + }); + } + + this.updateSelection = function(path, queryString) { + function fixupPath(path) { // hack for IE/Win + return (path.charAt(0) != "/") ? ("/" + path) : path; + } + if (!path) { + path = location.pathname; + if (!queryString) { + queryString = location.search; + } + } else if (!queryString) { + queryString = ""; + } + var href = fixupPath(path + queryString); + $("#nav li").removeClass("selected"); + $("#nav li a").each(function() { + if (fixupPath(this.pathname) + this.search != href) return; + $(this).parent("li").addClass("selected").parents("li").addClass("selected"); + }); + } + + this.toggle = function(speed) { + if (speed === undefined) { + speed = 500; + } + var sidebar = $("#sidebar").stop(true, true); + var hidden = !$(sidebar).is(".hidden"); + + $("#wrap").animate({ + marginRight: hidden ? 0 : 210 + }, speed, function() { + $(document.body).toggleClass("fullwidth", hidden); + }); + sidebar.toggleClass("hidden").animate({ + width: hidden ? 26 : 210, + height: hidden ? $("h1").outerHeight() - 1 : "100%", + right: hidden ? 0 : -210 + }, speed).children(":not(#sidebar-toggle)").animate({ + opacity: "toggle" + }, speed); + $("h1").animate({marginRight: hidden ? 26 : 0}, speed); + + $("#sidebar-toggle") + .attr("title", hidden ? "Show Sidebar" : "Hide Sidebar"); + $.futon.storage.set("sidebar", hidden ? "hidden" : "show"); + }; + } + + function Storage() { + var storage = this; + this.decls = {}; + + this.declare = function(name, options) { + this.decls[name] = $.extend({}, { + scope: "window", + defaultValue: null, + prefix: "" + }, options || {}); + } + + this.declareWithPrefix = function(prefix, decls) { + for (var name in decls) { + var options = decls[name]; + options.prefix = prefix; + storage.declare(name, options); + } + } + + this.del = function(name) { + lookup(name, function(decl) { + handlers[decl.scope].del(decl.prefix + name); + }); + } + + this.get = function(name, defaultValue) { + return lookup(name, function(decl) { + var value = handlers[decl.scope].get(decl.prefix + name); + if (value !== undefined) { + return value; + } + if (defaultValue !== undefined) { + return defaultValue; + } + return decl.defaultValue; + }); + } + + this.set = function(name, value) { + lookup(name, function(decl) { + if (value == decl.defaultValue) { + handlers[decl.scope].del(decl.prefix + name); + } else { + handlers[decl.scope].set(decl.prefix + name, value); + } + }); + } + + function lookup(name, callback) { + var decl = storage.decls[name]; + if (decl === undefined) { + return decl; + } + return callback(decl); + } + + function windowName() { + try { + return JSON.parse(window.name || "{}"); + } catch (e) { + return {}; + } + } + + // add suffix to cookie names to be able to separate between ports + var cookiePrefix = location.port + "_"; + + var handlers = { + + "cookie": { + get: function(name) { + var nameEq = cookiePrefix + name + "="; + var parts = document.cookie.split(';'); + for (var i = 0; i < parts.length; i++) { + var part = parts[i].replace(/^\s+/, ""); + if (part.indexOf(nameEq) == 0) { + return unescape(part.substring(nameEq.length, part.length)); + } + } + }, + set: function(name, value) { + var date = new Date(); + date.setTime(date.getTime() + 14*24*60*60*1000); // two weeks + document.cookie = cookiePrefix + name + "=" + escape(value) + + "; expires=" + date.toGMTString(); + }, + del: function(name) { + var date = new Date(); + date.setTime(date.getTime() - 24*60*60*1000); // yesterday + document.cookie = cookiePrefix + name + "=" + + "; expires=" + date.toGMTString(); + } + }, + + "window": { + get: function(name) { + return windowName()[name]; + }, + set: function(name, value) { + var obj = windowName(); + obj[name] = value || null; + window.name = JSON.stringify(obj); + }, + del: function(name) { + var obj = windowName(); + delete obj[name]; + window.name = JSON.stringify(obj); + } + } + + }; + + } + + $.couch.urlPrefix = ".."; + $.futon = $.futon || {}; + $.extend($.futon, { + navigation: new Navigation(), + session : new Session(), + storage: new Storage() + }); + + $.fn.addPlaceholder = function() { + if (this[0] && "placeholder" in document.createElement("input")) { + return; // found native placeholder support + } + return this.live('focusin', function() { + var input = $(this); + if (input.val() === input.attr("placeholder")) { + input.removeClass("placeholder").val(""); + } + }).live("focusout", function() { + var input = $(this); + if (input.val() === "") { + input.val(input.attr("placeholder")).addClass("placeholder"); + } + }).trigger("focusout"); + } + + $.fn.enableTabInsertion = function(chars) { + chars = chars || "\t"; + var width = chars.length; + return this.keydown(function(evt) { + if (evt.keyCode == 9) { + var v = this.value; + var start = this.selectionStart; + var scrollTop = this.scrollTop; + if (start !== undefined) { + this.value = v.slice(0, start) + chars + v.slice(start); + this.selectionStart = this.selectionEnd = start + width; + } else { + document.selection.createRange().text = chars; + this.caretPos += width; + } + return false; + } + }); + } + + $(document) + .ajaxStart(function() { $(this.body).addClass("loading"); }) + .ajaxStop(function() { $(this.body).removeClass("loading"); }); + + $.futon.storage.declare("sidebar", {scope: "cookie", defaultValue: "show"}); + $.futon.storage.declare("recent", {scope: "cookie", defaultValue: ""}); + + $(function() { + document.title = "Apache CouchDB - Futon: " + document.title; + if ($.futon.storage.get("sidebar") == "hidden") { + // doing this as early as possible prevents flickering + $(document.body).addClass("fullwidth"); + } + $("input[placeholder]").addPlaceholder(); + + $.get("_sidebar.html", function(resp) { + $("#wrap").append(resp) + .find("#sidebar-toggle").click(function(e) { + $.futon.navigation.toggle(e.shiftKey ? 2500 : 500); + return false; + }); + if ($.futon.storage.get("sidebar") == "hidden") { + $.futon.navigation.toggle(0); + } + + $.futon.navigation.updateDatabases(); + $.futon.navigation.updateSelection(); + $.futon.navigation.ready(); + $.futon.session.setupSidebar(); + $.futon.session.sidebar(); + + $.couch.info({ + success: function(info, status) { + $("#version").text(info.version); + } + }); + }); + }); + +})(jQuery); diff --git a/1.1.x/share/www/script/jquery-ui-1.8.11.custom.min.js b/1.1.x/share/www/script/jquery-ui-1.8.11.custom.min.js new file mode 100644 index 00000000..45b927e0 --- /dev/null +++ b/1.1.x/share/www/script/jquery-ui-1.8.11.custom.min.js @@ -0,0 +1,81 @@ +/*! + * jQuery UI 1.8.11 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI + */ +(function(c,j){function k(a){return!c(a).parents().andSelf().filter(function(){return c.curCSS(this,"visibility")==="hidden"||c.expr.filters.hidden(this)}).length}c.ui=c.ui||{};if(!c.ui.version){c.extend(c.ui,{version:"1.8.11",keyCode:{ALT:18,BACKSPACE:8,CAPS_LOCK:20,COMMA:188,COMMAND:91,COMMAND_LEFT:91,COMMAND_RIGHT:93,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,INSERT:45,LEFT:37,MENU:93,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106, +NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SHIFT:16,SPACE:32,TAB:9,UP:38,WINDOWS:91}});c.fn.extend({_focus:c.fn.focus,focus:function(a,b){return typeof a==="number"?this.each(function(){var d=this;setTimeout(function(){c(d).focus();b&&b.call(d)},a)}):this._focus.apply(this,arguments)},scrollParent:function(){var a;a=c.browser.msie&&/(static|relative)/.test(this.css("position"))||/absolute/.test(this.css("position"))?this.parents().filter(function(){return/(relative|absolute|fixed)/.test(c.curCSS(this, +"position",1))&&/(auto|scroll)/.test(c.curCSS(this,"overflow",1)+c.curCSS(this,"overflow-y",1)+c.curCSS(this,"overflow-x",1))}).eq(0):this.parents().filter(function(){return/(auto|scroll)/.test(c.curCSS(this,"overflow",1)+c.curCSS(this,"overflow-y",1)+c.curCSS(this,"overflow-x",1))}).eq(0);return/fixed/.test(this.css("position"))||!a.length?c(document):a},zIndex:function(a){if(a!==j)return this.css("zIndex",a);if(this.length){a=c(this[0]);for(var b;a.length&&a[0]!==document;){b=a.css("position"); +if(b==="absolute"||b==="relative"||b==="fixed"){b=parseInt(a.css("zIndex"),10);if(!isNaN(b)&&b!==0)return b}a=a.parent()}}return 0},disableSelection:function(){return this.bind((c.support.selectstart?"selectstart":"mousedown")+".ui-disableSelection",function(a){a.preventDefault()})},enableSelection:function(){return this.unbind(".ui-disableSelection")}});c.each(["Width","Height"],function(a,b){function d(f,g,l,m){c.each(e,function(){g-=parseFloat(c.curCSS(f,"padding"+this,true))||0;if(l)g-=parseFloat(c.curCSS(f, +"border"+this+"Width",true))||0;if(m)g-=parseFloat(c.curCSS(f,"margin"+this,true))||0});return g}var e=b==="Width"?["Left","Right"]:["Top","Bottom"],h=b.toLowerCase(),i={innerWidth:c.fn.innerWidth,innerHeight:c.fn.innerHeight,outerWidth:c.fn.outerWidth,outerHeight:c.fn.outerHeight};c.fn["inner"+b]=function(f){if(f===j)return i["inner"+b].call(this);return this.each(function(){c(this).css(h,d(this,f)+"px")})};c.fn["outer"+b]=function(f,g){if(typeof f!=="number")return i["outer"+b].call(this,f);return this.each(function(){c(this).css(h, +d(this,f,true,g)+"px")})}});c.extend(c.expr[":"],{data:function(a,b,d){return!!c.data(a,d[3])},focusable:function(a){var b=a.nodeName.toLowerCase(),d=c.attr(a,"tabindex");if("area"===b){b=a.parentNode;d=b.name;if(!a.href||!d||b.nodeName.toLowerCase()!=="map")return false;a=c("img[usemap=#"+d+"]")[0];return!!a&&k(a)}return(/input|select|textarea|button|object/.test(b)?!a.disabled:"a"==b?a.href||!isNaN(d):!isNaN(d))&&k(a)},tabbable:function(a){var b=c.attr(a,"tabindex");return(isNaN(b)||b>=0)&&c(a).is(":focusable")}}); +c(function(){var a=document.body,b=a.appendChild(b=document.createElement("div"));c.extend(b.style,{minHeight:"100px",height:"auto",padding:0,borderWidth:0});c.support.minHeight=b.offsetHeight===100;c.support.selectstart="onselectstart"in b;a.removeChild(b).style.display="none"});c.extend(c.ui,{plugin:{add:function(a,b,d){a=c.ui[a].prototype;for(var e in d){a.plugins[e]=a.plugins[e]||[];a.plugins[e].push([b,d[e]])}},call:function(a,b,d){if((b=a.plugins[b])&&a.element[0].parentNode)for(var e=0;e0)return true;a[b]=1;d=a[b]>0;a[b]=0;return d},isOverAxis:function(a,b,d){return a>b&&a0?b.left-d:Math.max(b.left-a.collisionPosition.left,b.left)},top:function(b,a){var d=c(window);d=a.collisionPosition.top+a.collisionHeight-d.height()-d.scrollTop();b.top=d>0?b.top-d:Math.max(b.top-a.collisionPosition.top,b.top)}},flip:{left:function(b,a){if(a.at[0]!=="center"){var d=c(window);d=a.collisionPosition.left+a.collisionWidth-d.width()-d.scrollLeft();var g=a.my[0]==="left"?-a.elemWidth:a.my[0]==="right"?a.elemWidth:0,e=a.at[0]==="left"?a.targetWidth:-a.targetWidth,h=-2*a.offset[0];b.left+= +a.collisionPosition.left<0?g+e+h:d>0?g+e+h:0}},top:function(b,a){if(a.at[1]!=="center"){var d=c(window);d=a.collisionPosition.top+a.collisionHeight-d.height()-d.scrollTop();var g=a.my[1]==="top"?-a.elemHeight:a.my[1]==="bottom"?a.elemHeight:0,e=a.at[1]==="top"?a.targetHeight:-a.targetHeight,h=-2*a.offset[1];b.top+=a.collisionPosition.top<0?g+e+h:d>0?g+e+h:0}}}};if(!c.offset.setOffset){c.offset.setOffset=function(b,a){if(/static/.test(c.curCSS(b,"position")))b.style.position="relative";var d=c(b), +g=d.offset(),e=parseInt(c.curCSS(b,"top",true),10)||0,h=parseInt(c.curCSS(b,"left",true),10)||0;g={top:a.top-g.top+e,left:a.left-g.left+h};"using"in a?a.using.call(b,g):d.css(g)};c.fn.offset=function(b){var a=this[0];if(!a||!a.ownerDocument)return null;if(b)return this.each(function(){c.offset.setOffset(this,b)});return u.call(this)}}})(jQuery); +;/* + * jQuery UI Autocomplete 1.8.11 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Autocomplete + * + * Depends: + * jquery.ui.core.js + * jquery.ui.widget.js + * jquery.ui.position.js + */ +(function(d){var e=0;d.widget("ui.autocomplete",{options:{appendTo:"body",autoFocus:false,delay:300,minLength:1,position:{my:"left top",at:"left bottom",collision:"none"},source:null},pending:0,_create:function(){var a=this,b=this.element[0].ownerDocument,g;this.element.addClass("ui-autocomplete-input").attr("autocomplete","off").attr({role:"textbox","aria-autocomplete":"list","aria-haspopup":"true"}).bind("keydown.autocomplete",function(c){if(!(a.options.disabled||a.element.attr("readonly"))){g= +false;var f=d.ui.keyCode;switch(c.keyCode){case f.PAGE_UP:a._move("previousPage",c);break;case f.PAGE_DOWN:a._move("nextPage",c);break;case f.UP:a._move("previous",c);c.preventDefault();break;case f.DOWN:a._move("next",c);c.preventDefault();break;case f.ENTER:case f.NUMPAD_ENTER:if(a.menu.active){g=true;c.preventDefault()}case f.TAB:if(!a.menu.active)return;a.menu.select(c);break;case f.ESCAPE:a.element.val(a.term);a.close(c);break;default:clearTimeout(a.searching);a.searching=setTimeout(function(){if(a.term!= +a.element.val()){a.selectedItem=null;a.search(null,c)}},a.options.delay);break}}}).bind("keypress.autocomplete",function(c){if(g){g=false;c.preventDefault()}}).bind("focus.autocomplete",function(){if(!a.options.disabled){a.selectedItem=null;a.previous=a.element.val()}}).bind("blur.autocomplete",function(c){if(!a.options.disabled){clearTimeout(a.searching);a.closing=setTimeout(function(){a.close(c);a._change(c)},150)}});this._initSource();this.response=function(){return a._response.apply(a,arguments)}; +this.menu=d("
          ").addClass("ui-autocomplete").appendTo(d(this.options.appendTo||"body",b)[0]).mousedown(function(c){var f=a.menu.element[0];d(c.target).closest(".ui-menu-item").length||setTimeout(function(){d(document).one("mousedown",function(h){h.target!==a.element[0]&&h.target!==f&&!d.ui.contains(f,h.target)&&a.close()})},1);setTimeout(function(){clearTimeout(a.closing)},13)}).menu({focus:function(c,f){f=f.item.data("item.autocomplete");false!==a._trigger("focus",c,{item:f})&&/^key/.test(c.originalEvent.type)&& +a.element.val(f.value)},selected:function(c,f){var h=f.item.data("item.autocomplete"),i=a.previous;if(a.element[0]!==b.activeElement){a.element.focus();a.previous=i;setTimeout(function(){a.previous=i;a.selectedItem=h},1)}false!==a._trigger("select",c,{item:h})&&a.element.val(h.value);a.term=a.element.val();a.close(c);a.selectedItem=h},blur:function(){a.menu.element.is(":visible")&&a.element.val()!==a.term&&a.element.val(a.term)}}).zIndex(this.element.zIndex()+1).css({top:0,left:0}).hide().data("menu"); +d.fn.bgiframe&&this.menu.element.bgiframe()},destroy:function(){this.element.removeClass("ui-autocomplete-input").removeAttr("autocomplete").removeAttr("role").removeAttr("aria-autocomplete").removeAttr("aria-haspopup");this.menu.element.remove();d.Widget.prototype.destroy.call(this)},_setOption:function(a,b){d.Widget.prototype._setOption.apply(this,arguments);a==="source"&&this._initSource();if(a==="appendTo")this.menu.element.appendTo(d(b||"body",this.element[0].ownerDocument)[0]);a==="disabled"&& +b&&this.xhr&&this.xhr.abort()},_initSource:function(){var a=this,b,g;if(d.isArray(this.options.source)){b=this.options.source;this.source=function(c,f){f(d.ui.autocomplete.filter(b,c.term))}}else if(typeof this.options.source==="string"){g=this.options.source;this.source=function(c,f){a.xhr&&a.xhr.abort();a.xhr=d.ajax({url:g,data:c,dataType:"json",autocompleteRequest:++e,success:function(h){this.autocompleteRequest===e&&f(h)},error:function(){this.autocompleteRequest===e&&f([])}})}}else this.source= +this.options.source},search:function(a,b){a=a!=null?a:this.element.val();this.term=this.element.val();if(a.length").data("item.autocomplete",b).append(d("").text(b.label)).appendTo(a)},_move:function(a,b){if(this.menu.element.is(":visible"))if(this.menu.first()&&/^previous/.test(a)||this.menu.last()&&/^next/.test(a)){this.element.val(this.term);this.menu.deactivate()}else this.menu[a](b);else this.search(null,b)},widget:function(){return this.menu.element}});d.extend(d.ui.autocomplete,{escapeRegex:function(a){return a.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, +"\\$&")},filter:function(a,b){var g=new RegExp(d.ui.autocomplete.escapeRegex(b),"i");return d.grep(a,function(c){return g.test(c.label||c.value||c)})}})})(jQuery); +(function(d){d.widget("ui.menu",{_create:function(){var e=this;this.element.addClass("ui-menu ui-widget ui-widget-content ui-corner-all").attr({role:"listbox","aria-activedescendant":"ui-active-menuitem"}).click(function(a){if(d(a.target).closest(".ui-menu-item a").length){a.preventDefault();e.select(a)}});this.refresh()},refresh:function(){var e=this;this.element.children("li:not(.ui-menu-item):has(a)").addClass("ui-menu-item").attr("role","menuitem").children("a").addClass("ui-corner-all").attr("tabindex", +-1).mouseenter(function(a){e.activate(a,d(this).parent())}).mouseleave(function(){e.deactivate()})},activate:function(e,a){this.deactivate();if(this.hasScroll()){var b=a.offset().top-this.element.offset().top,g=this.element.attr("scrollTop"),c=this.element.height();if(b<0)this.element.attr("scrollTop",g+b);else b>=c&&this.element.attr("scrollTop",g+b-c+a.height())}this.active=a.eq(0).children("a").addClass("ui-state-hover").attr("id","ui-active-menuitem").end();this._trigger("focus",e,{item:a})}, +deactivate:function(){if(this.active){this.active.children("a").removeClass("ui-state-hover").removeAttr("id");this._trigger("blur");this.active=null}},next:function(e){this.move("next",".ui-menu-item:first",e)},previous:function(e){this.move("prev",".ui-menu-item:last",e)},first:function(){return this.active&&!this.active.prevAll(".ui-menu-item").length},last:function(){return this.active&&!this.active.nextAll(".ui-menu-item").length},move:function(e,a,b){if(this.active){e=this.active[e+"All"](".ui-menu-item").eq(0); +e.length?this.activate(b,e):this.activate(b,this.element.children(a))}else this.activate(b,this.element.children(a))},nextPage:function(e){if(this.hasScroll())if(!this.active||this.last())this.activate(e,this.element.children(".ui-menu-item:first"));else{var a=this.active.offset().top,b=this.element.height(),g=this.element.children(".ui-menu-item").filter(function(){var c=d(this).offset().top-a-b+d(this).height();return c<10&&c>-10});g.length||(g=this.element.children(".ui-menu-item:last"));this.activate(e, +g)}else this.activate(e,this.element.children(".ui-menu-item").filter(!this.active||this.last()?":first":":last"))},previousPage:function(e){if(this.hasScroll())if(!this.active||this.first())this.activate(e,this.element.children(".ui-menu-item:last"));else{var a=this.active.offset().top,b=this.element.height();result=this.element.children(".ui-menu-item").filter(function(){var g=d(this).offset().top-a+b-d(this).height();return g<10&&g>-10});result.length||(result=this.element.children(".ui-menu-item:first")); +this.activate(e,result)}else this.activate(e,this.element.children(".ui-menu-item").filter(!this.active||this.first()?":last":":first"))},hasScroll:function(){return this.element.height()= 0, + data = xml ? xhr.responseXML : xhr.responseText; + + if ( xml && data.documentElement.nodeName === "parsererror" ) { + $.error( "parsererror" ); + } + if ( s && s.dataFilter ) { + data = s.dataFilter( data, type ); + } + if ( typeof data === "string" ) { + if ( type === "json" || !type && ct.indexOf("json") >= 0 ) { + data = $.parseJSON( data ); + } else if ( type === "script" || !type && ct.indexOf("javascript") >= 0 ) { + $.globalEval( data ); + } + } + return data; + }; + + function ajax(obj, options, errorMessage, ajaxOptions) { + options = $.extend({successStatus: 200}, options); + ajaxOptions = $.extend({contentType: "application/json"}, ajaxOptions); + errorMessage = errorMessage || "Unknown error"; + $.ajax($.extend($.extend({ + type: "GET", dataType: "json", cache : !$.browser.msie, + beforeSend: function(xhr){ + if(ajaxOptions && ajaxOptions.headers){ + for (var header in ajaxOptions.headers){ + xhr.setRequestHeader(header, ajaxOptions.headers[header]); + } + } + }, + complete: function(req) { + try { + var resp = httpData(req, "json"); + } catch(e) { + if (options.error) { + options.error(req.status, req, e); + } else { + alert(errorMessage + ": " + e); + } + return; + } + if (options.ajaxStart) { + options.ajaxStart(resp); + } + if (req.status == options.successStatus) { + if (options.beforeSuccess) options.beforeSuccess(req, resp); + if (options.success) options.success(resp); + } else if (options.error) { + options.error(req.status, resp && resp.error || errorMessage, resp && resp.reason || "no response"); + } else { + alert(errorMessage + ": " + resp.reason); + } + } + }, obj), ajaxOptions)); + } + + function fullCommit(options) { + var options = options || {}; + if (typeof options.ensure_full_commit !== "undefined") { + var commit = options.ensure_full_commit; + delete options.ensure_full_commit; + return function(xhr) { + xhr.setRequestHeader('Accept', 'application/json'); + xhr.setRequestHeader("X-Couch-Full-Commit", commit.toString()); + }; + } + }; + + // Convert a options object to an url query string. + // ex: {key:'value',key2:'value2'} becomes '?key="value"&key2="value2"' + function encodeOptions(options) { + var buf = []; + if (typeof(options) === "object" && options !== null) { + for (var name in options) { + if ($.inArray(name, ["error", "success", "beforeSuccess", "ajaxStart"]) >= 0) + continue; + var value = options[name]; + if ($.inArray(name, ["key", "startkey", "endkey"]) >= 0) { + value = toJSON(value); + } + buf.push(encodeURIComponent(name) + "=" + encodeURIComponent(value)); + } + } + return buf.length ? "?" + buf.join("&") : ""; + } + + function toJSON(obj) { + return obj !== null ? JSON.stringify(obj) : null; + } + +})(jQuery); diff --git a/1.1.x/share/www/script/jquery.dialog.js b/1.1.x/share/www/script/jquery.dialog.js new file mode 100644 index 00000000..02c0c497 --- /dev/null +++ b/1.1.x/share/www/script/jquery.dialog.js @@ -0,0 +1,96 @@ +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy of +// the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations under +// the License. + +(function($) { + + $.fn.centerBox = function() { + return this.each(function() { + var s = this.style; + s.left = (($(window).width() - $(this).width()) / 2) + "px"; + s.top = (($(window).height() - $(this).height()) / 2) + "px"; + }); + } + + $.showDialog = function(url, options) { + options = options || {}; + options.load = options.load || function() {}; + options.cancel = options.cancel || function() {}; + options.validate = options.validate || function() { return true }; + options.submit = options.submit || function() {}; + + var overlay = $('
          ') + .css("opacity", "0"); + var dialog = $(''); + if ($.browser.msie) { + var frame = $('') + .css("opacity", "0").appendTo(document.body); + if (parseInt($.browser.version)<7) { + dialog.css("position", "absolute"); + overlay.css("position", "absolute"); + $("html,body").css({width: "100%", height: "100%"}); + } + } + overlay.appendTo(document.body).fadeTo(100, 0.6); + dialog.appendTo(document.body).addClass("loading").centerBox().fadeIn(400); + + $(document).keydown(function(e) { + if (e.keyCode == 27) dismiss(); // dismiss on escape key + }); + function dismiss() { + dialog.fadeOut("fast", function() { + $("#dialog, #overlay, #overlay-frame").remove(); + }); + $(document).unbind("keydown"); + } + overlay.click(function() { dismiss(); }); + + function showError(name, message) { + var input = dialog.find(":input[name=" + name + "]"); + input.addClass("error").next("div.error").remove(); + $('
          ').text(message).insertAfter(input); + } + + $.get(url, function(html) { + $(html).appendTo(dialog); + dialog.removeClass("loading").addClass("loaded").centerBox().each(function() { + options.load(dialog.children()[0]); + $(":input:first", dialog).each(function() { this.focus() }); + $("button.cancel", dialog).click(function() { // dismiss on cancel + dismiss(); + options.cancel(); + }); + $("form", dialog).submit(function(e) { // invoke callback on submit + e.preventDefault(); + dialog.find("div.error").remove().end().find(".error").removeClass("error"); + var data = {}; + $.each($("form :input", dialog).serializeArray(), function(i, field) { + data[field.name] = field.value; + }); + $("form :file", dialog).each(function() { + data[this.name] = this.value; // file inputs need special handling + }); + options.submit(data, function callback(errors) { + if ($.isEmptyObject(errors)) { + dismiss(); + } else { + for (var name in errors) { + showError(name, errors[name]); + } + } + }); + return false; + }); + }); + }); + } + +})(jQuery); diff --git a/1.1.x/share/www/script/jquery.editinline.js b/1.1.x/share/www/script/jquery.editinline.js new file mode 100644 index 00000000..b48607d4 --- /dev/null +++ b/1.1.x/share/www/script/jquery.editinline.js @@ -0,0 +1,114 @@ +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy of +// the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations under +// the License. + +(function($) { + + function startEditing(elem, options) { + var editable = $(elem); + var origHtml = editable.html(); + var origText = options.populate($.trim(editable.text())); + + if (!options.begin.apply(elem, [origText])) { + return; + } + + var input = options.createInput.apply(elem, [origText]) + .addClass("editinline").val(origText) + .dblclick(function() { return false; }) + .keydown(function(evt) { + switch (evt.keyCode) { + case 13: { // return + if (!input.is("textarea")) applyChange(evt.keyCode); + break; + } + case 27: { // escape + cancelChange(evt.keyCode); + break; + } + case 9: { // tab + if (!input.is("textarea")) { + applyChange(evt.keyCode); + return false; + } + } + } + }); + if (options.acceptOnBlur) { + input.blur(function() { + return applyChange(); + }); + } + + function applyChange(keyCode) { + var newText = input.val(); + if (newText == origText) { + cancelChange(keyCode); + return true; + } + if ((!options.allowEmpty && !newText.length) || + !options.validate.apply(elem, [newText, origText])) { + input.addClass("invalid"); + return false; + } + input.remove(); + tools.remove(); + options.accept.apply(elem, [newText, origText]); + editable.removeClass("editinline-container"); + options.end.apply(elem, [keyCode]); + return true; + } + + function cancelChange(keyCode) { + options.cancel.apply(elem, [origText]); + editable.html(origHtml).removeClass("editinline-container"); + options.end.apply(elem, [keyCode]); + } + + var tools = $(""); + $("") + .text(options.acceptLabel).click(applyChange).appendTo(tools); + $("") + .text(options.cancelLabel).click(cancelChange).appendTo(tools) + + editable.html("").append(tools).append(input) + .addClass("editinline-container"); + options.prepareInput.apply(elem, [input[0]]); + input.each(function() { this.focus(); this.select(); }); + } + + $.fn.makeEditable = function(options) { + options = $.extend({ + allowEmpty: true, + acceptLabel: "", + cancelLabel: "", + toolTip: "Double click to edit", + acceptOnBlur: true, + + // callbacks + begin: function() { return true }, + accept: function(newValue, oldValue) {}, + cancel: function(oldValue) {}, + createInput: function(value) { return $("") }, + prepareInput: function(input) {}, + end: function(keyCode) {}, + populate: function(value) { return value }, + validate: function() { return true } + }, options || {}); + + return this.each(function() { + $(this).attr("title", options.toolTip).dblclick(function() { + startEditing(this, options); + }); + }); + } + +})(jQuery); diff --git a/1.1.x/share/www/script/jquery.form.js b/1.1.x/share/www/script/jquery.form.js new file mode 100644 index 00000000..dde39427 --- /dev/null +++ b/1.1.x/share/www/script/jquery.form.js @@ -0,0 +1,660 @@ +/* + * jQuery Form Plugin + * version: 2.36 (07-NOV-2009) + * @requires jQuery v1.2.6 or later + * + * Examples and documentation at: http://malsup.com/jquery/form/ + * Dual licensed under the MIT and GPL licenses: + * http://www.opensource.org/licenses/mit-license.php + * http://www.gnu.org/licenses/gpl.html + */ +;(function($) { + +/* + Usage Note: + ----------- + Do not use both ajaxSubmit and ajaxForm on the same form. These + functions are intended to be exclusive. Use ajaxSubmit if you want + to bind your own submit handler to the form. For example, + + $(document).ready(function() { + $('#myForm').bind('submit', function() { + $(this).ajaxSubmit({ + target: '#output' + }); + return false; // <-- important! + }); + }); + + Use ajaxForm when you want the plugin to manage all the event binding + for you. For example, + + $(document).ready(function() { + $('#myForm').ajaxForm({ + target: '#output' + }); + }); + + When using ajaxForm, the ajaxSubmit function will be invoked for you + at the appropriate time. +*/ + +/** + * ajaxSubmit() provides a mechanism for immediately submitting + * an HTML form using AJAX. + */ +$.fn.ajaxSubmit = function(options) { + // fast fail if nothing selected (http://dev.jquery.com/ticket/2752) + if (!this.length) { + log('ajaxSubmit: skipping submit process - no element selected'); + return this; + } + + if (typeof options == 'function') + options = { success: options }; + + var url = $.trim(this.attr('action')); + if (url) { + // clean url (don't include hash vaue) + url = (url.match(/^([^#]+)/)||[])[1]; + } + url = url || window.location.href || ''; + + options = $.extend({ + url: url, + type: this.attr('method') || 'GET', + iframeSrc: /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank' + }, options || {}); + + // hook for manipulating the form data before it is extracted; + // convenient for use with rich editors like tinyMCE or FCKEditor + var veto = {}; + this.trigger('form-pre-serialize', [this, options, veto]); + if (veto.veto) { + log('ajaxSubmit: submit vetoed via form-pre-serialize trigger'); + return this; + } + + // provide opportunity to alter form data before it is serialized + if (options.beforeSerialize && options.beforeSerialize(this, options) === false) { + log('ajaxSubmit: submit aborted via beforeSerialize callback'); + return this; + } + + var a = this.formToArray(options.semantic); + if (options.data) { + options.extraData = options.data; + for (var n in options.data) { + if(options.data[n] instanceof Array) { + for (var k in options.data[n]) + a.push( { name: n, value: options.data[n][k] } ); + } + else + a.push( { name: n, value: options.data[n] } ); + } + } + + // give pre-submit callback an opportunity to abort the submit + if (options.beforeSubmit && options.beforeSubmit(a, this, options) === false) { + log('ajaxSubmit: submit aborted via beforeSubmit callback'); + return this; + } + + // fire vetoable 'validate' event + this.trigger('form-submit-validate', [a, this, options, veto]); + if (veto.veto) { + log('ajaxSubmit: submit vetoed via form-submit-validate trigger'); + return this; + } + + var q = $.param(a); + + if (options.type.toUpperCase() == 'GET') { + options.url += (options.url.indexOf('?') >= 0 ? '&' : '?') + q; + options.data = null; // data is null for 'get' + } + else + options.data = q; // data is the query string for 'post' + + var $form = this, callbacks = []; + if (options.resetForm) callbacks.push(function() { $form.resetForm(); }); + if (options.clearForm) callbacks.push(function() { $form.clearForm(); }); + + // perform a load on the target only if dataType is not provided + if (!options.dataType && options.target) { + var oldSuccess = options.success || function(){}; + callbacks.push(function(data) { + $(options.target).html(data).each(oldSuccess, arguments); + }); + } + else if (options.success) + callbacks.push(options.success); + + options.success = function(data, status) { + for (var i=0, max=callbacks.length; i < max; i++) + callbacks[i].apply(options, [data, status, $form]); + }; + + // are there files to upload? + var files = $('input:file', this).fieldValue(); + var found = false; + for (var j=0; j < files.length; j++) + if (files[j]) + found = true; + + var multipart = false; +// var mp = 'multipart/form-data'; +// multipart = ($form.attr('enctype') == mp || $form.attr('encoding') == mp); + + // options.iframe allows user to force iframe mode + // 06-NOV-09: now defaulting to iframe mode if file input is detected + if ((files.length && options.iframe !== false) || options.iframe || found || multipart) { + // hack to fix Safari hang (thanks to Tim Molendijk for this) + // see: http://groups.google.com/group/jquery-dev/browse_thread/thread/36395b7ab510dd5d + if (options.closeKeepAlive) + $.get(options.closeKeepAlive, fileUpload); + else + fileUpload(); + } + else + $.ajax(options); + + // fire 'notify' event + this.trigger('form-submit-notify', [this, options]); + return this; + + + // private function for handling file uploads (hat tip to YAHOO!) + function fileUpload() { + var form = $form[0]; + + if ($(':input[name=submit]', form).length) { + alert('Error: Form elements must not be named "submit".'); + return; + } + + var opts = $.extend({}, $.ajaxSettings, options); + var s = $.extend(true, {}, $.extend(true, {}, $.ajaxSettings), opts); + + var id = 'jqFormIO' + (new Date().getTime()); + var $io = $('