├── .gitignore ├── CMakeLists.txt ├── LICENSE ├── bin ├── CMakeLists.txt ├── couchdb.bat.tpl.in ├── couchdb.tpl.in └── couchjs.tpl.in ├── etc ├── CMakeLists.txt ├── couchdb │ ├── CMakeLists.txt │ ├── default.ini.in │ ├── default_dev.ini.in │ ├── local.ini │ └── local_dev.ini.in ├── default │ └── couchdb ├── init │ └── couchdb.tpl.in ├── launchd │ ├── CMakeLists.txt │ └── org.apache.couchdb.plist.tpl.in ├── logrotate.d │ ├── CMakeLists.txt │ └── couchdb.tpl.in └── windows │ ├── README.txt.tpl │ └── couchdb.iss.tpl ├── gen_load.sh ├── license.skip ├── rebar.config ├── rebar.lock ├── src ├── CMakeLists.txt ├── couch_audit │ ├── CMakeLists.txt │ ├── etc │ │ └── audit_descriptor.json │ └── src │ │ ├── couch_audit.app.src │ │ ├── couch_audit.erl │ │ ├── couch_audit_app.erl │ │ ├── couch_audit_sup.erl │ │ └── memcached_calls.erl ├── couch_dcp │ ├── CMakeLists.txt │ ├── include │ │ ├── couch_dcp.hrl │ │ └── couch_dcp_typespecs.hrl │ ├── src │ │ ├── cb_auth_info.erl │ │ ├── couch_dcp.app.src │ │ ├── couch_dcp_client.erl │ │ ├── couch_dcp_consumer.erl │ │ ├── couch_dcp_fake_server.erl │ │ └── couch_dcp_producer.erl │ └── test │ │ ├── 00-prepare.t │ │ ├── 01-load.t │ │ ├── 04-view-groups.t │ │ ├── 05-couch-dcp-client.t │ │ ├── 06-rollback.t │ │ ├── CMakeLists.txt │ │ └── run.tpl ├── couch_index_merger │ ├── CMakeLists.txt │ ├── include │ │ ├── couch_index_merger.hrl │ │ └── couch_view_merger.hrl │ └── src │ │ ├── couch_http_view_streamer.erl │ │ ├── couch_httpd_view_merger.erl │ │ ├── couch_index_app.erl │ │ ├── couch_index_merger.app.src │ │ ├── couch_index_merger.erl │ │ ├── couch_index_merger_validation.erl │ │ ├── couch_index_sup.erl │ │ ├── couch_query_logger.erl │ │ ├── couch_skew.erl │ │ ├── couch_view_merger.erl │ │ └── couch_view_merger_queue.erl ├── couch_set_view │ ├── CMakeLists.txt │ ├── include │ │ └── couch_set_view.hrl │ ├── src │ │ ├── couch_index_barrier.erl │ │ ├── couch_set_view.app.src │ │ ├── couch_set_view.erl │ │ ├── couch_set_view_compactor.erl │ │ ├── couch_set_view_ddoc_cache.erl │ │ ├── couch_set_view_dev.erl │ │ ├── couch_set_view_group.erl │ │ ├── couch_set_view_http.erl │ │ ├── couch_set_view_mapreduce.erl │ │ ├── couch_set_view_updater.erl │ │ ├── couch_set_view_updater_helper.erl │ │ ├── couch_set_view_util.erl │ │ └── mapreduce_view.erl │ └── test │ │ ├── 00-prepare.t │ │ ├── 01-collation.t │ │ ├── 01-headers.t │ │ ├── 01-load.t │ │ ├── 02-old-index-cleanup.t │ │ ├── 03-db-compaction-file-leaks.t │ │ ├── 05-replicas-transfer.t │ │ ├── 06-main-compaction.t │ │ ├── 07-replica-compaction.t │ │ ├── 08-deletes-cleanup.t │ │ ├── 09-deletes-cleanup-many-views.t │ │ ├── 10-updates-cleanup.t │ │ ├── 11-updates-cleanup-many-views.t │ │ ├── 12-errors.t │ │ ├── 13-progressive-cleanup.t │ │ ├── 14-duplicated-keys-per-doc.t │ │ ├── 15-passive-partitions.t │ │ ├── 16-pending-transition.t │ │ ├── 17-unindexable-partitions.t │ │ ├── 18-monitor-partition-updates.t │ │ ├── 19-compaction-retry.t │ │ ├── 20-debug-params.t │ │ ├── 21-updater-cleanup.t │ │ ├── 22-compactor-cleanup.t │ │ ├── 23-replica-group-missing.t │ │ ├── 24-updater-add-more-passive-partitions.t │ │ ├── 25-util-stats.t │ │ ├── 26-multiple-reductions.t │ │ ├── 27-dev-views.t │ │ ├── 28-big-reduce.t │ │ ├── 29-rollback.t │ │ ├── 30-query-fdleaks.t │ │ ├── 31-ryow-query.t │ │ ├── 32-upgrade.t │ │ ├── 33-dcp-duplicates.t │ │ ├── 34-truncate.t │ │ ├── 35-meta-params.t │ │ ├── 35-partition-versions.t │ │ ├── 36-write-guard.t │ │ ├── CMakeLists.txt │ │ ├── couch_set_view_test_util.erl │ │ ├── rebar.lock │ │ └── run.tpl ├── couch_view_parser │ ├── CMakeLists.txt │ ├── couch_view_parser.cc │ ├── couch_view_parser.h │ ├── couch_view_parser_nif.cc │ ├── erl_nif_compat.h │ ├── src │ │ ├── couch_view_parser.app.src │ │ └── couch_view_parser.erl │ ├── test │ │ ├── 01-map-view.t │ │ ├── 02-reduce-view.t │ │ ├── CMakeLists.txt │ │ └── run.tpl │ └── yajl │ │ ├── yajl.c │ │ ├── yajl_alloc.c │ │ ├── yajl_alloc.h │ │ ├── yajl_buf.c │ │ ├── yajl_buf.h │ │ ├── yajl_bytestack.h │ │ ├── yajl_common.h │ │ ├── yajl_encode.c │ │ ├── yajl_encode.h │ │ ├── yajl_gen.c │ │ ├── yajl_gen.h │ │ ├── yajl_lex.c │ │ ├── yajl_lex.h │ │ ├── yajl_parse.h │ │ ├── yajl_parser.c │ │ ├── yajl_parser.h │ │ ├── yajl_tree.c │ │ ├── yajl_tree.h │ │ ├── yajl_version.c │ │ └── yajl_version.h ├── couchdb │ ├── CMakeLists.txt │ ├── couch_db.hrl │ ├── include │ │ ├── couch_api_wrap.hrl │ │ ├── couch_js_functions.hrl │ │ └── couch_replicator.hrl │ ├── priv │ │ ├── CMakeLists.txt │ │ ├── couch_ejson_compare │ │ │ ├── couch_ejson_compare.c │ │ │ ├── couch_ejson_compare.h │ │ │ ├── couch_ejson_compare_utils.c │ │ │ ├── couch_raw_json_compare.c │ │ │ └── erl_nif_compat.h │ │ └── stat_descriptions.cfg.in │ └── src │ │ ├── couch.app.src │ │ ├── couch_app.erl │ │ ├── couch_btree.erl │ │ ├── couch_btree_copy.erl │ │ ├── couch_changes.erl │ │ ├── couch_compaction_daemon.erl │ │ ├── couch_compress.erl │ │ ├── couch_config.erl │ │ ├── couch_config_writer.erl │ │ ├── couch_db.erl │ │ ├── couch_db_frontend.erl │ │ ├── couch_db_update_notifier.erl │ │ ├── couch_db_update_notifier_sup.erl │ │ ├── couch_db_updater.erl │ │ ├── couch_doc.erl │ │ ├── couch_ejson_compare.erl │ │ ├── couch_event_sup.erl │ │ ├── couch_file.erl │ │ ├── couch_file_write_guard.erl │ │ ├── couch_httpd.erl │ │ ├── couch_httpd_db.erl │ │ ├── couch_httpd_external.erl │ │ ├── couch_httpd_misc_handlers.erl │ │ ├── couch_httpd_view.erl │ │ ├── couch_log.erl │ │ ├── couch_os_process.erl │ │ ├── couch_primary_sup.erl │ │ ├── couch_query_servers.erl │ │ ├── couch_ref_counter.erl │ │ ├── couch_rep_sup.erl │ │ ├── couch_replication_manager.erl │ │ ├── couch_replication_notifier.erl │ │ ├── couch_replicator.erl │ │ ├── couch_replicator_utils.erl │ │ ├── couch_replicator_worker.erl │ │ ├── couch_secondary_sup.erl │ │ ├── couch_server.erl │ │ ├── couch_server_sup.erl │ │ ├── couch_system_event.erl │ │ ├── couch_task_status.erl │ │ ├── couch_util.erl │ │ ├── couch_uuids.erl │ │ ├── couch_view.erl │ │ ├── couch_view_compactor.erl │ │ ├── couch_view_group.erl │ │ ├── couch_view_mapreduce.erl │ │ ├── couch_view_updater.erl │ │ ├── couch_work_queue.erl │ │ ├── file2.erl │ │ ├── file_sorter_2.erl │ │ └── json_stream_parse.erl ├── ejson │ ├── CMakeLists.txt │ ├── src │ │ ├── decode.c │ │ ├── ejson.app.src │ │ ├── ejson.c │ │ ├── ejson.erl │ │ ├── ejson.h │ │ ├── encode.c │ │ └── erl_nif_compat.h │ └── yajl │ │ ├── yajl.c │ │ ├── yajl_alloc.c │ │ ├── yajl_alloc.h │ │ ├── yajl_buf.c │ │ ├── yajl_buf.h │ │ ├── yajl_bytestack.h │ │ ├── yajl_common.h │ │ ├── yajl_encode.c │ │ ├── yajl_encode.h │ │ ├── yajl_gen.c │ │ ├── yajl_gen.h │ │ ├── yajl_lex.c │ │ ├── yajl_lex.h │ │ ├── yajl_parse.h │ │ ├── yajl_parser.c │ │ └── yajl_parser.h ├── erlang-oauth │ ├── CMakeLists.txt │ └── src │ │ ├── oauth.app.src │ │ ├── oauth.erl │ │ ├── oauth_hmac_sha1.erl │ │ ├── oauth_http.erl │ │ ├── oauth_plaintext.erl │ │ ├── oauth_rsa_sha1.erl │ │ ├── oauth_unix.erl │ │ └── oauth_uri.erl ├── etap │ ├── CMakeLists.txt │ └── etap.erl ├── lhttpc │ ├── CMakeLists.txt │ ├── include │ │ ├── lhttpc.hrl │ │ └── lhttpc_types.hrl │ └── src │ │ ├── lhttpc.app.src │ │ ├── lhttpc.erl │ │ ├── lhttpc_client.erl │ │ ├── lhttpc_lib.erl │ │ ├── lhttpc_manager.erl │ │ ├── lhttpc_sock.erl │ │ └── lhttpc_sup.erl ├── mapreduce │ ├── CMakeLists.txt │ ├── erl_nif_compat.h │ ├── jsfunctions │ │ ├── CMakeLists.txt │ │ ├── builtin.js │ │ ├── embed_data.c │ │ ├── esprima.js │ │ ├── is_doc_used.js │ │ ├── jsfunctions_data.h │ │ └── unused │ │ │ ├── context.js │ │ │ └── index.js │ ├── mapreduce.cc │ ├── mapreduce.h │ ├── mapreduce_nif.cc │ ├── nif_stl_allocator.h │ ├── src │ │ ├── mapreduce.app.src │ │ └── mapreduce.erl │ └── test │ │ ├── 01-map.t │ │ ├── 02-reduce.t │ │ ├── 03-builtin-functions.t │ │ ├── 04-optimize_doc_load.t │ │ ├── CMakeLists.txt │ │ └── run.tpl ├── mochiweb │ ├── CMakeLists.txt │ ├── include │ │ └── internal.hrl │ └── src │ │ ├── mochifmt.erl │ │ ├── mochifmt_records.erl │ │ ├── mochifmt_std.erl │ │ ├── mochiglobal.erl │ │ ├── mochihex.erl │ │ ├── mochijson.erl │ │ ├── mochijson2.erl │ │ ├── mochilists.erl │ │ ├── mochilogfile2.erl │ │ ├── mochinum.erl │ │ ├── mochitemp.erl │ │ ├── mochiutf8.erl │ │ ├── mochiweb.app.src │ │ ├── mochiweb.erl │ │ ├── mochiweb_acceptor.erl │ │ ├── mochiweb_app.erl │ │ ├── mochiweb_base64url.erl │ │ ├── mochiweb_charref.erl │ │ ├── mochiweb_clock.erl │ │ ├── mochiweb_cookies.erl │ │ ├── mochiweb_cover.erl │ │ ├── mochiweb_echo.erl │ │ ├── mochiweb_headers.erl │ │ ├── mochiweb_html.erl │ │ ├── mochiweb_http.erl │ │ ├── mochiweb_io.erl │ │ ├── mochiweb_mime.erl │ │ ├── mochiweb_multipart.erl │ │ ├── mochiweb_request.erl │ │ ├── mochiweb_request_tests.erl │ │ ├── mochiweb_response.erl │ │ ├── mochiweb_session.erl │ │ ├── mochiweb_socket.erl │ │ ├── mochiweb_socket_server.erl │ │ ├── mochiweb_sup.erl │ │ ├── mochiweb_util.erl │ │ ├── mochiweb_websocket.erl │ │ └── reloader.erl └── snappy │ ├── CMakeLists.txt │ └── src │ ├── erl_nif_compat.h │ ├── snappy.app.src │ ├── snappy.erl │ └── snappy_nif.cc └── test ├── CMakeLists.txt ├── bench ├── CMakeLists.txt ├── bench_marks.js ├── benchbulk.sh └── run.tpl ├── ci ├── build ├── dobuild ├── domain ├── dotest ├── dotiming ├── dowatch ├── kick ├── redo └── skip.txt ├── etap ├── 001-load.t ├── 002-write-guard.t ├── 010-file-basics.t ├── 011-file-headers.t ├── 020-btree-basics.t ├── 021-btree-reductions.t ├── 022-btree-copy.t ├── 023-btree-guided-purge.t ├── 024-btree-guided-fold.t ├── 030-doc-from-json.t ├── 031-doc-to-json.t ├── 032-doc-to-binary-views.t ├── 033-doc-from-binary.t ├── 040-util.t ├── 041-uuid-gen-seq.ini ├── 041-uuid-gen-utc.ini ├── 041-uuid-gen.t ├── 042-work-queue.t ├── 070-couch-db.t ├── 071-couch-db-external-write.t ├── 073-changes.t ├── 080-config-get-set.t ├── 081-config-override.1.ini ├── 081-config-override.2.ini ├── 081-config-override.t ├── 082-config-register.t ├── 083-config-no-files.t ├── 090-task-status.t ├── 100-ref-counter.t ├── 150-invalid-view-seq.t ├── 190-json-stream-parse.t ├── 201-view-group-shutdown.t ├── 202-dev-view-group-shutdown.t ├── CMakeLists.txt ├── misc.erl ├── random_port.ini ├── run.tpl ├── runtest.py ├── test_cfg_register.c ├── test_util.erl.in └── test_web.erl ├── functional_test ├── 00-setup.t ├── 01-node_to_node_encryption_test.t ├── CMakeLists.txt ├── bucket_ops.erl ├── cluster_ops.erl ├── defs.hrl └── run.tpl ├── javascript ├── CMakeLists.txt ├── cli_runner.js ├── couch_http.js └── run.tpl ├── python ├── lib │ └── couchdb │ │ ├── __init__.py │ │ ├── client.py │ │ ├── design.py │ │ ├── http.py │ │ ├── json.py │ │ ├── mapping.py │ │ ├── multipart.py │ │ └── view.py └── set_view │ ├── burst_state_updates.py │ ├── cleanup.py │ ├── common │ └── common.py │ ├── compaction.py │ ├── compaction_transitions.py │ ├── erlang_views.py │ ├── filter_partitions.py │ ├── include_docs.py │ ├── many_partitions.py │ ├── passive_partitions.py │ ├── passive_partitions_update.py │ ├── replica_index.py │ ├── run.py.tpl │ ├── stale.py │ ├── update_cleanup.py │ ├── updates.py │ ├── view_merge.py │ └── view_params.py └── view_server ├── query_server_spec.rb └── run_native_process.es /bin/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | IF (WIN32) 2 | CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/couchdb.bat.tpl.in 3 | ${CMAKE_CURRENT_BINARY_DIR}/couchdb.bat.tpl) 4 | 5 | CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/couchdb.bat.tpl.in 6 | ${CMAKE_CURRENT_BINARY_DIR}/couchdb.bat) 7 | 8 | INSTALL(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/couchdb.bat 9 | DESTINATION bin) 10 | 11 | ELSE (WIN32) 12 | CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/couchjs.tpl.in 13 | ${CMAKE_CURRENT_BINARY_DIR}/couchjs.tpl) 14 | 15 | CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/couchjs.tpl.in 16 | ${CMAKE_CURRENT_BINARY_DIR}/couchjs) 17 | 18 | CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/couchjs.tpl.in 19 | ${CMAKE_CURRENT_BINARY_DIR}/couchjs_dev) 20 | 21 | CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/couchdb.tpl.in 22 | ${CMAKE_CURRENT_BINARY_DIR}/couchdb.tpl) 23 | 24 | CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/couchdb.tpl.in 25 | ${CMAKE_CURRENT_BINARY_DIR}/couchdb) 26 | 27 | INSTALL(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/couchjs 28 | ${CMAKE_CURRENT_BINARY_DIR}/couchdb 29 | DESTINATION bin) 30 | ENDIF (WIN32) 31 | -------------------------------------------------------------------------------- /bin/couchdb.bat.tpl.in: -------------------------------------------------------------------------------- 1 | @echo off 2 | rem Licensed under the Apache License, Version 2.0 (the "License"); you may not 3 | rem use this file except in compliance with the License. You may obtain a copy 4 | rem of the License at 5 | rem 6 | rem http://www.apache.org/licenses/LICENSE-2.0 7 | rem 8 | rem Unless required by applicable law or agreed to in writing, software 9 | rem distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 10 | rem WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 11 | rem License for the specific language governing permissions and limitations 12 | rem under the License. 13 | 14 | setlocal 15 | rem First change to the drive with the erlang bin directory 16 | %~d0 17 | rem then change to the erlang bin directory 18 | cd %~dp0 19 | 20 | rem Allow a different erlang executable (eg, erl) to be used. 21 | rem When using erl instead of werl, server restarts during test runs can fail 22 | rem intermittently. But using erl should be fine for production use. 23 | if "%ERL%x" == "x" set ERL=werl.exe 24 | 25 | echo CouchDB %version% - prepare to relax... 26 | %ERL% -sasl errlog_type error -s couch 27 | -------------------------------------------------------------------------------- /bin/couchjs.tpl.in: -------------------------------------------------------------------------------- 1 | #! /bin/sh -e 2 | 3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may not 4 | # use this file except in compliance with the License. You may obtain a copy of 5 | # the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | # License for the specific language governing permissions and limitations under 13 | # the License. 14 | 15 | SCRIPT_OK=0 16 | SCRIPT_ERROR=1 17 | 18 | DEFAULT_VERSION=170 19 | 20 | basename=`basename $0` 21 | 22 | display_version () { 23 | cat << EOF 24 | $basename - Apache CouchDB ${COUCHDB_VERSION} 25 | 26 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use 27 | this file except in compliance with the License. You may obtain a copy of the 28 | License at 29 | 30 | http://www.apache.org/licenses/LICENSE-2.0 31 | 32 | Unless required by applicable law or agreed to in writing, software distributed 33 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 34 | CONDITIONS OF ANY KIND, either express or implied. See the License for the 35 | specific language governing permissions and limitations under the License. 36 | EOF 37 | } 38 | 39 | display_help () { 40 | cat << EOF 41 | Usage: $basename [FILE] 42 | 43 | The $basename command runs the Apache CouchDB JavaScript interpreter. 44 | 45 | The exit status is 0 for success or 1 for failure. 46 | 47 | Options: 48 | 49 | -h display a short help message and exit 50 | -V display version information and exit 51 | -H install couchjs cURL bindings (only avaiable 52 | if CouchDB was built with cURL available) 53 | 54 | Report bugs at . 55 | EOF 56 | } 57 | 58 | display_error () { 59 | if test -n "$1"; then 60 | echo $1 >&2 61 | fi 62 | echo >&2 63 | echo "Try \`"$basename" -h' for more information." >&2 64 | exit $SCRIPT_ERROR 65 | } 66 | 67 | run_couchjs () { 68 | exec "${CMAKE_INSTALL_PREFIX}/lib/couchdb/bin/couchjs" "$@" 69 | } 70 | 71 | parse_script_option_list () { 72 | set +e 73 | options=`getopt hVH $@` 74 | if test ! $? -eq 0; then 75 | display_error 76 | fi 77 | set -e 78 | eval set -- $options 79 | while [ $# -gt 0 ]; do 80 | case "$1" in 81 | -h) shift; display_help; exit $SCRIPT_OK;; 82 | -V) shift; display_version; exit $SCRIPT_OK;; 83 | --) shift; break;; 84 | *) break;; 85 | esac 86 | done 87 | script_name=`echo "$@" | sed -e 's/.*--[[:blank:]]*//'` 88 | if test -z "$script_name"; then 89 | display_error "You must specify a FILE." 90 | fi 91 | options=`echo "$@" | sed -e 's/--//'` 92 | run_couchjs "$options" 93 | } 94 | 95 | parse_script_option_list $@ 96 | -------------------------------------------------------------------------------- /etc/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | ADD_SUBDIRECTORY(couchdb) 2 | ADD_SUBDIRECTORY(launchd) 3 | ADD_SUBDIRECTORY(logrotate.d) 4 | -------------------------------------------------------------------------------- /etc/couchdb/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/default.ini.in 2 | ${CMAKE_CURRENT_BINARY_DIR}/default.ini) 3 | 4 | CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/default_dev.ini.in 5 | ${CMAKE_CURRENT_BINARY_DIR}/default_dev.ini) 6 | 7 | CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/local_dev.ini.in 8 | ${CMAKE_CURRENT_BINARY_DIR}/local_dev.ini) 9 | 10 | INSTALL(FILES local.ini 11 | ${CMAKE_CURRENT_BINARY_DIR}/default.ini 12 | DESTINATION etc/couchdb) 13 | -------------------------------------------------------------------------------- /etc/couchdb/local.ini: -------------------------------------------------------------------------------- 1 | ; CouchDB Configuration Settings 2 | 3 | ; Custom settings should be made in this file. They will override settings 4 | ; in default.ini, but unlike changes made to default.ini, this file won't be 5 | ; overwritten on server upgrade. 6 | 7 | [couchdb] 8 | ;max_document_size = 4294967296 ; bytes 9 | 10 | [httpd] 11 | ;port = 5984 12 | ;ip4_bind_address = 127.0.0.1 13 | ;ip6_bind_address = ::1 14 | ; Options for the MochiWeb HTTP server. 15 | ;server_options = [{backlog, 128}, {acceptor_pool_size, 16}] 16 | ; For more socket options, consult Erlang's module 'inet' man page. 17 | ;socket_options = [{recbuf, 262144}, {sndbuf, 262144}, {nodelay, true}] 18 | 19 | ; Uncomment next line to trigger basic-auth popup on unauthorized requests. 20 | ;WWW-Authenticate = Basic realm="administrator" 21 | 22 | ; Uncomment next line to set the configuration modification whitelist. Only 23 | ; whitelisted values may be changed via the /_config URLs. To allow the admin 24 | ; to change this value over HTTP, remember to include {httpd,config_whitelist} 25 | ; itself. Excluding it from the list would require editing this file to update 26 | ; the whitelist. 27 | ;config_whitelist = [{httpd,config_whitelist}, {log,level}, {etc,etc}] 28 | 29 | [httpd_global_handlers] 30 | ;_google = {couch_httpd_proxy, handle_proxy_req, <<"http://www.google.com">>} 31 | 32 | [log] 33 | ;level = debug 34 | 35 | [os_daemons] 36 | ; For any commands listed here, CouchDB will attempt to ensure that 37 | ; the process remains alive while CouchDB runs as well as shut them 38 | ; down when CouchDB exits. 39 | ;foo = /path/to/command -with args 40 | 41 | [daemons] 42 | ; enable SSL support by uncommenting the following line and supply the PEM's below. 43 | ; the default ssl port CouchDB listens on is 6984 44 | ; httpsd = {couch_httpd, start_link, [https]} 45 | 46 | [ssl] 47 | ;cert_file = /full/path/to/server_cert.pem 48 | ;key_file = /full/path/to/server_key.pem 49 | 50 | ; To enable Virtual Hosts in CouchDB, add a vhost = path directive. All requests to 51 | ; the Virual Host will be redirected to the path. In the example below all requests 52 | ; to http://example.com/ are redirected to /database. 53 | ; If you run CouchDB on a specific port, include the port number in the vhost: 54 | ; example.com:5984 = /database 55 | 56 | [vhosts] 57 | ;example.com = /database/ 58 | 59 | [update_notification] 60 | ;unique notifier name=/full/path/to/exe -with "cmd line arg" 61 | 62 | ; To create an admin account uncomment the '[admins]' section below and add a 63 | ; line in the format 'username = password'. When you next start CouchDB, it 64 | ; will change the password to a hash (so that your passwords don't linger 65 | ; around in plain-text files). You can add more admin accounts with more 66 | ; 'username = password' lines. Don't forget to restart CouchDB after 67 | ; changing this. 68 | [admins] 69 | ;admin = mysecretpassword 70 | -------------------------------------------------------------------------------- /etc/couchdb/local_dev.ini.in: -------------------------------------------------------------------------------- 1 | ; CouchDB Configuration Settings 2 | 3 | ; Custom settings should be made in this file. They will override settings 4 | ; in default.ini, but unlike changes made to default.ini, this file won't be 5 | ; overwritten on server upgrade. 6 | 7 | [couchdb] 8 | ;max_document_size = 4294967296 ; bytes 9 | 10 | [httpd] 11 | ;port = 5984 12 | ;ip4_bind_address = 127.0.0.1 13 | ;ip6_bind_address = ::1 14 | ; Options for the MochiWeb HTTP server. 15 | ;server_options = [{backlog, 128}, {acceptor_pool_size, 16}] 16 | ; For more socket options, consult Erlang's module 'inet' man page. 17 | ;socket_options = [{recbuf, 262144}, {sndbuf, 262144}, {nodelay, true}] 18 | 19 | ; Uncomment next line to trigger basic-auth popup on unauthorized requests. 20 | ;WWW-Authenticate = Basic realm="administrator" 21 | 22 | ; Uncomment next line to set the configuration modification whitelist. Only 23 | ; whitelisted values may be changed via the /_config URLs. To allow the admin 24 | ; to change this value over HTTP, remember to include {httpd,config_whitelist} 25 | ; itself. Excluding it from the list would require editing this file to update 26 | ; the whitelist. 27 | ;config_whitelist = [{httpd,config_whitelist}, {log,level}, {etc,etc}] 28 | 29 | [httpd_global_handlers] 30 | ;_google = {couch_httpd_proxy, handle_proxy_req, <<"http://www.google.com">>} 31 | 32 | [log] 33 | ;level = debug 34 | 35 | [os_daemons] 36 | ; For any commands listed here, CouchDB will attempt to ensure that 37 | ; the process remains alive while CouchDB runs as well as shut them 38 | ; down when CouchDB exits. 39 | ;foo = /path/to/command -with args 40 | 41 | [daemons] 42 | ; enable SSL support by uncommenting the following line and supply the PEM's below. 43 | ; the default ssl port CouchDB listens on is 6984 44 | ; httpsd = {couch_httpd, start_link, [https]} 45 | 46 | [ssl] 47 | ;cert_file = /full/path/to/server_cert.pem 48 | ;key_file = /full/path/to/server_key.pem 49 | 50 | ; To enable Virtual Hosts in CouchDB, add a vhost = path directive. All requests to 51 | ; the Virual Host will be redirected to the path. In the example below all requests 52 | ; to http://example.com/ are redirected to /database. 53 | ; If you run CouchDB on a specific port, include the port number in the vhost: 54 | ; example.com:5984 = /database 55 | 56 | [vhosts] 57 | ;example.com = /database/ 58 | 59 | [update_notification] 60 | ;unique notifier name=/full/path/to/exe -with "cmd line arg" 61 | 62 | ; To create an admin account uncomment the '[admins]' section below and add a 63 | ; line in the format 'username = password'. When you next start CouchDB, it 64 | ; will change the password to a hash (so that your passwords don't linger 65 | ; around in plain-text files). You can add more admin accounts with more 66 | ; 'username = password' lines. Don't forget to restart CouchDB after 67 | ; changing this. 68 | [admins] 69 | ;admin = mysecretpassword 70 | -------------------------------------------------------------------------------- /etc/default/couchdb: -------------------------------------------------------------------------------- 1 | # Sourced by init script for configuration. 2 | 3 | COUCHDB_USER=couchdb 4 | COUCHDB_STDOUT_FILE=/dev/null 5 | COUCHDB_STDERR_FILE=/dev/null 6 | COUCHDB_RESPAWN_TIMEOUT=5 7 | COUCHDB_OPTIONS= 8 | -------------------------------------------------------------------------------- /etc/launchd/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | IF (APPLE) 2 | 3 | CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/org.apache.couchdb.plist.tpl.in 4 | ${CMAKE_CURRENT_BINARY_DIR}/org.apache.couchdb.plist) 5 | 6 | 7 | INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/org.apache.couchdb.plist 8 | DESTINATION Library/LaunchDaemons ) 9 | 10 | ENDIF(APPLE) 11 | -------------------------------------------------------------------------------- /etc/launchd/org.apache.couchdb.plist.tpl.in: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | Label 7 | org.apache.couchdb 8 | EnvironmentVariables 9 | 10 | HOME 11 | ~ 12 | DYLD_LIBRARY_PATH 13 | /opt/local/lib:$DYLD_LIBRARY_PATH 14 | 15 | ProgramArguments 16 | 17 | ${CMAKE_INSTALL_PREFIX}/bin/couchdb 18 | 19 | UserName 20 | couchdb 21 | StandardOutPath 22 | /dev/null 23 | StandardErrorPath 24 | /dev/null 25 | RunAtLoad 26 | 27 | KeepAlive 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /etc/logrotate.d/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/couchdb.tpl.in 2 | ${CMAKE_CURRENT_BINARY_DIR}/couchdb) 3 | 4 | INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/couchdb 5 | DESTINATION etc/logrotate.d) 6 | -------------------------------------------------------------------------------- /etc/logrotate.d/couchdb.tpl.in: -------------------------------------------------------------------------------- 1 | ${CMAKE_INSTALL_PREFIX}/var/log/couchdb/*.log { 2 | weekly 3 | rotate 10 4 | copytruncate 5 | delaycompress 6 | compress 7 | notifempty 8 | missingok 9 | } 10 | -------------------------------------------------------------------------------- /etc/windows/README.txt.tpl: -------------------------------------------------------------------------------- 1 | This is the README for the %package_name% binary distribution for 2 | Windows, version %version%. 3 | 4 | * Although CouchDB defaults to installing into your "Program Files" directory, 5 | the permissions on the 'var' and 'etc' sub-directories have been adjusted 6 | to allow modification by any authorized user so the couchdb databases, logs 7 | and .ini files can be written. You may like to further restrict these 8 | permissions to only the user who will be running couchdb. 9 | 10 | * The installer offers to install CouchDB as a Windows Service. If you select 11 | this option, the service will run as the "LocalSystem" user and be 12 | configured to start automatically. You can configure the service properties 13 | via the Windows 'Services' applet. 14 | 15 | * To start CouchDB in a "console" environment, execute couchdb.bat in the 16 | 'bin' directory. A shortcut to this batch file should have been installed. 17 | Don't try and start couchdb this way if the service is running - it will 18 | fail. 19 | 20 | * The Futon application which comes with CouchDB does not work with 21 | Internet Explorer - Mozilla Firefox is generally recommended. 22 | 23 | * The test suite is known to fail on Windows due to what appear to be 24 | permissions errors; this is due to couch being unable to delete a 25 | file while it is in use on Windows. 26 | See also https://issues.apache.org/jira/browse/COUCHDB-326 27 | 28 | * Additional help with the Windows support is needed - please contact the 29 | couchdb-dev list if you can help. 30 | -------------------------------------------------------------------------------- /rebar.config: -------------------------------------------------------------------------------- 1 | %% Top-level rebar.config drives the build of all of our applications and 2 | %% dependencies. This configuration file is applied to all applications that we 3 | %% compile. 4 | 5 | {deps, []}. 6 | 7 | {erl_opts, [{src_dirs, ["src"]}, 8 | {i, "src/couchdb"}, 9 | debug_info]}. 10 | {project_app_dirs, ["src/*"]}. 11 | -------------------------------------------------------------------------------- /rebar.lock: -------------------------------------------------------------------------------- 1 | []. 2 | -------------------------------------------------------------------------------- /src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | ADD_SUBDIRECTORY(couchdb) 2 | ADD_SUBDIRECTORY(lhttpc) 3 | ADD_SUBDIRECTORY(couch_set_view) 4 | ADD_SUBDIRECTORY(couch_index_merger) 5 | ADD_SUBDIRECTORY(couch_view_parser) 6 | ADD_SUBDIRECTORY(couch_dcp) 7 | ADD_SUBDIRECTORY(couch_audit) 8 | ADD_SUBDIRECTORY(mapreduce) 9 | ADD_SUBDIRECTORY(snappy) 10 | ADD_SUBDIRECTORY(erlang-oauth) 11 | ADD_SUBDIRECTORY(ejson) 12 | ADD_SUBDIRECTORY(mochiweb) 13 | ADD_SUBDIRECTORY(etap) 14 | -------------------------------------------------------------------------------- /src/couch_audit/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | SET(COUCH_AUDIT_VERSION "1.0.0") 2 | SET(COUCH_AUDIT_PREFIX ${CMAKE_ERL_LIB_INSTALL_PREFIX}/couch_audit-${COUCH_AUDIT_VERSION}) 3 | 4 | INSTALL(DIRECTORY ${COUCHDB_DEFAULT_LIB_DIR}/couch_audit/ebin 5 | DESTINATION ${COUCH_AUDIT_PREFIX}) 6 | -------------------------------------------------------------------------------- /src/couch_audit/src/couch_audit.app.src: -------------------------------------------------------------------------------- 1 | %% @author Couchbase 2 | %% @copyright 2019 Couchbase, Inc. 3 | %% 4 | %% Licensed under the Apache License, Version 2.0 (the "License"); 5 | %% you may not use this file except in compliance with the License. 6 | %% You may obtain a copy of the License at 7 | %% 8 | %% http://www.apache.org/licenses/LICENSE-2.0 9 | %% 10 | %% Unless required by applicable law or agreed to in writing, software 11 | %% distributed under the License is distributed on an "AS IS" BASIS, 12 | %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | %% See the License for the specific language governing permissions and 14 | %% limitations under the License. 15 | 16 | {application, couch_audit, [ 17 | {description, "Couch_audit - decode and encode JSON into/from Erlang terms"}, 18 | {vsn, "0.1.0"}, 19 | {modules, [couch_audit, 20 | couch_audit_app, 21 | couch_audit_sup 22 | ]}, 23 | {registered, []}, 24 | {mod, {couch_audit_app, []}}, 25 | {applications, [kernel, stdlib]}, 26 | {env, []} 27 | ]}. 28 | -------------------------------------------------------------------------------- /src/couch_audit/src/couch_audit_app.erl: -------------------------------------------------------------------------------- 1 | %% @author Couchbase 2 | %% @copyright 2019 Couchbase, Inc. 3 | %% 4 | %% Licensed under the Apache License, Version 2.0 (the "License"); 5 | %% you may not use this file except in compliance with the License. 6 | %% You may obtain a copy of the License at 7 | %% 8 | %% http://www.apache.org/licenses/LICENSE-2.0 9 | %% 10 | %% Unless required by applicable law or agreed to in writing, software 11 | %% distributed under the License is distributed on an "AS IS" BASIS, 12 | %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | %% See the License for the specific language governing permissions and 14 | %% limitations under the License. 15 | %% 16 | %% @doc application for couch_audit 17 | %% 18 | 19 | -module(couch_audit_app). 20 | -behaviour(application). 21 | 22 | %% Application callbacks 23 | -export([start/2, stop/1]). 24 | 25 | %% =================================================================== 26 | %% Application callbacks 27 | %% =================================================================== 28 | 29 | start(_Type, _Args) -> 30 | couch_audit_sup:start_link(). 31 | 32 | stop(_State) -> 33 | ok. 34 | -------------------------------------------------------------------------------- /src/couch_audit/src/couch_audit_sup.erl: -------------------------------------------------------------------------------- 1 | %% @author Couchbase 2 | %% @copyright 2019 Couchbase, Inc. 3 | %% 4 | %% Licensed under the Apache License, Version 2.0 (the "License"); 5 | %% you may not use this file except in compliance with the License. 6 | %% You may obtain a copy of the License at 7 | %% 8 | %% http://www.apache.org/licenses/LICENSE-2.0 9 | %% 10 | %% Unless required by applicable law or agreed to in writing, software 11 | %% distributed under the License is distributed on an "AS IS" BASIS, 12 | %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | %% See the License for the specific language governing permissions and 14 | %% limitations under the License. 15 | %% 16 | %% @doc Supervisor for Audit couchdb 17 | %% 18 | 19 | -module(couch_audit_sup). 20 | 21 | -behaviour(supervisor). 22 | 23 | %% Supervisor callbacks 24 | -export([start_link/0]). 25 | -export([init/1]). 26 | 27 | start_link() -> 28 | supervisor:start_link({local, ?MODULE}, ?MODULE, []). 29 | 30 | init(_Args) -> 31 | {ok, {{one_for_one, 3, 60}, 32 | [{couch_audit, 33 | {couch_audit, start_link, []}, 34 | permanent, 1000, worker, [couch_audit]} 35 | ]}}. 36 | -------------------------------------------------------------------------------- /src/couch_dcp/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | SET(COUCH_DCP_VERSION "1.0.0") 2 | SET(COUCH_DCP_PREFIX ${CMAKE_ERL_LIB_INSTALL_PREFIX}/couch_dcp-${COUCH_DCP_VERSION}) 3 | 4 | INSTALL(DIRECTORY ${COUCHDB_DEFAULT_LIB_DIR}/couch_dcp/ebin 5 | DESTINATION ${COUCH_DCP_PREFIX}) 6 | 7 | ADD_SUBDIRECTORY(test) 8 | -------------------------------------------------------------------------------- /src/couch_dcp/include/couch_dcp_typespecs.hrl: -------------------------------------------------------------------------------- 1 | % Licensed under the Apache License, Version 2.0 (the "License"); you may not 2 | % use this file except in compliance with the License. You may obtain a copy of 3 | % the License at 4 | % 5 | % http://www.apache.org/licenses/LICENSE-2.0 6 | % 7 | % Unless required by applicable law or agreed to in writing, software 8 | % distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 9 | % WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | % License for the specific language governing permissions and limitations under 11 | % the License. 12 | 13 | -type dcp_status() :: non_neg_integer(). 14 | -type dcp_data_type() :: 0..255. 15 | -type request_id() :: non_neg_integer(). 16 | -type size() :: non_neg_integer(). 17 | -type socket() :: port(). 18 | 19 | % Those types are duplicates from couch_set_view.hrl 20 | -type uint64() :: 0..18446744073709551615. 21 | -type partition_id() :: non_neg_integer(). 22 | -type update_seq() :: non_neg_integer(). 23 | -type uuid() :: uint64(). 24 | -type partition_seq() :: {partition_id(), update_seq()}. 25 | % Manipulate via ordsets or orddict, keep it ordered by partition id. 26 | -type partition_seqs() :: ordsets:ordset(partition_seq()). 27 | -type partition_version() :: [{uuid(), update_seq()}]. 28 | % Manipulate via ordsets or orddict, keep it ordered by partition id. 29 | -type partition_versions() :: ordsets:ordset({partition_id(), partition_version()}). 30 | -------------------------------------------------------------------------------- /src/couch_dcp/src/cb_auth_info.erl: -------------------------------------------------------------------------------- 1 | % Licensed under the Apache License, Version 2.0 (the "License"); you may not 2 | % use this file except in compliance with the License. You may obtain a copy of 3 | % the License at 4 | % 5 | % http://www.apache.org/licenses/LICENSE-2.0 6 | % 7 | % Unless required by applicable law or agreed to in writing, software 8 | % distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 9 | % WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | % License for the specific language governing permissions and limitations under 11 | % the License. 12 | 13 | -module(cb_auth_info). 14 | 15 | -export([get/0, trick_dialyzer/1]). 16 | 17 | % This is a fake cb_auth_info service (provided by ns_server in couchbase stack) 18 | 19 | get() -> 20 | % We can't just return `{auth, <<"admin_user">>, <<"admin_passwd">>}` as 21 | % the dialyzer would complain that it never returns 22 | % `{error, server_not_ready}`. Hence there's another function to trick the 23 | % dialyzer. As this module is *only* used to run couchdb without the full 24 | % stack, this is an acceptable trade-off. 25 | trick_dialyzer(auth). 26 | 27 | trick_dialyzer(auth) -> 28 | {auth, <<"admin_user">>, <<"admin_passwd">>}; 29 | trick_dialyzer(error) -> 30 | {error, server_not_ready}. 31 | -------------------------------------------------------------------------------- /src/couch_dcp/src/couch_dcp.app.src: -------------------------------------------------------------------------------- 1 | % Licensed under the Apache License, Version 2.0 (the "License"); you may not 2 | % use this file except in compliance with the License. You may obtain a copy of 3 | % the License at 4 | % 5 | % http://www.apache.org/licenses/LICENSE-2.0 6 | % 7 | % Unless required by applicable law or agreed to in writing, software 8 | % distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 9 | % WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | % License for the specific language governing permissions and limitations under 11 | % the License. 12 | 13 | {application, couch_dcp, [ 14 | {description, "DCP for couch"}, 15 | {vsn, "${COUCHDB_VERSION}"}, 16 | {modules, [ 17 | couch_dcp, 18 | couch_dcp_fake_server 19 | ]}, 20 | {registered, []}, 21 | {applications, [kernel, stdlib]} 22 | ]}. 23 | -------------------------------------------------------------------------------- /src/couch_dcp/test/00-prepare.t: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env escript 2 | %% -*- erlang -*- 3 | %%! -smp enable 4 | 5 | % Licensed under the Apache License, Version 2.0 (the "License"); you may not 6 | % use this file except in compliance with the License. You may obtain a copy of 7 | % the License at 8 | % 9 | % http://www.apache.org/licenses/LICENSE-2.0 10 | % 11 | % Unless required by applicable law or agreed to in writing, software 12 | % distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 13 | % WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14 | % License for the specific language governing permissions and limitations under 15 | % the License. 16 | 17 | main(_) -> 18 | test_util:init_code_path(), 19 | 20 | etap:plan(1), 21 | case (catch test()) of 22 | ok -> 23 | etap:end_tests(); 24 | Other -> 25 | etap:diag(io_lib:format("Test died abnormally: ~p", [Other])), 26 | etap:bail(Other) 27 | end, 28 | ok. 29 | 30 | 31 | test() -> 32 | % Purpose of this test is to create all system databases (_users, _replicator) 33 | % before we start running all other tests in parallel. When the other tests start 34 | % in parallel, if the system databases don't exist, they will all attempt to create 35 | % them, and 1 succeeds while others will fail. 36 | couch_set_view_test_util:start_server(), 37 | {ok, RepDb} = couch_db:open_int(<<"_replicator">>, []), 38 | {ok, _} = couch_db:ensure_full_commit(RepDb), 39 | ok = couch_db:close(RepDb), 40 | etap:is(true, true, "Preparation for parallel testing done"), 41 | couch_set_view_test_util:stop_server(), 42 | ok. 43 | -------------------------------------------------------------------------------- /src/couch_dcp/test/01-load.t: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env escript 2 | %% -*- erlang -*- 3 | %%! -smp enable 4 | 5 | % Licensed under the Apache License, Version 2.0 (the "License"); you may not 6 | % use this file except in compliance with the License. You may obtain a copy of 7 | % the License at 8 | % 9 | % http://www.apache.org/licenses/LICENSE-2.0 10 | % 11 | % Unless required by applicable law or agreed to in writing, software 12 | % distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 13 | % WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14 | % License for the specific language governing permissions and limitations under 15 | % the License. 16 | 17 | main(_) -> 18 | test_util:init_code_path(), 19 | Modules = [ 20 | couch_dcp_client, 21 | couch_dcp_consumer, 22 | couch_dcp_fake_server, 23 | couch_dcp_producer 24 | ], 25 | 26 | etap:plan(length(Modules)), 27 | lists:foreach( 28 | fun(Module) -> 29 | etap:loaded_ok(Module, lists:concat(["Loaded: ", Module])) 30 | end, Modules), 31 | etap:end_tests(). 32 | -------------------------------------------------------------------------------- /src/couch_dcp/test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/run.tpl 2 | ${CMAKE_CURRENT_BINARY_DIR}/run) 3 | 4 | SET(TEST_FILES 5 | 00-prepare.t 6 | 01-load.t 7 | 04-view-groups.t 8 | 05-couch-dcp-client.t 9 | 06-rollback.t) 10 | 11 | FOREACH (it ${TEST_FILES}) 12 | GET_FILENAME_COMPONENT(testname ${it} NAME_WE) 13 | GET_FILENAME_COMPONENT(fullpath ${it} REALPATH) 14 | ADD_TEST(couchdb-couch_dcp-${testname} python3 15 | ${COUCHDB_RUNTEST} -c ${CMAKE_INSTALL_PREFIX}/bin -p ${COUCHDB_BIN_PATH}/src 16 | -m couch_set_view/test -e ${ESCRIPT_EXECUTABLE} -t ${fullpath} --verbose) 17 | ENDFOREACH (it) 18 | -------------------------------------------------------------------------------- /src/couch_dcp/test/run.tpl: -------------------------------------------------------------------------------- 1 | #!/bin/sh -e 2 | 3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may not 4 | # use this file except in compliance with the License. You may obtain a copy of 5 | # the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | # License for the specific language governing permissions and limitations under 13 | # the License. 14 | 15 | BUILDDIR="@abs_top_builddir@" 16 | export ERL_FLAGS="$ERL_FLAGS -pa $BUILDDIR/src/couch_set_view/test/" 17 | 18 | $BUILDDIR/test/etap/run $@ 19 | -------------------------------------------------------------------------------- /src/couch_index_merger/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | SET(COUCH_INDEX_MERGER_VERSION "1.0.0") 2 | SET(COUCH_INDEX_MERGER_PREFIX ${CMAKE_ERL_LIB_INSTALL_PREFIX}/couch_index_merger-${COUCH_INDEX_MERGER_VERSION}) 3 | 4 | INSTALL(DIRECTORY ${COUCHDB_DEFAULT_LIB_DIR}/couch_index_merger/ebin 5 | DESTINATION ${COUCH_INDEX_MERGER_PREFIX}) 6 | -------------------------------------------------------------------------------- /src/couch_index_merger/include/couch_index_merger.hrl: -------------------------------------------------------------------------------- 1 | % Licensed under the Apache License, Version 2.0 (the "License"); you may not 2 | % use this file except in compliance with the License. You may obtain a copy of 3 | % the License at 4 | % 5 | % http://www.apache.org/licenses/LICENSE-2.0 6 | % 7 | % Unless required by applicable law or agreed to in writing, software 8 | % distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 9 | % WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | % License for the specific language governing permissions and limitations under 11 | % the License. 12 | 13 | -define(ON_ERROR_DEFAULT, continue). 14 | 15 | % It's always remote. 16 | -record(merged_index_spec, { 17 | url, 18 | ejson_spec, 19 | ssl_opts = [] 20 | }). 21 | 22 | -record(index_merge, { 23 | indexes = [], % [ #merged_index_spec{} ] 24 | callback, 25 | user_acc, 26 | % parameters that matter only when there are remote views to merge 27 | conn_timeout = nil, % milliseconds 28 | on_error = ?ON_ERROR_DEFAULT, % 'continue' | 'stop' 29 | ddoc_revision = nil, % nil | auto | Revision 30 | http_params = nil, 31 | user_ctx = nil, 32 | make_row_fun = nil, 33 | % extra is for index implementation specific properties 34 | extra = nil, 35 | % captures the timestamp for start of query processing pipeline 36 | start_timer = nil :: erlang:timestamp() | nil 37 | }). 38 | 39 | -record(merge_params, { 40 | index_name, 41 | queue, 42 | collector, 43 | skip = 0, 44 | limit = 10000000000, % Huge number to simplify logic (from couch_db.hrl) 45 | row_acc = [], 46 | % Indexer specific record 47 | extra = nil 48 | }). 49 | 50 | -record(httpdb, { 51 | url, 52 | timeout, 53 | headers = [{"Accept", "application/json"}], 54 | lhttpc_options = [] 55 | }). 56 | 57 | -record(merge_acc, { 58 | fold_fun, 59 | acc 60 | }). 61 | -------------------------------------------------------------------------------- /src/couch_index_merger/include/couch_view_merger.hrl: -------------------------------------------------------------------------------- 1 | % Licensed under the Apache License, Version 2.0 (the "License"); you may not 2 | % use this file except in compliance with the License. You may obtain a copy of 3 | % the License at 4 | % 5 | % http://www.apache.org/licenses/LICENSE-2.0 6 | % 7 | % Unless required by applicable law or agreed to in writing, software 8 | % distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 9 | % WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | % License for the specific language governing permissions and limitations under 11 | % the License. 12 | 13 | -record(view_merge, { 14 | keys = nil, 15 | rereduce_fun = nil 16 | }). 17 | 18 | -record(set_view_spec, { 19 | name, 20 | ddoc_id, 21 | view_name, 22 | partitions, 23 | view = nil, 24 | group = nil, 25 | category = prod :: 'prod' | 'dev' 26 | }). 27 | -------------------------------------------------------------------------------- /src/couch_index_merger/src/couch_index_app.erl: -------------------------------------------------------------------------------- 1 | %% @author Couchbase 2 | %% @copyright 2018 Couchbase, Inc. 3 | %% 4 | %% Licensed under the Apache License, Version 2.0 (the "License"); 5 | %% you may not use this file except in compliance with the License. 6 | %% You may obtain a copy of the License at 7 | %% 8 | %% http://www.apache.org/licenses/LICENSE-2.0 9 | %% 10 | %% Unless required by applicable law or agreed to in writing, software 11 | %% distributed under the License is distributed on an "AS IS" BASIS, 12 | %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | %% See the License for the specific language governing permissions and 14 | %% limitations under the License. 15 | %% 16 | %% @doc application for couch_index_merger 17 | %% 18 | 19 | -module(couch_index_app). 20 | -behaviour(application). 21 | 22 | %% Application callbacks 23 | -export([start/2, stop/1]). 24 | 25 | %% =================================================================== 26 | %% Application callbacks 27 | %% =================================================================== 28 | 29 | start(_Type, _Args) -> 30 | couch_index_sup:start_link(). 31 | 32 | stop(_State) -> 33 | ok. 34 | -------------------------------------------------------------------------------- /src/couch_index_merger/src/couch_index_merger.app.src: -------------------------------------------------------------------------------- 1 | % Licensed under the Apache License, Version 2.0 (the "License"); you may not 2 | % use this file except in compliance with the License. You may obtain a copy of 3 | % the License at 4 | % 5 | % http://www.apache.org/licenses/LICENSE-2.0 6 | % 7 | % Unless required by applicable law or agreed to in writing, software 8 | % distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 9 | % WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | % License for the specific language governing permissions and limitations under 11 | % the License. 12 | 13 | {application, couch_index_merger, [ 14 | {description, "Index merger"}, 15 | {vsn, "${COUCHDB_VERSION}"}, 16 | {modules, [ 17 | couch_index_merger, 18 | couch_view_merger, 19 | couch_view_merger_queue, 20 | couch_httpd_view_merger, 21 | couch_index_app, 22 | couch_index_sup, 23 | couch_query_logger 24 | ]}, 25 | {registered, [ 26 | couch_view_merger_queue, 27 | couch_query_logger 28 | ]}, 29 | {mod, {couch_index_app, []}}, 30 | {applications, [kernel, stdlib]} 31 | ]}. 32 | -------------------------------------------------------------------------------- /src/couch_index_merger/src/couch_index_sup.erl: -------------------------------------------------------------------------------- 1 | %% @author Couchbase 2 | %% @copyright 2018 Couchbase, Inc. 3 | %% 4 | %% Licensed under the Apache License, Version 2.0 (the "License"); 5 | %% you may not use this file except in compliance with the License. 6 | %% You may obtain a copy of the License at 7 | %% 8 | %% http://www.apache.org/licenses/LICENSE-2.0 9 | %% 10 | %% Unless required by applicable law or agreed to in writing, software 11 | %% distributed under the License is distributed on an "AS IS" BASIS, 12 | %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | %% See the License for the specific language governing permissions and 14 | %% limitations under the License. 15 | %% 16 | %% @doc Supervisor for the query volume logger 17 | %% 18 | 19 | -module(couch_index_sup). 20 | -behaviour(supervisor). 21 | 22 | %% Supervisor callbacks 23 | -export([start_link/0]). 24 | -export([init/1]). 25 | 26 | %% =================================================================== 27 | %% Supervisor callbacks 28 | %% =================================================================== 29 | 30 | start_link() -> 31 | supervisor:start_link({local, ?MODULE}, ?MODULE, []). 32 | 33 | init(_Args) -> 34 | {ok, {{one_for_one, 3, 60}, 35 | [{couch_query_logger, 36 | {couch_query_logger, start_link, []}, 37 | permanent, 1000, worker, [couch_query_logger]} 38 | ]}}. 39 | -------------------------------------------------------------------------------- /src/couch_index_merger/src/couch_skew.erl: -------------------------------------------------------------------------------- 1 | % -*- Mode: Erlang; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */ 2 | 3 | % Licensed under the Apache License, Version 2.0 (the "License"); you may not 4 | % use this file except in compliance with the License. You may obtain a copy of 5 | % the License at 6 | % 7 | % http://www.apache.org/licenses/LICENSE-2.0 8 | % 9 | % Unless required by applicable law or agreed to in writing, software 10 | % distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | % WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | % License for the specific language governing permissions and limitations under 13 | % the License. 14 | 15 | -module(couch_skew). 16 | 17 | -export([new/0, size/1, in/3, out/2, min/1]). 18 | 19 | -define(null, []). 20 | 21 | new() -> 22 | ?null. 23 | 24 | size(?null) -> 25 | 0; 26 | size({Sz, _, _, _}) -> 27 | Sz. 28 | 29 | in(X, _LessFun, ?null) -> 30 | {1, X, ?null, ?null}; 31 | in(X, LessFun, A) -> 32 | merge(LessFun, {1, X, ?null, ?null}, A). 33 | 34 | out(LessFun, {_Sz, X, A, B}) -> 35 | {X, merge(LessFun, A, B)}. 36 | 37 | min({_, X, _, _}) -> 38 | X. 39 | 40 | merge(_LessFun, A, ?null) -> 41 | A; 42 | merge(_LessFun, ?null, B) -> 43 | B; 44 | merge(LessFun, {_, Xa, _, _} = A, {_, Xb, _, _} = B) -> 45 | case LessFun(Xa, Xb) of 46 | true -> 47 | join(LessFun, A, B); 48 | false -> 49 | join(LessFun, B, A) 50 | end. 51 | 52 | join(LessFun, {Sz1, X, A, B}, {Sz2, _, _, _} = C) -> 53 | {Sz1 + Sz2, X, B, merge(LessFun, A, C)}. 54 | -------------------------------------------------------------------------------- /src/couch_set_view/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | SET(COUCH_SET_VIEW_VERSION "1.0.0") 2 | SET(COUCH_SET_VIEW_PREFIX ${CMAKE_ERL_LIB_INSTALL_PREFIX}/couch_set_view-${COUCH_SET_VIEW_VERSION}) 3 | 4 | INSTALL(DIRECTORY ${COUCHDB_DEFAULT_LIB_DIR}/couch_set_view/ebin 5 | DESTINATION ${COUCH_SET_VIEW_PREFIX}) 6 | 7 | ADD_SUBDIRECTORY(test) 8 | -------------------------------------------------------------------------------- /src/couch_set_view/src/couch_set_view.app.src: -------------------------------------------------------------------------------- 1 | % Licensed under the Apache License, Version 2.0 (the "License"); you may not 2 | % use this file except in compliance with the License. You may obtain a copy of 3 | % the License at 4 | % 5 | % http://www.apache.org/licenses/LICENSE-2.0 6 | % 7 | % Unless required by applicable law or agreed to in writing, software 8 | % distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 9 | % WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | % License for the specific language governing permissions and limitations under 11 | % the License. 12 | 13 | {application, couch_set_view, [ 14 | {description, "Set views"}, 15 | {vsn, "${COUCHDB_VERSION}"}, 16 | {modules, [ 17 | couch_set_view, 18 | couch_set_view_dev, 19 | couch_set_view_ddoc_cache, 20 | couch_set_view_http, 21 | couch_set_view_group, 22 | couch_set_view_updater, 23 | couch_set_view_updater_helper, 24 | couch_set_view_compactor, 25 | couch_set_view_util, 26 | couch_set_view_mapreduce, 27 | mapreduce_view 28 | ]}, 29 | {registered, []}, 30 | {applications, [kernel, stdlib]} 31 | ]}. 32 | -------------------------------------------------------------------------------- /src/couch_set_view/src/couch_set_view_dev.erl: -------------------------------------------------------------------------------- 1 | % -*- Mode: Erlang; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */ 2 | 3 | % Licensed under the Apache License, Version 2.0 (the "License"); you may not 4 | % use this file except in compliance with the License. You may obtain a copy of 5 | % the License at 6 | % 7 | % http://www.apache.org/licenses/LICENSE-2.0 8 | % 9 | % Unless required by applicable law or agreed to in writing, software 10 | % distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | % WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | % License for the specific language governing permissions and limitations under 13 | % the License. 14 | 15 | % This module is mainly a proxy to couch_set_view. It's specifically 16 | % for development views. 17 | -module(couch_set_view_dev). 18 | 19 | -export([define_group/4, set_active_partition/4]). 20 | 21 | 22 | -include("couch_db.hrl"). 23 | -include_lib("couch_set_view/include/couch_set_view.hrl"). 24 | 25 | 26 | -spec define_group(atom(), binary(), binary(), partition_id()) -> 'ok'. 27 | define_group(Mod, SetName, DDocId, PartitionId) -> 28 | Params = #set_view_params{ 29 | max_partitions = ?MAX_NUM_PARTITIONS, 30 | active_partitions = [PartitionId], 31 | passive_partitions = [], 32 | use_replica_index = false 33 | }, 34 | try 35 | GroupPid = couch_set_view:get_group_pid(Mod, SetName, DDocId, dev), 36 | case couch_set_view_group:define_view(GroupPid, Params) of 37 | ok -> 38 | ok; 39 | Error -> 40 | throw(Error) 41 | end 42 | catch throw:{error, empty_group} -> 43 | ok 44 | end. 45 | 46 | 47 | -spec set_active_partition(atom(), binary(), binary(), partition_id()) -> 'ok'. 48 | set_active_partition(Mod, SetName, DDocId, ActivePartition) -> 49 | try 50 | GroupPid = couch_set_view:get_group_pid(Mod, SetName, DDocId, dev), 51 | CleanupPartitions = 52 | lists:seq(0, ?MAX_NUM_PARTITIONS - 1) -- [ActivePartition], 53 | case couch_set_view_group:set_state( 54 | GroupPid, [ActivePartition], [], CleanupPartitions) of 55 | ok -> 56 | ok; 57 | Error -> 58 | throw(Error) 59 | end 60 | catch throw:{error, empty_group} -> 61 | ok 62 | end. 63 | -------------------------------------------------------------------------------- /src/couch_set_view/test/00-prepare.t: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env escript 2 | %% -*- Mode: Erlang; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */ 3 | %%! -smp enable 4 | 5 | % Licensed under the Apache License, Version 2.0 (the "License"); you may not 6 | % use this file except in compliance with the License. You may obtain a copy of 7 | % the License at 8 | % 9 | % http://www.apache.org/licenses/LICENSE-2.0 10 | % 11 | % Unless required by applicable law or agreed to in writing, software 12 | % distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 13 | % WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14 | % License for the specific language governing permissions and limitations under 15 | % the License. 16 | 17 | main(_) -> 18 | test_util:init_code_path(), 19 | 20 | etap:plan(1), 21 | case (catch test()) of 22 | ok -> 23 | etap:end_tests(); 24 | Other -> 25 | etap:diag(io_lib:format("Test died abnormally: ~p", [Other])), 26 | etap:bail(Other) 27 | end, 28 | ok. 29 | 30 | 31 | test() -> 32 | % Purpose of this test is to create all system databases (_users, _replicator) 33 | % before we start running all other tests in parallel. When the other tests start 34 | % in parallel, if the system databases don't exist, they will all attempt to create 35 | % them, and 1 succeeds while others will fail. 36 | couch_set_view_test_util:start_server(), 37 | {ok, RepDb} = couch_db:open_int(<<"_replicator">>, []), 38 | {ok, _} = couch_db:ensure_full_commit(RepDb), 39 | ok = couch_db:close(RepDb), 40 | etap:is(true, true, "Preparation for parallel testing done"), 41 | couch_set_view_test_util:stop_server(), 42 | ok. 43 | -------------------------------------------------------------------------------- /src/couch_set_view/test/01-load.t: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env escript 2 | %% -*- Mode: Erlang; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */ 3 | %%! -smp enable 4 | 5 | % Licensed under the Apache License, Version 2.0 (the "License"); you may not 6 | % use this file except in compliance with the License. You may obtain a copy of 7 | % the License at 8 | % 9 | % http://www.apache.org/licenses/LICENSE-2.0 10 | % 11 | % Unless required by applicable law or agreed to in writing, software 12 | % distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 13 | % WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14 | % License for the specific language governing permissions and limitations under 15 | % the License. 16 | 17 | main(_) -> 18 | test_util:init_code_path(), 19 | Modules = [ 20 | couch_set_view, 21 | couch_set_view_dev, 22 | couch_set_view_ddoc_cache, 23 | couch_set_view_http, 24 | couch_set_view_group, 25 | couch_set_view_updater, 26 | couch_set_view_updater_helper, 27 | couch_set_view_compactor, 28 | couch_set_view_util, 29 | couch_set_view_mapreduce, 30 | mapreduce_view 31 | ], 32 | 33 | etap:plan(length(Modules)), 34 | lists:foreach( 35 | fun(Module) -> 36 | etap:loaded_ok(Module, lists:concat(["Loaded: ", Module])) 37 | end, Modules), 38 | etap:end_tests(). 39 | -------------------------------------------------------------------------------- /src/couch_set_view/test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/run.tpl 2 | ${CMAKE_CURRENT_BINARY_DIR}/run) 3 | 4 | SET(TEST_FILES 5 | 00-prepare.t 6 | 01-collation.t 7 | 01-headers.t 8 | 01-load.t 9 | #02-old-index-cleanup.t 10 | 03-db-compaction-file-leaks.t 11 | 05-replicas-transfer.t 12 | 06-main-compaction.t 13 | 07-replica-compaction.t 14 | 08-deletes-cleanup.t 15 | 09-deletes-cleanup-many-views.t 16 | 10-updates-cleanup.t 17 | 11-updates-cleanup-many-views.t 18 | 12-errors.t 19 | 13-progressive-cleanup.t 20 | 14-duplicated-keys-per-doc.t 21 | 15-passive-partitions.t 22 | 16-pending-transition.t 23 | 17-unindexable-partitions.t 24 | 18-monitor-partition-updates.t 25 | 19-compaction-retry.t 26 | 20-debug-params.t 27 | 21-updater-cleanup.t 28 | 22-compactor-cleanup.t 29 | 23-replica-group-missing.t 30 | 24-updater-add-more-passive-partitions.t 31 | 25-util-stats.t 32 | 26-multiple-reductions.t 33 | 27-dev-views.t 34 | 28-big-reduce.t 35 | 29-rollback.t 36 | #30-query-fdleaks.t 37 | 31-ryow-query.t 38 | 32-upgrade.t 39 | 33-dcp-duplicates.t 40 | 34-truncate.t 41 | 35-meta-params.t 42 | 35-partition-versions.t 43 | 36-write-guard.t) 44 | 45 | FOREACH (it ${TEST_FILES}) 46 | GET_FILENAME_COMPONENT(testname ${it} NAME_WE) 47 | GET_FILENAME_COMPONENT(fullpath ${it} REALPATH) 48 | ADD_TEST(couchdb-couch_set_view-${testname} python3 49 | ${COUCHDB_RUNTEST} -c ${CMAKE_INSTALL_PREFIX}/bin -p ${COUCHDB_BIN_PATH}/src 50 | -m couch_set_view/test -e ${ESCRIPT_EXECUTABLE} -t ${fullpath} --verbose) 51 | ENDFOREACH (it) 52 | 53 | REBAR(TARGET couch_set_view_test 54 | EUNIT 55 | CLEAN_HOOK couch_set_view_test_realclean 56 | EXTRA_ENV "REBAR_BASE_DIR=${COUCHDB_REBAR_BASE_DIR}") 57 | -------------------------------------------------------------------------------- /src/couch_set_view/test/rebar.lock: -------------------------------------------------------------------------------- 1 | []. 2 | -------------------------------------------------------------------------------- /src/couch_set_view/test/run.tpl: -------------------------------------------------------------------------------- 1 | #!/bin/sh -e 2 | 3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may not 4 | # use this file except in compliance with the License. You may obtain a copy of 5 | # the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | # License for the specific language governing permissions and limitations under 13 | # the License. 14 | 15 | BUILDDIR="@abs_top_builddir@" 16 | export ERL_FLAGS="$ERL_FLAGS -pa $BUILDDIR/src/couch_set_view/test/ -pa $BUILDDIR/src/mapreduce/" 17 | 18 | $BUILDDIR/test/etap/run $@ 19 | -------------------------------------------------------------------------------- /src/couch_view_parser/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | SET(COUCH_VIEW_PARSER_VERSION "1.0") 2 | SET(COUCH_VIEW_PARSER_PREFIX ${CMAKE_ERL_LIB_INSTALL_PREFIX}/couch_view_parser-${COUCH_VIEW_PARSER_VERSION}) 3 | SET(COUCH_VIEW_PARSER_PRIV_PREFIX ${COUCH_VIEW_PARSER_PREFIX}/priv) 4 | 5 | CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/test/run.tpl 6 | ${CMAKE_CURRENT_BINARY_DIR}/test/run) 7 | 8 | CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/src/couch_view_parser.app.src 9 | ${CMAKE_CURRENT_BINARY_DIR}/couch_view_parser.app) 10 | 11 | 12 | SET(COUCH_VIEW_YAJL_SRC couch_view_parser.cc 13 | couch_view_parser_nif.cc 14 | yajl/yajl.c 15 | yajl/yajl_alloc.c 16 | yajl/yajl_buf.c 17 | yajl/yajl_encode.c 18 | yajl/yajl_gen.c 19 | yajl/yajl_lex.c 20 | yajl/yajl_parser.c 21 | yajl/yajl_tree.c 22 | yajl/yajl_version.c) 23 | 24 | INCLUDE_DIRECTORIES(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} 25 | ${Platform_SOURCE_DIR}/include 26 | ${ERLANG_INCLUDE_PATH}) 27 | 28 | 29 | 30 | ADD_LIBRARY(couch_view_parser_nif MODULE ${COUCH_VIEW_YAJL_SRC}) 31 | SET_TARGET_PROPERTIES(couch_view_parser_nif PROPERTIES PREFIX "") 32 | 33 | TARGET_LINK_LIBRARIES(couch_view_parser_nif ${COUCHBASE_UNRESOLVED} 34 | ${COUCHBASE_MATH_LIBS} platform_cbassert_unsanitized) 35 | SET_TARGET_PROPERTIES(couch_view_parser_nif PROPERTIES 36 | LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/priv" 37 | RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/priv" 38 | ) 39 | # couch_view_parser_nif is loaded into Erlang VM (beam.smp) which 40 | # doesn't link the sanitizer libs and hence cannot successfully load 41 | # couch_view_parser_nif if it has the sanitizers enabled. As such 42 | # disable them. 43 | remove_sanitizers(couch_view_parser_nif) 44 | 45 | INSTALL(TARGETS couch_view_parser_nif 46 | DESTINATION ${COUCH_VIEW_PARSER_PRIV_PREFIX}) 47 | INSTALL(DIRECTORY ${COUCHDB_DEFAULT_LIB_DIR}/couch_view_parser/ebin 48 | DESTINATION ${COUCH_VIEW_PARSER_PREFIX}) 49 | 50 | ADD_SUBDIRECTORY(test) 51 | -------------------------------------------------------------------------------- /src/couch_view_parser/src/couch_view_parser.app.src: -------------------------------------------------------------------------------- 1 | {application, couch_view_parser, 2 | [ 3 | {description, "Couch view parser"}, 4 | {vsn, "1.0.0"}, 5 | {registered, []}, 6 | {applications, [ 7 | kernel, 8 | stdlib 9 | ]}, 10 | {env, []}, 11 | {modules, [couch_view_parser]} 12 | ]}. 13 | -------------------------------------------------------------------------------- /src/couch_view_parser/src/couch_view_parser.erl: -------------------------------------------------------------------------------- 1 | % -*- Mode: Erlang; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */ 2 | 3 | %% @copyright 2012 Couchbase, Inc. 4 | %% 5 | %% @author Filipe Manana 6 | %% 7 | %% Licensed under the Apache License, Version 2.0 (the "License"); you may not 8 | %% use this file except in compliance with the License. You may obtain a copy of 9 | %% the License at 10 | %% 11 | %% http://www.apache.org/licenses/LICENSE-2.0 12 | %% 13 | %% Unless required by applicable law or agreed to in writing, software 14 | %% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | %% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | %% License for the specific language governing permissions and limitations under 17 | %% the License. 18 | 19 | -module(couch_view_parser). 20 | 21 | -export([start_context/0, parse_chunk/2, next_state/1]). 22 | 23 | -on_load(init/0). 24 | 25 | -type key_docid() :: {Key::binary(), DocId::binary()}. 26 | -type map_value() :: binary() | 27 | {PartId::binary(), Node::binary(), Value::binary()}. 28 | -type reduce_value() :: binary(). 29 | -type doc_member() :: {'doc', Doc::binary()}. 30 | -type view_row() :: {Key::binary(), reduce_value()} | 31 | {key_docid(), map_value()} | 32 | {key_docid(), map_value(), doc_member()}. 33 | 34 | init() -> 35 | SoName = case code:priv_dir(?MODULE) of 36 | {error, bad_name} -> 37 | case filelib:is_dir(filename:join(["..", "priv"])) of 38 | true -> 39 | filename:join(["..", "priv", "couch_view_parser_nif"]); 40 | false -> 41 | filename:join(["priv", "couch_view_parser_nif"]) 42 | end; 43 | Dir -> 44 | filename:join(Dir, "couch_view_parser_nif") 45 | end, 46 | erlang:load_nif(SoName, 0). 47 | 48 | 49 | -spec start_context() -> {ok, Context::term()}. 50 | start_context() -> 51 | erlang:nif_error(couch_view_parser_nif_not_loaded). 52 | 53 | 54 | -spec parse_chunk(Context::term(), iolist()) -> 'ok' | {'error', term()}. 55 | parse_chunk(_Ctx, _Chunk) -> 56 | erlang:nif_error(couch_view_parser_nif_not_loaded). 57 | 58 | 59 | -spec next_state(Context::term()) -> 60 | {'ok', 'need_more_data'} | 61 | {'ok', 'debug_infos', [{From::binary(), Value::binary()}]} | 62 | {'ok', 'row_count', string()} | 63 | {'ok', 'rows', [view_row()]} | 64 | {'ok', 'errors', [{From::binary(), Reason::binary()}]} | 65 | {'ok', 'done'} | 66 | {'error', term()}. 67 | next_state(_Ctx) -> 68 | erlang:nif_error(couch_view_parser_nif_not_loaded). 69 | -------------------------------------------------------------------------------- /src/couch_view_parser/test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | SET(TEST_FILES 2 | 01-map-view.t 3 | 02-reduce-view.t) 4 | 5 | FOREACH (it ${TEST_FILES}) 6 | GET_FILENAME_COMPONENT(testname ${it} NAME_WE) 7 | GET_FILENAME_COMPONENT(fullpath ${it} REALPATH) 8 | ADD_TEST(couchdb-couch_view_parser-${testname} python3 9 | ${COUCHDB_RUNTEST} -c ${COUCHSTORE_BIN_PATH} -p ${COUCHDB_BIN_PATH}/src 10 | -e ${ESCRIPT_EXECUTABLE} -e ${ESCRIPT_EXECUTABLE} -t ${fullpath} --verbose) 11 | ENDFOREACH (it) 12 | -------------------------------------------------------------------------------- /src/couch_view_parser/test/run.tpl: -------------------------------------------------------------------------------- 1 | #!/bin/sh -e 2 | 3 | # @copyright 2012 Couchbase, Inc. 4 | # 5 | # @author Filipe Manana 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may not 8 | # use this file except in compliance with the License. You may obtain a copy of 9 | # the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations under 17 | # the License. 18 | 19 | BUILDDIR="${CMAKE_CURRENT_BINARY_DIR}" 20 | export ERL_FLAGS="$ERL_FLAGS -pa $BUILDDIR/src/couch_view_parser/test/" 21 | 22 | $BUILDDIR/test/etap/run $@ 23 | -------------------------------------------------------------------------------- /src/couch_view_parser/yajl/yajl_alloc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007-2011, Lloyd Hilaiel 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | /** 18 | * \file yajl_alloc.h 19 | * default memory allocation routines for yajl which use malloc/realloc and 20 | * free 21 | */ 22 | 23 | #include "yajl_alloc.h" 24 | #include 25 | 26 | static void * yajl_internal_malloc(void *ctx, size_t sz) 27 | { 28 | return malloc(sz); 29 | } 30 | 31 | static void * yajl_internal_realloc(void *ctx, void * previous, 32 | size_t sz) 33 | { 34 | return realloc(previous, sz); 35 | } 36 | 37 | static void yajl_internal_free(void *ctx, void * ptr) 38 | { 39 | free(ptr); 40 | } 41 | 42 | void yajl_set_default_alloc_funcs(yajl_alloc_funcs * yaf) 43 | { 44 | yaf->malloc = yajl_internal_malloc; 45 | yaf->free = yajl_internal_free; 46 | yaf->realloc = yajl_internal_realloc; 47 | yaf->ctx = NULL; 48 | } 49 | 50 | -------------------------------------------------------------------------------- /src/couch_view_parser/yajl/yajl_alloc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007-2011, Lloyd Hilaiel 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | /** 18 | * \file yajl_alloc.h 19 | * default memory allocation routines for yajl which use malloc/realloc and 20 | * free 21 | */ 22 | 23 | #ifndef __YAJL_ALLOC_H__ 24 | #define __YAJL_ALLOC_H__ 25 | 26 | #include "yajl/yajl_common.h" 27 | 28 | #define YA_MALLOC(afs, sz) (afs)->malloc((afs)->ctx, (sz)) 29 | #define YA_FREE(afs, ptr) (afs)->free((afs)->ctx, (ptr)) 30 | #define YA_REALLOC(afs, ptr, sz) (afs)->realloc((afs)->ctx, (ptr), (sz)) 31 | 32 | void yajl_set_default_alloc_funcs(yajl_alloc_funcs * yaf); 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /src/couch_view_parser/yajl/yajl_buf.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007-2011, Lloyd Hilaiel 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #ifndef __YAJL_BUF_H__ 18 | #define __YAJL_BUF_H__ 19 | 20 | #include "yajl/yajl_common.h" 21 | #include "yajl_alloc.h" 22 | 23 | /* 24 | * Implementation/performance notes. If this were moved to a header 25 | * only implementation using #define's where possible we might be 26 | * able to sqeeze a little performance out of the guy by killing function 27 | * call overhead. YMMV. 28 | */ 29 | 30 | /** 31 | * yajl_buf is a buffer with exponential growth. the buffer ensures that 32 | * you are always null padded. 33 | */ 34 | typedef struct yajl_buf_t * yajl_buf; 35 | 36 | /* allocate a new buffer */ 37 | yajl_buf yajl_buf_alloc(yajl_alloc_funcs * alloc); 38 | 39 | /* free the buffer */ 40 | void yajl_buf_free(yajl_buf buf); 41 | 42 | /* append a number of bytes to the buffer */ 43 | void yajl_buf_append(yajl_buf buf, const void * data, size_t len); 44 | 45 | /* empty the buffer */ 46 | void yajl_buf_clear(yajl_buf buf); 47 | 48 | /* get a pointer to the beginning of the buffer */ 49 | const unsigned char * yajl_buf_data(yajl_buf buf); 50 | 51 | /* get the length of the buffer */ 52 | size_t yajl_buf_len(yajl_buf buf); 53 | 54 | /* truncate the buffer */ 55 | void yajl_buf_truncate(yajl_buf buf, size_t len); 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /src/couch_view_parser/yajl/yajl_bytestack.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007-2011, Lloyd Hilaiel 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | /* 18 | * A header only implementation of a simple stack of bytes, used in YAJL 19 | * to maintain parse state. 20 | */ 21 | 22 | #ifndef __YAJL_BYTESTACK_H__ 23 | #define __YAJL_BYTESTACK_H__ 24 | 25 | #include "yajl/yajl_common.h" 26 | 27 | #define YAJL_BS_INC 128 28 | 29 | typedef struct yajl_bytestack_t 30 | { 31 | unsigned char * stack; 32 | size_t size; 33 | size_t used; 34 | yajl_alloc_funcs * yaf; 35 | } yajl_bytestack; 36 | 37 | /* initialize a bytestack */ 38 | #define yajl_bs_init(obs, _yaf) { \ 39 | (obs).stack = NULL; \ 40 | (obs).size = 0; \ 41 | (obs).used = 0; \ 42 | (obs).yaf = (_yaf); \ 43 | } \ 44 | 45 | 46 | /* initialize a bytestack */ 47 | #define yajl_bs_free(obs) \ 48 | if ((obs).stack) (obs).yaf->free((obs).yaf->ctx, (obs).stack); 49 | 50 | #define yajl_bs_current(obs) \ 51 | (assert((obs).used > 0), (obs).stack[(obs).used - 1]) 52 | 53 | #define yajl_bs_push(obs, byte) { \ 54 | if (((obs).size - (obs).used) == 0) { \ 55 | (obs).size += YAJL_BS_INC; \ 56 | (obs).stack = (obs).yaf->realloc((obs).yaf->ctx,\ 57 | (void *) (obs).stack, (obs).size);\ 58 | } \ 59 | (obs).stack[((obs).used)++] = (byte); \ 60 | } 61 | 62 | /* removes the top item of the stack, returns nothing */ 63 | #define yajl_bs_pop(obs) { ((obs).used)--; } 64 | 65 | #define yajl_bs_set(obs, byte) \ 66 | (obs).stack[((obs).used) - 1] = (byte); 67 | 68 | 69 | #endif 70 | -------------------------------------------------------------------------------- /src/couch_view_parser/yajl/yajl_common.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007-2011, Lloyd Hilaiel 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #ifndef __YAJL_COMMON_H__ 18 | #define __YAJL_COMMON_H__ 19 | 20 | #include 21 | 22 | #ifdef __cplusplus 23 | extern "C" { 24 | #endif 25 | 26 | #define YAJL_MAX_DEPTH 128 27 | 28 | /* msft dll export gunk. To build a DLL on windows, you 29 | * must define WIN32, YAJL_SHARED, and YAJL_BUILD. To use a shared 30 | * DLL, you must define YAJL_SHARED and WIN32 */ 31 | #if (defined(_WIN32) || defined(WIN32)) && defined(YAJL_SHARED) 32 | # ifdef YAJL_BUILD 33 | # define YAJL_API __declspec(dllexport) 34 | # else 35 | # define YAJL_API __declspec(dllimport) 36 | # endif 37 | #else 38 | # if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 303 39 | # define YAJL_API __attribute__ ((visibility("default"))) 40 | # else 41 | # define YAJL_API 42 | # endif 43 | #endif 44 | 45 | /** pointer to a malloc function, supporting client overriding memory 46 | * allocation routines */ 47 | typedef void * (*yajl_malloc_func)(void *ctx, size_t sz); 48 | 49 | /** pointer to a free function, supporting client overriding memory 50 | * allocation routines */ 51 | typedef void (*yajl_free_func)(void *ctx, void * ptr); 52 | 53 | /** pointer to a realloc function which can resize an allocation. */ 54 | typedef void * (*yajl_realloc_func)(void *ctx, void * ptr, size_t sz); 55 | 56 | /** A structure which can be passed to yajl_*_alloc routines to allow the 57 | * client to specify memory allocation functions to be used. */ 58 | typedef struct 59 | { 60 | /** pointer to a function that can allocate uninitialized memory */ 61 | yajl_malloc_func malloc; 62 | /** pointer to a function that can resize memory allocations */ 63 | yajl_realloc_func realloc; 64 | /** pointer to a function that can free memory allocated using 65 | * reallocFunction or mallocFunction */ 66 | yajl_free_func free; 67 | /** a context pointer that will be passed to above allocation routines */ 68 | void * ctx; 69 | } yajl_alloc_funcs; 70 | 71 | #ifdef __cplusplus 72 | } 73 | #endif 74 | 75 | #endif 76 | -------------------------------------------------------------------------------- /src/couch_view_parser/yajl/yajl_encode.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007-2011, Lloyd Hilaiel 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #ifndef __YAJL_ENCODE_H__ 18 | #define __YAJL_ENCODE_H__ 19 | 20 | #include "yajl_buf.h" 21 | #include "yajl/yajl_gen.h" 22 | 23 | void yajl_string_encode(const yajl_print_t printer, 24 | void * ctx, 25 | const unsigned char * str, 26 | size_t length, 27 | int escape_solidus); 28 | 29 | void yajl_string_decode(yajl_buf buf, const unsigned char * str, 30 | size_t length); 31 | 32 | int yajl_string_validate_utf8(const unsigned char * s, size_t len); 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /src/couch_view_parser/yajl/yajl_parser.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007-2011, Lloyd Hilaiel 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #ifndef __YAJL_PARSER_H__ 18 | #define __YAJL_PARSER_H__ 19 | 20 | #include "yajl/yajl_parse.h" 21 | #include "yajl_bytestack.h" 22 | #include "yajl_buf.h" 23 | #include "yajl_lex.h" 24 | 25 | 26 | typedef enum { 27 | yajl_state_start = 0, 28 | yajl_state_parse_complete, 29 | yajl_state_parse_error, 30 | yajl_state_lexical_error, 31 | yajl_state_map_start, 32 | yajl_state_map_sep, 33 | yajl_state_map_need_val, 34 | yajl_state_map_got_val, 35 | yajl_state_map_need_key, 36 | yajl_state_array_start, 37 | yajl_state_array_got_val, 38 | yajl_state_array_need_val, 39 | yajl_state_got_value, 40 | } yajl_state; 41 | 42 | struct yajl_handle_t { 43 | const yajl_callbacks * callbacks; 44 | void * ctx; 45 | yajl_lexer lexer; 46 | const char * parseError; 47 | /* the number of bytes consumed from the last client buffer, 48 | * in the case of an error this will be an error offset, in the 49 | * case of an error this can be used as the error offset */ 50 | size_t bytesConsumed; 51 | /* temporary storage for decoded strings */ 52 | yajl_buf decodeBuf; 53 | /* a stack of states. access with yajl_state_XXX routines */ 54 | yajl_bytestack stateStack; 55 | /* memory allocation routines */ 56 | yajl_alloc_funcs alloc; 57 | /* bitfield */ 58 | unsigned int flags; 59 | }; 60 | 61 | yajl_status 62 | yajl_do_parse(yajl_handle handle, const unsigned char * jsonText, 63 | size_t jsonTextLen); 64 | 65 | yajl_status 66 | yajl_do_finish(yajl_handle handle); 67 | 68 | unsigned char * 69 | yajl_render_error_string(yajl_handle hand, const unsigned char * jsonText, 70 | size_t jsonTextLen, int verbose); 71 | 72 | /* A little built in integer parsing routine with the same semantics as strtol 73 | * that's unaffected by LOCALE. */ 74 | long long 75 | yajl_parse_integer(const unsigned char *number, unsigned int length); 76 | 77 | 78 | #endif 79 | -------------------------------------------------------------------------------- /src/couch_view_parser/yajl/yajl_version.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int yajl_version(void) 4 | { 5 | return YAJL_VERSION; 6 | } 7 | 8 | -------------------------------------------------------------------------------- /src/couch_view_parser/yajl/yajl_version.h: -------------------------------------------------------------------------------- 1 | #ifndef YAJL_VERSION_H_ 2 | #define YAJL_VERSION_H_ 3 | 4 | #include 5 | 6 | #define YAJL_MAJOR 2 7 | #define YAJL_MINOR 1 8 | #define YAJL_MICRO 0 9 | 10 | #define YAJL_VERSION ((YAJL_MAJOR * 10000) + (YAJL_MINOR * 100) + YAJL_MICRO) 11 | 12 | #ifdef __cplusplus 13 | extern "C" { 14 | #endif 15 | 16 | extern int YAJL_API yajl_version(void); 17 | 18 | #ifdef __cplusplus 19 | } 20 | #endif 21 | 22 | #endif /* YAJL_VERSION_H_ */ 23 | 24 | -------------------------------------------------------------------------------- /src/couchdb/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Todo We should automagically build the module list.. 2 | CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/src/couch.app.src 3 | ${CMAKE_CURRENT_BINARY_DIR}/couch.app) 4 | 5 | #todo remove this.. its currently just to diff the directories 6 | CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/src/couch.app.src 7 | ${CMAKE_CURRENT_BINARY_DIR}/couch.app.tpl) 8 | 9 | SET(COUCH_VERSION "1.2.0a-961ad59-git") 10 | SET(COUCH_LIB_DIR ${CMAKE_ERL_LIB_INSTALL_PREFIX}/couch-${COUCH_VERSION}) 11 | ADD_SUBDIRECTORY(priv) 12 | 13 | INSTALL(DIRECTORY ${COUCHDB_DEFAULT_LIB_DIR}/couch/ebin DESTINATION ${COUCH_LIB_DIR}) 14 | -------------------------------------------------------------------------------- /src/couchdb/include/couch_api_wrap.hrl: -------------------------------------------------------------------------------- 1 | % Licensed under the Apache License, Version 2.0 (the "License"); you may not 2 | % use this file except in compliance with the License. You may obtain a copy of 3 | % the License at 4 | % 5 | % http://www.apache.org/licenses/LICENSE-2.0 6 | % 7 | % Unless required by applicable law or agreed to in writing, software 8 | % distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 9 | % WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | % License for the specific language governing permissions and limitations under 11 | % the License. 12 | 13 | 14 | 15 | -record(httpdb, { 16 | url, 17 | oauth = nil, 18 | headers = [ 19 | {"Accept", "application/json"}, 20 | {"User-Agent", "CouchDB/" ++ couch_server:get_version()} 21 | ], 22 | timeout, % milliseconds 23 | lhttpc_options = [], 24 | retries = 10, 25 | wait = 250, % milliseconds 26 | httpc_pool = nil, 27 | http_connections 28 | }). 29 | 30 | -record(oauth, { 31 | consumer_key, 32 | token, 33 | token_secret, 34 | consumer_secret, 35 | signature_method 36 | }). 37 | -------------------------------------------------------------------------------- /src/couchdb/include/couch_replicator.hrl: -------------------------------------------------------------------------------- 1 | % Licensed under the Apache License, Version 2.0 (the "License"); you may not 2 | % use this file except in compliance with the License. You may obtain a copy of 3 | % the License at 4 | % 5 | % http://www.apache.org/licenses/LICENSE-2.0 6 | % 7 | % Unless required by applicable law or agreed to in writing, software 8 | % distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 9 | % WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | % License for the specific language governing permissions and limitations under 11 | % the License. 12 | 13 | -define(REP_ID_VERSION, 2). 14 | 15 | -record(rep, { 16 | id, 17 | source, 18 | target, 19 | options, 20 | user_ctx, 21 | doc_id 22 | }). 23 | 24 | -record(rep_stats, { 25 | missing_checked = 0, 26 | missing_found = 0, 27 | docs_read = 0, 28 | docs_written = 0, 29 | doc_write_failures = 0 30 | }). 31 | -------------------------------------------------------------------------------- /src/couchdb/priv/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | SET(COUCH_PRIV_PREFIX ${COUCH_LIB_DIR}/priv) 2 | SET(COUCH_PRIV_LIB_PREFIX ${COUCH_PRIV_PREFIX}/lib) 3 | 4 | CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/stat_descriptions.cfg.in 5 | ${CMAKE_CURRENT_BINARY_DIR}/stat_descriptions.cfg) 6 | 7 | INCLUDE_DIRECTORIES(BEFORE ${ICU_INCLUDE_DIR} 8 | ${Platform_SOURCE_DIR}/include 9 | ${ERLANG_INCLUDE_PATH}) 10 | 11 | ADD_DEFINITIONS(-DXP_UNIX) 12 | 13 | SET(COUCH_EJSON_COMPARE_SRC couch_ejson_compare/couch_ejson_compare.c 14 | couch_ejson_compare/couch_raw_json_compare.c 15 | couch_ejson_compare/couch_ejson_compare_utils.c) 16 | 17 | ADD_LIBRARY(couch_ejson_compare MODULE ${COUCH_EJSON_COMPARE_SRC}) 18 | SET_TARGET_PROPERTIES(couch_ejson_compare PROPERTIES PREFIX "") 19 | TARGET_LINK_LIBRARIES(couch_ejson_compare 20 | ${COUCHBASE_UNRESOLVED} 21 | ${ICU_LIBRARIES} 22 | platform_cbassert_unsanitized) 23 | 24 | # couch_ejson_compare is loaded into Erlang VM (beam.smp) which 25 | # doesn't link the sanitizer libs and hence cannot successfully load 26 | # couch_ejson_compare if it has the sanitizers enabled. As such 27 | # disable them. 28 | remove_sanitizers(couch_ejson_compare) 29 | 30 | IF (UNIX) 31 | # It would be nice to share this code from 32 | # tlm/cmake/Modules/CouchbaseRpath.cmake, but unfortunately MacOS has 33 | # a distinction between @loader_path and @executable_path that doesn't 34 | # map to anything on other Unices, so it just has to be special 35 | IF (APPLE) 36 | SET (ORIGIN @loader_path) 37 | ELSE () 38 | SET (ORIGIN \$ORIGIN) 39 | ENDIF () 40 | # map from lib/couchdb/erlang/lib/couch-1.2.0a-961ad59-git/priv/lib to lib/ 41 | SET_TARGET_PROPERTIES(couch_ejson_compare PROPERTIES 42 | INSTALL_RPATH "${ORIGIN}/../../../../../..") 43 | ENDIF () 44 | 45 | INSTALL(TARGETS couch_ejson_compare 46 | DESTINATION ${COUCH_PRIV_LIB_PREFIX}) 47 | 48 | INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/stat_descriptions.cfg 49 | DESTINATION ${COUCH_PRIV_PREFIX}) 50 | -------------------------------------------------------------------------------- /src/couchdb/priv/couch_ejson_compare/couch_ejson_compare.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 3 | * use this file except in compliance with the License. You may obtain a copy of 4 | * the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 10 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 11 | * License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | #ifndef _COUCH_EJSON_COMPARE_H 16 | #define _COUCH_EJSON_COMPARE_H 17 | 18 | #include 19 | #include "erl_nif_compat.h" 20 | #include "unicode/ucol.h" 21 | #include "unicode/ucasemap.h" 22 | 23 | typedef struct { 24 | UCollator **collators; 25 | int collStackTop; 26 | int numCollators; 27 | ErlNifMutex *collMutex; 28 | } couch_ejson_global_ctx_t; 29 | 30 | 31 | typedef struct { 32 | couch_ejson_global_ctx_t *globalCtx; 33 | ErlNifEnv *env; 34 | UCollator *coll; 35 | int error; 36 | const char *errorMsg; 37 | } couch_ejson_ctx_t; 38 | 39 | 40 | int less_json(const char *key1, const char *key2, couch_ejson_ctx_t *ctx); 41 | 42 | void reserve_coll(couch_ejson_ctx_t *); 43 | void release_coll(couch_ejson_ctx_t *); 44 | 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /src/couchdb/priv/couch_ejson_compare/couch_ejson_compare_utils.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 3 | * use this file except in compliance with the License. You may obtain a copy of 4 | * the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 10 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 11 | * License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | #include "couch_ejson_compare.h" 16 | 17 | #ifdef WIN32 18 | #define INLINE_MODIFIER 19 | #else 20 | #define INLINE_MODIFIER __inline 21 | #endif 22 | 23 | #include 24 | 25 | INLINE_MODIFIER void reserve_coll(couch_ejson_ctx_t *ctx) 26 | { 27 | if (ctx->coll == NULL) { 28 | enif_mutex_lock(ctx->globalCtx->collMutex); 29 | cb_assert(ctx->globalCtx->collStackTop < ctx->globalCtx->numCollators); 30 | ctx->coll = ctx->globalCtx->collators[ctx->globalCtx->collStackTop]; 31 | ctx->globalCtx->collStackTop += 1; 32 | enif_mutex_unlock(ctx->globalCtx->collMutex); 33 | } 34 | } 35 | 36 | INLINE_MODIFIER void release_coll(couch_ejson_ctx_t *ctx) 37 | { 38 | if (ctx->coll != NULL) { 39 | enif_mutex_lock(ctx->globalCtx->collMutex); 40 | ctx->globalCtx->collStackTop -= 1; 41 | cb_assert(ctx->globalCtx->collStackTop >= 0); 42 | enif_mutex_unlock(ctx->globalCtx->collMutex); 43 | } 44 | } 45 | 46 | -------------------------------------------------------------------------------- /src/couchdb/priv/stat_descriptions.cfg.in: -------------------------------------------------------------------------------- 1 | %% Licensed under the Apache License, Version 2.0 (the "License"); you may not 2 | %% use this file except in compliance with the License. You may obtain a copy of 3 | %% the License at 4 | %% 5 | %% http://www.apache.org/licenses/LICENSE-2.0 6 | %% 7 | %% Unless required by applicable law or agreed to in writing, software 8 | %% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 9 | %% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | %% License for the specific language governing permissions and limitations under 11 | %% the License. 12 | 13 | % Style guide for descriptions: Start with a lowercase letter & do not add 14 | % a trailing full-stop / period 15 | % Please keep this in alphabetical order 16 | 17 | {couchdb, database_writes, "number of times a database was changed"}. 18 | {couchdb, database_reads, "number of times a document was read from a database"}. 19 | {couchdb, open_databases, "number of open databases"}. 20 | {couchdb, open_os_files, "number of file descriptors CouchDB has open"}. 21 | {couchdb, request_time, "length of a request inside CouchDB without MochiWeb"}. 22 | {couchdb, auth_cache_hits, "number of authentication cache hits"}. 23 | {couchdb, auth_cache_misses, "number of authentication cache misses"}. 24 | 25 | {httpd, bulk_requests, "number of bulk requests"}. 26 | {httpd, requests, "number of HTTP requests"}. 27 | {httpd, temporary_view_reads, "number of temporary view reads"}. 28 | {httpd, view_reads, "number of view reads"}. 29 | {httpd, clients_requesting_changes, "number of clients for continuous _changes"}. 30 | 31 | {httpd_request_methods, 'COPY', "number of HTTP COPY requests"}. 32 | {httpd_request_methods, 'DELETE', "number of HTTP DELETE requests"}. 33 | {httpd_request_methods, 'GET', "number of HTTP GET requests"}. 34 | {httpd_request_methods, 'HEAD', "number of HTTP HEAD requests"}. 35 | {httpd_request_methods, 'POST', "number of HTTP POST requests"}. 36 | {httpd_request_methods, 'PUT', "number of HTTP PUT requests"}. 37 | 38 | {httpd_status_codes, '200', "number of HTTP 200 OK responses"}. 39 | {httpd_status_codes, '201', "number of HTTP 201 Created responses"}. 40 | {httpd_status_codes, '202', "number of HTTP 202 Accepted responses"}. 41 | {httpd_status_codes, '301', "number of HTTP 301 Moved Permanently responses"}. 42 | {httpd_status_codes, '304', "number of HTTP 304 Not Modified responses"}. 43 | {httpd_status_codes, '400', "number of HTTP 400 Bad Request responses"}. 44 | {httpd_status_codes, '401', "number of HTTP 401 Unauthorized responses"}. 45 | {httpd_status_codes, '403', "number of HTTP 403 Forbidden responses"}. 46 | {httpd_status_codes, '404', "number of HTTP 404 Not Found responses"}. 47 | {httpd_status_codes, '405', "number of HTTP 405 Method Not Allowed responses"}. 48 | {httpd_status_codes, '409', "number of HTTP 409 Conflict responses"}. 49 | {httpd_status_codes, '412', "number of HTTP 412 Precondition Failed responses"}. 50 | {httpd_status_codes, '500', "number of HTTP 500 Internal Server Error responses"}. 51 | -------------------------------------------------------------------------------- /src/couchdb/src/couch.app.src: -------------------------------------------------------------------------------- 1 | {application, couch, [ 2 | {description, "Apache CouchDB"}, 3 | {vsn, "${COUCHDB_VERSION}"}, 4 | {modules, [couch_btree,couch_app,couch_btree_copy,couch_changes,couch_compaction_daemon,couch_compress,couch_config,couch_config_writer,couch_db,couch_db_frontend,couch_db_update_notifier,couch_db_update_notifier_sup,couch_db_updater,couch_doc,couch_ejson_compare,couch_event_sup,couch_file,couch_file_write_guard,couch_httpd,couch_httpd_db,couch_httpd_external,couch_httpd_misc_handlers,couch_httpd_view,couch_log,couch_os_process,couch_primary_sup,couch_query_servers,couch_ref_counter,couch_rep_sup,couch_replication_manager,couch_replication_notifier,couch_replicator,couch_replicator_utils,couch_replicator_worker,couch_secondary_sup,couch_server,couch_server_sup,couch_task_status,couch_util,couch_uuids,couch_view,couch_view_compactor,couch_view_group,couch_view_mapreduce,couch_view_updater,couch_work_queue,file2,file_sorter_2,json_stream_parse]}, 5 | {registered, [ 6 | couch_config, 7 | couch_db_update, 8 | couch_db_update_notifier_sup, 9 | couch_httpd, 10 | couch_log, 11 | couch_primary_services, 12 | couch_query_servers, 13 | couch_rep_sup, 14 | couch_secondary_services, 15 | couch_server, 16 | couch_server_sup, 17 | couch_task_status, 18 | couch_view, 19 | couch_file_write_guard 20 | ]}, 21 | {mod, {couch_app, [ 22 | "${CMAKE_INSTALL_PREFIX}/etc/couchdb/default.ini", 23 | "${CMAKE_INSTALL_PREFIX}/etc/couchdb/local.ini" 24 | ]}}, 25 | {applications, [kernel, stdlib]}, 26 | {included_applications, [crypto, sasl, inets, oauth, lhttpc, mochiweb, os_mon]} 27 | ]}. 28 | -------------------------------------------------------------------------------- /src/couchdb/src/couch_app.erl: -------------------------------------------------------------------------------- 1 | % Licensed under the Apache License, Version 2.0 (the "License"); you may not 2 | % use this file except in compliance with the License. You may obtain a copy of 3 | % the License at 4 | % 5 | % http://www.apache.org/licenses/LICENSE-2.0 6 | % 7 | % Unless required by applicable law or agreed to in writing, software 8 | % distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 9 | % WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | % License for the specific language governing permissions and limitations under 11 | % the License. 12 | 13 | -module(couch_app). 14 | 15 | -behaviour(application). 16 | 17 | -include_lib("kernel/include/logger.hrl"). 18 | 19 | -export([start/2, stop/1]). 20 | 21 | start(_Type, DefaultIniFiles) -> 22 | ns_babysitter:setup_server_profile(), 23 | IniFiles = get_ini_files(DefaultIniFiles), 24 | Apps = [ 25 | crypto, asn1, public_key, sasl, inets, oauth, ssl, lhttpc, 26 | xmerl, compiler, syntax_tools, mochiweb, os_mon 27 | ] ++ couch_apps(), 28 | 29 | case start_apps(Apps) of 30 | ok -> 31 | couch_server_sup:start_link(IniFiles); 32 | {error, Reason} -> 33 | {error, Reason} 34 | end. 35 | 36 | stop(_) -> 37 | stop_apps(couch_apps()). 38 | 39 | couch_apps() -> 40 | Apps0 = [couch_set_view, couch_index_merger, mapreduce], 41 | case os:type() of 42 | {win32, _} -> 43 | Apps0; 44 | _ -> 45 | [couch_view_parser | Apps0] 46 | end. 47 | 48 | get_ini_files(Default) -> 49 | case init:get_argument(couch_ini) of 50 | error -> 51 | Default; 52 | {ok, [[]]} -> 53 | Default; 54 | {ok, [Values]} -> 55 | Values 56 | end. 57 | 58 | start_apps([]) -> 59 | ok; 60 | start_apps([App|Rest]) -> 61 | case application:start(App) of 62 | ok -> 63 | start_apps(Rest); 64 | {error, {already_started, App}} -> 65 | start_apps(Rest); 66 | {error, _Reason} when App =:= public_key; App =:= couch_index_merger -> 67 | % ignore on R12B5 68 | % don't crash the node if couch_query_logger fails to start 69 | start_apps(Rest); 70 | {error, Reason} -> 71 | ?LOG_ERROR("Could not start app ~p: ~p~n", [App, Reason]), 72 | {error, {app_would_not_start, App}} 73 | end. 74 | 75 | stop_apps(Apps) -> 76 | do_stop_apps(lists:reverse(Apps)). 77 | 78 | do_stop_apps([]) -> 79 | ok; 80 | do_stop_apps([App|Rest]) -> 81 | case application:stop(App) of 82 | ok -> 83 | stop_apps(Rest); 84 | {error, {not_running, App}} -> 85 | stop_apps(Rest); 86 | {error, Reason} -> 87 | ?LOG_ERROR("Could not stop app ~p: ~p~n", [App, Reason]) 88 | end. 89 | -------------------------------------------------------------------------------- /src/couchdb/src/couch_compress.erl: -------------------------------------------------------------------------------- 1 | % Licensed under the Apache License, Version 2.0 (the "License"); you may not 2 | % use this file except in compliance with the License. You may obtain a copy of 3 | % the License at 4 | % 5 | % http://www.apache.org/licenses/LICENSE-2.0 6 | % 7 | % Unless required by applicable law or agreed to in writing, software 8 | % distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 9 | % WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | % License for the specific language governing permissions and limitations under 11 | % the License. 12 | 13 | -module(couch_compress). 14 | 15 | -export([compress/1, decompress/1]). 16 | 17 | -include("couch_db.hrl"). 18 | 19 | compress(Bin) -> 20 | {ok, CompressedBin} = snappy:compress(Bin), 21 | CompressedBin. 22 | 23 | decompress(Bin) -> 24 | {ok, DecompressedBin} = snappy:decompress(Bin), 25 | DecompressedBin. 26 | 27 | -------------------------------------------------------------------------------- /src/couchdb/src/couch_db_update_notifier.erl: -------------------------------------------------------------------------------- 1 | % Licensed under the Apache License, Version 2.0 (the "License"); you may not 2 | % use this file except in compliance with the License. You may obtain a copy of 3 | % the License at 4 | % 5 | % http://www.apache.org/licenses/LICENSE-2.0 6 | % 7 | % Unless required by applicable law or agreed to in writing, software 8 | % distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 9 | % WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | % License for the specific language governing permissions and limitations under 11 | % the License. 12 | 13 | % 14 | % This causes an OS process to spawned and it is notified every time a database 15 | % is updated. 16 | % 17 | % The notifications are in the form of a the database name sent as a line of 18 | % text to the OS processes stdout. 19 | % 20 | 21 | -module(couch_db_update_notifier). 22 | 23 | -behaviour(gen_event). 24 | 25 | -export([start_link/1, notify/1, sync_notify/1]). 26 | -export([init/1, terminate/2, handle_event/2, handle_call/2, handle_info/2, code_change/3,stop/1]). 27 | 28 | -include("couch_db.hrl"). 29 | 30 | start_link(Exec) -> 31 | couch_event_sup:start_link(couch_db_update, {couch_db_update_notifier, make_ref()}, Exec). 32 | 33 | notify(Event) -> 34 | gen_event:notify(couch_db_update, Event). 35 | 36 | sync_notify(Event) -> 37 | gen_event:sync_notify(couch_db_update, Event). 38 | 39 | stop(Pid) -> 40 | couch_event_sup:stop(Pid). 41 | 42 | init(Exec) when is_list(Exec) -> % an exe 43 | couch_os_process:start_link(Exec, []); 44 | init(Else) -> 45 | {ok, Else}. 46 | 47 | terminate(_Reason, Pid) when is_pid(Pid) -> 48 | couch_os_process:stop(Pid), 49 | ok; 50 | terminate(_Reason, _State) -> 51 | ok. 52 | 53 | handle_event(Event, Fun) when is_function(Fun, 1) -> 54 | Fun(Event), 55 | {ok, Fun}; 56 | handle_event(Event, {Fun, FunAcc}) -> 57 | FunAcc2 = Fun(Event, FunAcc), 58 | {ok, {Fun, FunAcc2}}; 59 | handle_event({EventAtom, DbName}, Pid) -> 60 | Obj = {[{type, list_to_binary(atom_to_list(EventAtom))}, {db, DbName}]}, 61 | ok = couch_os_process:send(Pid, Obj), 62 | {ok, Pid}. 63 | 64 | handle_call(_Request, State) -> 65 | {ok, ok, State}. 66 | 67 | handle_info({'EXIT', Pid, Reason}, Pid) -> 68 | ?LOG_ERROR("Update notification process ~p died: ~p", [Pid, Reason]), 69 | remove_handler; 70 | handle_info({'EXIT', _, _}, Pid) -> 71 | %% the db_update event manager traps exits and forwards this message to all 72 | %% its handlers. Just ignore as it wasn't our os_process that exited. 73 | {ok, Pid}. 74 | 75 | code_change(_OldVsn, State, _Extra) -> 76 | {ok, State}. 77 | -------------------------------------------------------------------------------- /src/couchdb/src/couch_db_update_notifier_sup.erl: -------------------------------------------------------------------------------- 1 | % Licensed under the Apache License, Version 2.0 (the "License"); you may not 2 | % use this file except in compliance with the License. You may obtain a copy of 3 | % the License at 4 | % 5 | % http://www.apache.org/licenses/LICENSE-2.0 6 | % 7 | % Unless required by applicable law or agreed to in writing, software 8 | % distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 9 | % WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | % License for the specific language governing permissions and limitations under 11 | % the License. 12 | 13 | % 14 | % This causes an OS process to spawned and it is notified every time a database 15 | % is updated. 16 | % 17 | % The notifications are in the form of a the database name sent as a line of 18 | % text to the OS processes stdout. 19 | % 20 | 21 | -module(couch_db_update_notifier_sup). 22 | 23 | -behaviour(supervisor). 24 | 25 | -export([start_link/0, init/1, config_change/3]). 26 | 27 | start_link() -> 28 | supervisor:start_link({local, couch_db_update_notifier_sup}, 29 | couch_db_update_notifier_sup, []). 30 | 31 | init([]) -> 32 | ok = couch_config:register(fun ?MODULE:config_change/3), 33 | 34 | UpdateNotifierExes = couch_config:get("update_notification"), 35 | 36 | {ok, 37 | {{one_for_one, 10, 3600}, 38 | lists:map(fun({Name, UpdateNotifierExe}) -> 39 | {Name, 40 | {couch_db_update_notifier, start_link, [UpdateNotifierExe]}, 41 | permanent, 42 | 1000, 43 | supervisor, 44 | [couch_db_update_notifier]} 45 | end, UpdateNotifierExes)}}. 46 | 47 | %% @doc when update_notification configuration changes, terminate the process 48 | %% for that notifier and start a new one with the updated config 49 | config_change("update_notification", Id, Exe) -> 50 | ChildSpec = { 51 | Id, 52 | {couch_db_update_notifier, start_link, [Exe]}, 53 | permanent, 54 | 1000, 55 | supervisor, 56 | [couch_db_update_notifier] 57 | }, 58 | supervisor:terminate_child(couch_db_update_notifier_sup, Id), 59 | supervisor:delete_child(couch_db_update_notifier_sup, Id), 60 | supervisor:start_child(couch_db_update_notifier_sup, ChildSpec). 61 | 62 | -------------------------------------------------------------------------------- /src/couchdb/src/couch_ejson_compare.erl: -------------------------------------------------------------------------------- 1 | % Licensed under the Apache License, Version 2.0 (the "License"); you may not 2 | % use this file except in compliance with the License. You may obtain a copy of 3 | % the License at 4 | % 5 | % http://www.apache.org/licenses/LICENSE-2.0 6 | % 7 | % Unless required by applicable law or agreed to in writing, software 8 | % distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 9 | % WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | % License for the specific language governing permissions and limitations under 11 | % the License. 12 | 13 | -module(couch_ejson_compare). 14 | 15 | -export([less/2, less_json/2]). 16 | 17 | -on_load(init/0). 18 | 19 | -type raw_json() :: binary() | iolist() | {'json', binary()} | {'json', iolist()}. 20 | 21 | 22 | init() -> 23 | LibDir = case couch_config:get("couchdb", "util_driver_dir") of 24 | undefined -> 25 | filename:join(couch_util:priv_dir(), "lib"); 26 | LibDir0 -> 27 | LibDir0 28 | end, 29 | NumScheds = erlang:system_info(schedulers), 30 | erlang:load_nif(filename:join([LibDir, ?MODULE]), NumScheds). 31 | 32 | -spec less(EJsonKey1::term(), EJsonKey2::term()) -> -1 .. 1. 33 | less(A, B) -> 34 | case less_ejson_nif(A, B) of 35 | {error, _Reason} = Error -> 36 | throw(Error); 37 | Else -> 38 | Else 39 | end. 40 | 41 | 42 | -spec less_json(raw_json(), raw_json()) -> -1 .. 1. 43 | less_json(A, B) -> 44 | case less_json_nif(get_raw_json(A), get_raw_json(B)) of 45 | {error, _Reason} = Error -> 46 | throw(Error); 47 | Else -> 48 | Else 49 | end. 50 | 51 | 52 | less_ejson_nif(_, _) -> 53 | erlang:nif_error(ejson_compare_nif_not_loaded). 54 | 55 | 56 | less_json_nif(_, _) -> 57 | erlang:nif_error(ejson_compare_nif_not_loaded). 58 | 59 | 60 | get_raw_json({json, RawJson}) -> 61 | RawJson; 62 | get_raw_json(RawJson) -> 63 | RawJson. 64 | -------------------------------------------------------------------------------- /src/couchdb/src/couch_event_sup.erl: -------------------------------------------------------------------------------- 1 | % Licensed under the Apache License, Version 2.0 (the "License"); you may not 2 | % use this file except in compliance with the License. You may obtain a copy of 3 | % the License at 4 | % 5 | % http://www.apache.org/licenses/LICENSE-2.0 6 | % 7 | % Unless required by applicable law or agreed to in writing, software 8 | % distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 9 | % WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | % License for the specific language governing permissions and limitations under 11 | % the License. 12 | 13 | %% The purpose of this module is to allow event handlers to particpate in Erlang 14 | %% supervisor trees. It provide a monitorable process that crashes if the event 15 | %% handler fails. The process, when shutdown, deregisters the event handler. 16 | 17 | -module(couch_event_sup). 18 | -behaviour(gen_server). 19 | 20 | -include("couch_db.hrl"). 21 | 22 | -export([start_link/3, stop/1]). 23 | -export([init/1, terminate/2, handle_call/3, handle_cast/2, handle_info/2,code_change/3]). 24 | 25 | % 26 | % Instead calling the 27 | % ok = gen_event:add_sup_handler(couch_replication, Handler, Args) 28 | % 29 | % do this: 30 | % {ok, LinkedPid} = couch_event_sup:start_link(couch_replication, Handler, Args) 31 | % 32 | % The benefit is the event is now part of the process tree, and can be 33 | % started, restarted and shutdown consistently like the rest of the server 34 | % components. 35 | % 36 | % And now if the "event" crashes, the supervisor is notified and can restart 37 | % the event handler. 38 | 39 | start_link(EventMgr, EventHandler, Args) -> 40 | gen_server:start_link(couch_event_sup, {EventMgr, EventHandler, Args}, []). 41 | 42 | stop(Pid) -> 43 | gen_server:cast(Pid, stop). 44 | 45 | init({EventMgr, EventHandler, Args}) -> 46 | case gen_event:add_sup_handler(EventMgr, EventHandler, Args) of 47 | ok -> 48 | {ok, {EventMgr, EventHandler}}; 49 | {stop, Error} -> 50 | {stop, Error} 51 | end. 52 | 53 | terminate(_Reason, _State) -> 54 | ok. 55 | 56 | handle_call(_Whatever, _From, State) -> 57 | {reply, ok, State}. 58 | 59 | handle_cast(stop, State) -> 60 | {stop, normal, State}. 61 | 62 | handle_info({gen_event_EXIT, _Handler, Reason}, State) -> 63 | {stop, Reason, State}. 64 | 65 | code_change(_OldVsn, State, _Extra) -> 66 | {ok, State}. 67 | -------------------------------------------------------------------------------- /src/couchdb/src/couch_rep_sup.erl: -------------------------------------------------------------------------------- 1 | % Licensed under the Apache License, Version 2.0 (the "License"); you may not 2 | % use this file except in compliance with the License. You may obtain a copy of 3 | % the License at 4 | % 5 | % http://www.apache.org/licenses/LICENSE-2.0 6 | % 7 | % Unless required by applicable law or agreed to in writing, software 8 | % distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 9 | % WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | % License for the specific language governing permissions and limitations under 11 | % the License. 12 | 13 | -module(couch_rep_sup). 14 | -behaviour(supervisor). 15 | -export([init/1, start_link/0]). 16 | 17 | -include("couch_db.hrl"). 18 | 19 | start_link() -> 20 | supervisor:start_link({local,?MODULE}, ?MODULE, []). 21 | 22 | %%============================================================================= 23 | %% supervisor callbacks 24 | %%============================================================================= 25 | 26 | init([]) -> 27 | {ok, {{one_for_one, 3, 10}, []}}. 28 | 29 | %%============================================================================= 30 | %% internal functions 31 | %%============================================================================= 32 | -------------------------------------------------------------------------------- /src/couchdb/src/couch_replication_notifier.erl: -------------------------------------------------------------------------------- 1 | % Licensed under the Apache License, Version 2.0 (the "License"); you may not 2 | % use this file except in compliance with the License. You may obtain a copy of 3 | % the License at 4 | % 5 | % http://www.apache.org/licenses/LICENSE-2.0 6 | % 7 | % Unless required by applicable law or agreed to in writing, software 8 | % distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 9 | % WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | % License for the specific language governing permissions and limitations under 11 | % the License. 12 | 13 | -module(couch_replication_notifier). 14 | 15 | -behaviour(gen_event). 16 | 17 | % public API 18 | -export([start_link/1, stop/1, notify/1]). 19 | 20 | % gen_event callbacks 21 | -export([init/1, terminate/2, code_change/3]). 22 | -export([handle_event/2, handle_call/2, handle_info/2]). 23 | 24 | -include("couch_db.hrl"). 25 | 26 | start_link(FunAcc) -> 27 | couch_event_sup:start_link(couch_replication, 28 | {couch_replication_notifier, make_ref()}, FunAcc). 29 | 30 | notify(Event) -> 31 | gen_event:notify(couch_replication, Event). 32 | 33 | stop(Pid) -> 34 | couch_event_sup:stop(Pid). 35 | 36 | 37 | init(FunAcc) -> 38 | {ok, FunAcc}. 39 | 40 | terminate(_Reason, _State) -> 41 | ok. 42 | 43 | handle_event(Event, Fun) when is_function(Fun, 1) -> 44 | Fun(Event), 45 | {ok, Fun}; 46 | handle_event(Event, {Fun, Acc}) when is_function(Fun, 2) -> 47 | Acc2 = Fun(Event, Acc), 48 | {ok, {Fun, Acc2}}. 49 | 50 | handle_call(_Msg, State) -> 51 | {ok, ok, State}. 52 | 53 | handle_info(_Msg, State) -> 54 | {ok, State}. 55 | 56 | code_change(_OldVsn, State, _Extra) -> 57 | {ok, State}. 58 | -------------------------------------------------------------------------------- /src/couchdb/src/couch_secondary_sup.erl: -------------------------------------------------------------------------------- 1 | % Licensed under the Apache License, Version 2.0 (the "License"); you may not 2 | % use this file except in compliance with the License. You may obtain a copy of 3 | % the License at 4 | % 5 | % http://www.apache.org/licenses/LICENSE-2.0 6 | % 7 | % Unless required by applicable law or agreed to in writing, software 8 | % distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 9 | % WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | % License for the specific language governing permissions and limitations under 11 | % the License. 12 | 13 | -module(couch_secondary_sup). 14 | -behaviour(supervisor). 15 | -export([init/1, start_link/0]). 16 | 17 | start_link() -> 18 | supervisor:start_link({local,couch_secondary_services}, ?MODULE, []). 19 | 20 | init([]) -> 21 | SecondarySupervisors = [ 22 | {couch_db_update_notifier_sup, 23 | {couch_db_update_notifier_sup, start_link, []}, 24 | permanent, 25 | infinity, 26 | supervisor, 27 | [couch_db_update_notifier_sup]} 28 | ], 29 | Children = SecondarySupervisors ++ [ 30 | begin 31 | {ok, {Module, Fun, Args}} = couch_util:parse_term(SpecStr), 32 | 33 | case Module =:= couch_httpd andalso Fun =:= start_link of 34 | true -> 35 | Sup = self(), 36 | ok = couch_config:register( 37 | fun (S, K) -> 38 | %% Make sure the supervisor has had the 39 | %% chance to handle previous restarts. 40 | supervisor:which_children(Sup), 41 | 42 | couch_httpd:config_change(S, K) 43 | end, Sup); 44 | false -> 45 | ok 46 | end, 47 | {list_to_atom(Name), 48 | {Module, Fun, Args}, 49 | permanent, 50 | brutal_kill, 51 | worker, 52 | [Module]} 53 | end 54 | || {Name, SpecStr} 55 | <- couch_config:get("daemons"), SpecStr /= ""], 56 | {ok, {{one_for_one, 10, 3600}, Children}}. 57 | -------------------------------------------------------------------------------- /src/ejson/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | SET(EJSON_VERSION "0.1.0") 2 | SET(EJSON_PREFIX ${CMAKE_ERL_LIB_INSTALL_PREFIX}/ejson-${EJSON_VERSION}) 3 | SET(EJSON_EBIN_PREFIX ${EJSON_PREFIX}/ebin) 4 | SET(EJSON_PRIV_PREFIX ${EJSON_PREFIX}/priv) 5 | 6 | CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/src/ejson.app.src 7 | ${CMAKE_CURRENT_BINARY_DIR}/ejson.app) 8 | 9 | SET(EJSON_SRC src/ejson.c 10 | src/decode.c 11 | src/encode.c 12 | yajl/yajl_alloc.c 13 | yajl/yajl_buf.c 14 | yajl/yajl.c 15 | yajl/yajl_encode.c 16 | yajl/yajl_gen.c 17 | yajl/yajl_lex.c 18 | yajl/yajl_parser.c) 19 | 20 | INCLUDE_DIRECTORIES(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} 21 | ${ERLANG_INCLUDE_PATH}) 22 | 23 | ADD_LIBRARY(ejson MODULE ${EJSON_SRC}) 24 | SET_TARGET_PROPERTIES(ejson PROPERTIES PREFIX "") 25 | TARGET_LINK_LIBRARIES(ejson ${COUCHBASE_UNRESOLVED}) 26 | SET_TARGET_PROPERTIES(ejson PROPERTIES 27 | LIBRARY_OUTPUT_DIRECTORY "${COUCHDB_DEFAULT_LIB_DIR}/ejson/priv" 28 | RUNTIME_OUTPUT_DIRECTORY "${COUCHDB_DEFAULT_LIB_DIR}/ejson/priv" 29 | ) 30 | # ejson is loaded into Erlang VM (beam.smp) which doesn't 31 | # link the sanitizer libs and hence cannot successfully 32 | # load ejson if it has the sanitizers enabled. As such 33 | # disable them. 34 | remove_sanitizers(ejson) 35 | 36 | INSTALL(TARGETS ejson 37 | DESTINATION ${EJSON_PRIV_PREFIX}) 38 | INSTALL (DIRECTORY ${COUCHDB_DEFAULT_LIB_DIR}/ejson/ebin DESTINATION 39 | ${EJSON_PREFIX}) 40 | -------------------------------------------------------------------------------- /src/ejson/src/ejson.app.src: -------------------------------------------------------------------------------- 1 | {application, ejson, [ 2 | {description, "EJSON - decode and encode JSON into/from Erlang terms"}, 3 | {vsn, "0.1.0"}, 4 | {modules, [ejson]}, 5 | {registered, []}, 6 | {applications, [kernel, stdlib]}, 7 | {env, []} 8 | ]}. 9 | 10 | -------------------------------------------------------------------------------- /src/ejson/src/ejson.c: -------------------------------------------------------------------------------- 1 | #include "erl_nif.h" 2 | #include "ejson.h" 3 | 4 | static int on_load(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM info) 5 | { 6 | return 0; 7 | } 8 | 9 | static int on_reload(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM info) 10 | { 11 | return 0; 12 | } 13 | 14 | static int on_upgrade(ErlNifEnv* env, void** priv_data, void** old_data, ERL_NIF_TERM info) 15 | { 16 | return 0; 17 | } 18 | 19 | static ErlNifFunc nif_funcs[] = 20 | { 21 | {"final_encode", 1, final_encode}, 22 | {"reverse_tokens", 1, reverse_tokens}, 23 | {"validate", 1, validate_doc} 24 | }; 25 | 26 | #if defined (__SUNPRO_C) && (__SUNPRO_C >= 0x550) 27 | __global 28 | #elif defined __GNUC__ 29 | __attribute__ ((visibility("default"))) 30 | #endif 31 | ERL_NIF_INIT(ejson, nif_funcs, &on_load, &on_reload, &on_upgrade, NULL) 32 | -------------------------------------------------------------------------------- /src/ejson/src/ejson.h: -------------------------------------------------------------------------------- 1 | #ifndef EJSON_H 2 | #define EJSON_H 3 | 4 | ERL_NIF_TERM 5 | validate_doc(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); 6 | 7 | ERL_NIF_TERM 8 | reverse_tokens(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); 9 | 10 | ERL_NIF_TERM 11 | final_encode(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /src/ejson/yajl/yajl_alloc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010, Lloyd Hilaiel. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are 6 | * met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in 13 | * the documentation and/or other materials provided with the 14 | * distribution. 15 | * 16 | * 3. Neither the name of Lloyd Hilaiel nor the names of its 17 | * contributors may be used to endorse or promote products derived 18 | * from this software without specific prior written permission. 19 | * 20 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 21 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 22 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 24 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 25 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 28 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 29 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 | * POSSIBILITY OF SUCH DAMAGE. 31 | */ 32 | 33 | /** 34 | * \file yajl_alloc.h 35 | * default memory allocation routines for yajl which use malloc/realloc and 36 | * free 37 | */ 38 | 39 | #include "yajl_alloc.h" 40 | #include 41 | 42 | static void * yajl_internal_malloc(void *ctx, unsigned int sz) 43 | { 44 | return malloc(sz); 45 | } 46 | 47 | static void * yajl_internal_realloc(void *ctx, void * previous, 48 | unsigned int sz) 49 | { 50 | return realloc(previous, sz); 51 | } 52 | 53 | static void yajl_internal_free(void *ctx, void * ptr) 54 | { 55 | free(ptr); 56 | } 57 | 58 | void yajl_set_default_alloc_funcs(yajl_alloc_funcs * yaf) 59 | { 60 | yaf->malloc = yajl_internal_malloc; 61 | yaf->free = yajl_internal_free; 62 | yaf->realloc = yajl_internal_realloc; 63 | yaf->ctx = NULL; 64 | } 65 | 66 | -------------------------------------------------------------------------------- /src/ejson/yajl/yajl_alloc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010, Lloyd Hilaiel. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are 6 | * met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in 13 | * the documentation and/or other materials provided with the 14 | * distribution. 15 | * 16 | * 3. Neither the name of Lloyd Hilaiel nor the names of its 17 | * contributors may be used to endorse or promote products derived 18 | * from this software without specific prior written permission. 19 | * 20 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 21 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 22 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 24 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 25 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 28 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 29 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 | * POSSIBILITY OF SUCH DAMAGE. 31 | */ 32 | 33 | /** 34 | * \file yajl_alloc.h 35 | * default memory allocation routines for yajl which use malloc/realloc and 36 | * free 37 | */ 38 | 39 | #ifndef __YAJL_ALLOC_H__ 40 | #define __YAJL_ALLOC_H__ 41 | 42 | #include "yajl_common.h" 43 | 44 | #define YA_MALLOC(afs, sz) (afs)->malloc((afs)->ctx, (sz)) 45 | #define YA_FREE(afs, ptr) (afs)->free((afs)->ctx, (ptr)) 46 | #define YA_REALLOC(afs, ptr, sz) (afs)->realloc((afs)->ctx, (ptr), (sz)) 47 | 48 | void yajl_set_default_alloc_funcs(yajl_alloc_funcs * yaf); 49 | 50 | #endif 51 | -------------------------------------------------------------------------------- /src/ejson/yajl/yajl_buf.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010, Lloyd Hilaiel. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are 6 | * met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in 13 | * the documentation and/or other materials provided with the 14 | * distribution. 15 | * 16 | * 3. Neither the name of Lloyd Hilaiel nor the names of its 17 | * contributors may be used to endorse or promote products derived 18 | * from this software without specific prior written permission. 19 | * 20 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 21 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 22 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 24 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 25 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 28 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 29 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 | * POSSIBILITY OF SUCH DAMAGE. 31 | */ 32 | 33 | #ifndef __YAJL_BUF_H__ 34 | #define __YAJL_BUF_H__ 35 | 36 | #include "yajl_common.h" 37 | #include "yajl_alloc.h" 38 | 39 | /* 40 | * Implementation/performance notes. If this were moved to a header 41 | * only implementation using #define's where possible we might be 42 | * able to sqeeze a little performance out of the guy by killing function 43 | * call overhead. YMMV. 44 | */ 45 | 46 | /** 47 | * yajl_buf is a buffer with exponential growth. the buffer ensures that 48 | * you are always null padded. 49 | */ 50 | typedef struct yajl_buf_t * yajl_buf; 51 | 52 | /* allocate a new buffer */ 53 | yajl_buf yajl_buf_alloc(yajl_alloc_funcs * alloc); 54 | 55 | /* free the buffer */ 56 | void yajl_buf_free(yajl_buf buf); 57 | 58 | /* append a number of bytes to the buffer */ 59 | void yajl_buf_append(yajl_buf buf, const void * data, unsigned int len); 60 | 61 | /* empty the buffer */ 62 | void yajl_buf_clear(yajl_buf buf); 63 | 64 | /* get a pointer to the beginning of the buffer */ 65 | const unsigned char * yajl_buf_data(yajl_buf buf); 66 | 67 | /* get the length of the buffer */ 68 | unsigned int yajl_buf_len(yajl_buf buf); 69 | 70 | /* truncate the buffer */ 71 | void yajl_buf_truncate(yajl_buf buf, unsigned int len); 72 | 73 | #endif 74 | -------------------------------------------------------------------------------- /src/ejson/yajl/yajl_encode.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010, Lloyd Hilaiel. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are 6 | * met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in 13 | * the documentation and/or other materials provided with the 14 | * distribution. 15 | * 16 | * 3. Neither the name of Lloyd Hilaiel nor the names of its 17 | * contributors may be used to endorse or promote products derived 18 | * from this software without specific prior written permission. 19 | * 20 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 21 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 22 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 24 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 25 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 28 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 29 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 | * POSSIBILITY OF SUCH DAMAGE. 31 | */ 32 | 33 | #ifndef __YAJL_ENCODE_H__ 34 | #define __YAJL_ENCODE_H__ 35 | 36 | #include "yajl_buf.h" 37 | #include "yajl_gen.h" 38 | 39 | void yajl_string_encode2(const yajl_print_t printer, 40 | void * ctx, 41 | const unsigned char * str, 42 | unsigned int length); 43 | 44 | void yajl_string_encode(yajl_buf buf, const unsigned char * str, 45 | unsigned int length); 46 | 47 | void yajl_string_decode(yajl_buf buf, const unsigned char * str, 48 | unsigned int length); 49 | 50 | #endif 51 | -------------------------------------------------------------------------------- /src/erlang-oauth/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | SET(OAUTH_PREFIX ${CMAKE_ERL_LIB_INSTALL_PREFIX}/erlang-oauth) 2 | 3 | CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/src/oauth.app.src 4 | ${CMAKE_CURRENT_BINARY_DIR}/oauth.app) 5 | 6 | INSTALL(DIRECTORY ${COUCHDB_DEFAULT_LIB_DIR}/oauth/ebin 7 | DESTINATION ${OAUTH_PREFIX}) 8 | -------------------------------------------------------------------------------- /src/erlang-oauth/src/oauth.app.src: -------------------------------------------------------------------------------- 1 | {application, oauth, [ 2 | {description, "Erlang OAuth implementation"}, 3 | {vsn, "7d85d3ef"}, 4 | {modules, [ 5 | oauth, 6 | oauth_hmac_sha1, 7 | oauth_http, 8 | oauth_plaintext, 9 | oauth_rsa_sha1, 10 | oauth_unix, 11 | oauth_uri 12 | ]}, 13 | {registered, []}, 14 | {applications, [ 15 | kernel, 16 | stdlib, 17 | crypto, 18 | inets 19 | ]} 20 | ]}. 21 | -------------------------------------------------------------------------------- /src/erlang-oauth/src/oauth_hmac_sha1.erl: -------------------------------------------------------------------------------- 1 | -module(oauth_hmac_sha1). 2 | 3 | -export([signature/3, verify/4]). 4 | 5 | 6 | signature(BaseString, CS, TS) -> 7 | Key = oauth_uri:calate("&", [CS, TS]), 8 | base64:encode_to_string(crypto:mac(hmac, sha, Key, BaseString)). 9 | 10 | verify(Signature, BaseString, CS, TS) -> 11 | Signature =:= signature(BaseString, CS, TS). 12 | -------------------------------------------------------------------------------- /src/erlang-oauth/src/oauth_http.erl: -------------------------------------------------------------------------------- 1 | -module(oauth_http). 2 | 3 | -export([get/1, post/2, response_params/1, response_body/1, response_code/1]). 4 | 5 | 6 | get(URL) -> 7 | request(get, {URL, []}). 8 | 9 | post(URL, Data) -> 10 | request(post, {URL, [], "application/x-www-form-urlencoded", Data}). 11 | 12 | request(Method, Request) -> 13 | httpc:request(Method, Request, [{autoredirect, false}], []). 14 | 15 | response_params(Response) -> 16 | oauth_uri:params_from_string(response_body(Response)). 17 | 18 | response_body({{_, _, _}, _, Body}) -> 19 | Body. 20 | 21 | response_code({{_, Code, _}, _, _}) -> 22 | Code. 23 | -------------------------------------------------------------------------------- /src/erlang-oauth/src/oauth_plaintext.erl: -------------------------------------------------------------------------------- 1 | -module(oauth_plaintext). 2 | 3 | -export([signature/2, verify/3]). 4 | 5 | 6 | signature(CS, TS) -> 7 | oauth_uri:calate("&", [CS, TS]). 8 | 9 | verify(Signature, CS, TS) -> 10 | Signature =:= signature(CS, TS). 11 | -------------------------------------------------------------------------------- /src/erlang-oauth/src/oauth_rsa_sha1.erl: -------------------------------------------------------------------------------- 1 | -module(oauth_rsa_sha1). 2 | 3 | -export([signature/2, verify/3]). 4 | 5 | -include_lib("public_key/include/public_key.hrl"). 6 | 7 | 8 | signature(BaseString, PrivateKeyPath) -> 9 | {ok, [Info]} = public_key:pem_to_der(PrivateKeyPath), 10 | {ok, PrivateKey} = public_key:decode_private_key(Info), 11 | base64:encode_to_string(public_key:sign(list_to_binary(BaseString), PrivateKey)). 12 | 13 | verify(Signature, BaseString, PublicKey) -> 14 | public_key:verify_signature(to_binary(BaseString), sha, base64:decode(Signature), public_key(PublicKey)). 15 | 16 | to_binary(Term) when is_list(Term) -> 17 | list_to_binary(Term); 18 | to_binary(Term) when is_binary(Term) -> 19 | Term. 20 | 21 | public_key(Path) when is_list(Path) -> 22 | {ok, [{cert, DerCert, not_encrypted}]} = public_key:pem_to_der(Path), 23 | {ok, Cert} = public_key:pkix_decode_cert(DerCert, otp), 24 | public_key(Cert); 25 | public_key(#'OTPCertificate'{tbsCertificate=Cert}) -> 26 | public_key(Cert); 27 | public_key(#'OTPTBSCertificate'{subjectPublicKeyInfo=Info}) -> 28 | public_key(Info); 29 | public_key(#'OTPSubjectPublicKeyInfo'{subjectPublicKey=Key}) -> 30 | Key. 31 | -------------------------------------------------------------------------------- /src/erlang-oauth/src/oauth_unix.erl: -------------------------------------------------------------------------------- 1 | -module(oauth_unix). 2 | 3 | -export([timestamp/0]). 4 | 5 | 6 | timestamp() -> 7 | timestamp(calendar:universal_time()). 8 | 9 | timestamp(DateTime) -> 10 | seconds(DateTime) - epoch(). 11 | 12 | epoch() -> 13 | seconds({{1970,1,1},{00,00,00}}). 14 | 15 | seconds(DateTime) -> 16 | calendar:datetime_to_gregorian_seconds(DateTime). 17 | -------------------------------------------------------------------------------- /src/erlang-oauth/src/oauth_uri.erl: -------------------------------------------------------------------------------- 1 | -module(oauth_uri). 2 | 3 | -export([normalize/1, calate/2, encode/1]). 4 | -export([params_from_string/1, params_to_string/1, 5 | params_from_header_string/1, params_to_header_string/1]). 6 | 7 | -import(lists, [concat/1]). 8 | 9 | 10 | normalize(URI) -> uri_string:normalize(URI). 11 | 12 | params_to_header_string(Params) -> 13 | intercalate(", ", [concat([encode(K), "=\"", encode(V), "\""]) || {K, V} <- Params]). 14 | 15 | params_from_header_string(String) -> 16 | [param_from_header_string(Param) || Param <- re:split(String, ",\\s*", [{return, list}]), Param =/= ""]. 17 | 18 | param_from_header_string(Param) -> 19 | [Key, QuotedValue] = string:tokens(Param, "="), 20 | Value = string:substr(QuotedValue, 2, length(QuotedValue) - 2), 21 | {decode(Key), decode(Value)}. 22 | 23 | params_from_string(Params) -> 24 | [param_from_string(Param) || Param <- string:tokens(Params, "&")]. 25 | 26 | param_from_string(Param) -> 27 | list_to_tuple([decode(Value) || Value <- string:tokens(Param, "=")]). 28 | 29 | params_to_string(Params) -> 30 | intercalate("&", [calate("=", [K, V]) || {K, V} <- Params]). 31 | 32 | calate(Sep, Xs) -> 33 | intercalate(Sep, [encode(X) || X <- Xs]). 34 | 35 | intercalate(Sep, Xs) -> 36 | concat(intersperse(Sep, Xs)). 37 | 38 | intersperse(_, []) -> []; 39 | intersperse(_, [X]) -> [X]; 40 | intersperse(Sep, [X|Xs]) -> 41 | [X, Sep|intersperse(Sep, Xs)]. 42 | 43 | -define(is_alphanum(C), C >= $A, C =< $Z; C >= $a, C =< $z; C >= $0, C =< $9). 44 | 45 | encode(Term) when is_integer(Term) -> 46 | integer_to_list(Term); 47 | encode(Term) when is_atom(Term) -> 48 | encode(atom_to_list(Term)); 49 | encode(Term) when is_list(Term) -> 50 | encode(lists:reverse(Term, []), []). 51 | 52 | encode([X | T], Acc) when ?is_alphanum(X); X =:= $-; X =:= $_; X =:= $.; X =:= $~ -> 53 | encode(T, [X | Acc]); 54 | encode([X | T], Acc) -> 55 | NewAcc = [$%, dec2hex(X bsr 4), dec2hex(X band 16#0f) | Acc], 56 | encode(T, NewAcc); 57 | encode([], Acc) -> 58 | Acc. 59 | 60 | decode(Str) when is_list(Str) -> 61 | decode(Str, []). 62 | 63 | decode([$%, A, B | T], Acc) -> 64 | decode(T, [(hex2dec(A) bsl 4) + hex2dec(B) | Acc]); 65 | decode([X | T], Acc) -> 66 | decode(T, [X | Acc]); 67 | decode([], Acc) -> 68 | lists:reverse(Acc, []). 69 | 70 | -compile({inline, [{dec2hex, 1}, {hex2dec, 1}]}). 71 | 72 | dec2hex(N) when N >= 10 andalso N =< 15 -> 73 | N + $A - 10; 74 | dec2hex(N) when N >= 0 andalso N =< 9 -> 75 | N + $0. 76 | 77 | hex2dec(C) when C >= $A andalso C =< $F -> 78 | C - $A + 10; 79 | hex2dec(C) when C >= $0 andalso C =< $9 -> 80 | C - $0. 81 | -------------------------------------------------------------------------------- /src/etap/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | ERL_BUILD(APPNAME "etap" SOURCES etap.erl) 2 | INSTALL(FILES ${outfiles} 3 | DESTINATION ${CMAKE_ERL_LIB_INSTALL_PREFIX}/etap/ebin) 4 | -------------------------------------------------------------------------------- /src/lhttpc/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | SET(LHTTPC_VERSION "1.3") 2 | SET(LHTTPC_INSTALL_PREFIX ${CMAKE_ERL_LIB_INSTALL_PREFIX}/lhttpc-${LHTTPC_VERSION}) 3 | 4 | INSTALL (DIRECTORY ${COUCHDB_DEFAULT_LIB_DIR}/lhttpc/ebin DESTINATION 5 | ${LHTTPC_INSTALL_PREFIX}) -------------------------------------------------------------------------------- /src/lhttpc/include/lhttpc.hrl: -------------------------------------------------------------------------------- 1 | %%% ---------------------------------------------------------------------------- 2 | %%% Copyright (c) 2009, Erlang Training and Consulting Ltd. 3 | %%% All rights reserved. 4 | %%% 5 | %%% Redistribution and use in source and binary forms, with or without 6 | %%% modification, are permitted provided that the following conditions are met: 7 | %%% * Redistributions of source code must retain the above copyright 8 | %%% notice, this list of conditions and the following disclaimer. 9 | %%% * Redistributions in binary form must reproduce the above copyright 10 | %%% notice, this list of conditions and the following disclaimer in the 11 | %%% documentation and/or other materials provided with the distribution. 12 | %%% * Neither the name of Erlang Training and Consulting Ltd. nor the 13 | %%% names of its contributors may be used to endorse or promote products 14 | %%% derived from this software without specific prior written permission. 15 | %%% 16 | %%% THIS SOFTWARE IS PROVIDED BY Erlang Training and Consulting Ltd. ''AS IS'' 17 | %%% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | %%% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 | %%% ARE DISCLAIMED. IN NO EVENT SHALL Erlang Training and Consulting Ltd. BE 20 | %%% LIABLE SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 21 | %%% BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 22 | %%% WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 23 | %%% OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 24 | %%% ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | %%% ---------------------------------------------------------------------------- 26 | 27 | -record(lhttpc_url, { 28 | host :: string(), 29 | port :: integer(), 30 | path :: string(), 31 | is_ssl:: boolean(), 32 | user = "" :: string(), 33 | password = "" :: string() 34 | }). 35 | -------------------------------------------------------------------------------- /src/lhttpc/src/lhttpc.app.src: -------------------------------------------------------------------------------- 1 | %%% ---------------------------------------------------------------------------- 2 | %%% Copyright (c) 2009, Erlang Training and Consulting Ltd. 3 | %%% All rights reserved. 4 | %%% 5 | %%% Redistribution and use in source and binary forms, with or without 6 | %%% modification, are permitted provided that the following conditions are met: 7 | %%% * Redistributions of source code must retain the above copyright 8 | %%% notice, this list of conditions and the following disclaimer. 9 | %%% * Redistributions in binary form must reproduce the above copyright 10 | %%% notice, this list of conditions and the following disclaimer in the 11 | %%% documentation and/or other materials provided with the distribution. 12 | %%% * Neither the name of Erlang Training and Consulting Ltd. nor the 13 | %%% names of its contributors may be used to endorse or promote products 14 | %%% derived from this software without specific prior written permission. 15 | %%% 16 | %%% THIS SOFTWARE IS PROVIDED BY Erlang Training and Consulting Ltd. ''AS IS'' 17 | %%% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | %%% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 | %%% ARE DISCLAIMED. IN NO EVENT SHALL Erlang Training and Consulting Ltd. BE 20 | %%% LIABLE SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 21 | %%% BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 22 | %%% WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 23 | %%% OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 24 | %%% ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | %%% ---------------------------------------------------------------------------- 26 | 27 | %%% @author Oscar Hellström 28 | %%% @doc This is the specification for the lhttpc application. 29 | %%% @end 30 | {application, lhttpc, 31 | [{description, "Lightweight HTTP Client"}, 32 | {vsn, "1.3.0"}, 33 | {modules, []}, 34 | {registered, [lhttpc_manager]}, 35 | {applications, [kernel, stdlib, ssl, crypto]}, 36 | {mod, {lhttpc, nil}}, 37 | {env, [{connection_timeout, 300000}, {pool_size, 50}]} 38 | ]}. 39 | 40 | -------------------------------------------------------------------------------- /src/mapreduce/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | SET(MR_VERSION "1.0") 2 | SET(MR_PREFIX ${CMAKE_ERL_LIB_INSTALL_PREFIX}/mapreduce-${MR_VERSION}) 3 | SET(MR_PRIV_PREFIX ${MR_PREFIX}/priv) 4 | 5 | 6 | CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/test/run.tpl 7 | ${CMAKE_CURRENT_BINARY_DIR}/test/run) 8 | 9 | CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/src/mapreduce.app.src 10 | ${CMAKE_CURRENT_BINARY_DIR}/mapreduce.app) 11 | 12 | 13 | 14 | SET(COUCH_VIEW_MR_SRC mapreduce_nif.cc 15 | mapreduce.cc 16 | ${CMAKE_CURRENT_BINARY_DIR}/jsfunctions/jsfunctions_data.cc) 17 | 18 | INCLUDE_DIRECTORIES(BEFORE ${V8_INCLUDE_DIR} 19 | ${ERLANG_INCLUDE_PATH}) 20 | 21 | ADD_LIBRARY(mapreduce_nif MODULE ${COUCH_VIEW_MR_SRC}) 22 | SET_TARGET_PROPERTIES(mapreduce_nif PROPERTIES PREFIX "") 23 | 24 | TARGET_LINK_LIBRARIES(mapreduce_nif ${COUCHBASE_UNRESOLVED} 25 | ${V8_LIBRARIES} 26 | ${COUCHBASE_MATH_LIBS}) 27 | SET_TARGET_PROPERTIES(mapreduce_nif PROPERTIES 28 | LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/priv" 29 | RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/priv" 30 | ) 31 | # mapreduce_nif is loaded into Erlang VM (beam.smp) which doesn't 32 | # link the sanitizer libs and hence cannot successfully 33 | # load mapreduce_nif if it has the sanitizers enabled. As such 34 | # disable them. 35 | remove_sanitizers(mapreduce_nif) 36 | 37 | IF (UNIX) 38 | # It would be nice to share this code from 39 | # tlm/cmake/Modules/CouchbaseRpath.cmake, but unfortunately MacOS has 40 | # a distinction between @loader_path and @executable_path that doesn't 41 | # map to anything on other Unices, so it just has to be special 42 | IF (APPLE) 43 | SET (ORIGIN @loader_path) 44 | ELSE () 45 | SET (ORIGIN \$ORIGIN) 46 | ENDIF () 47 | # map from lib/couchdb/erlang/lib/mapreduce-1.0/priv/ to lib/ 48 | SET_TARGET_PROPERTIES(mapreduce_nif PROPERTIES 49 | INSTALL_RPATH "${ORIGIN}/../../../../..") 50 | ENDIF () 51 | 52 | 53 | INSTALL(TARGETS mapreduce_nif 54 | DESTINATION ${MR_PRIV_PREFIX}) 55 | INSTALL(DIRECTORY ${COUCHDB_DEFAULT_LIB_DIR}/mapreduce/ebin 56 | DESTINATION ${MR_PREFIX}) 57 | 58 | ADD_SUBDIRECTORY(test) 59 | ADD_SUBDIRECTORY(jsfunctions) 60 | -------------------------------------------------------------------------------- /src/mapreduce/jsfunctions/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | SET(ESPRIMA_FILE ${CMAKE_CURRENT_SOURCE_DIR}/esprima.js) 2 | SET(UNUSED_CONTEXT_FILE ${CMAKE_CURRENT_SOURCE_DIR}/unused/context.js) 3 | SET(UNUSED_INDEX_FILE ${CMAKE_CURRENT_SOURCE_DIR}/unused/index.js) 4 | SET(IS_DOC_USED_FILE ${CMAKE_CURRENT_SOURCE_DIR}/is_doc_used.js) 5 | 6 | TRY_RUN(EMBED_DATA_EXITCODE EMBED_DATA_COMPILED 7 | ${CMAKE_CURRENT_BINARY_DIR} 8 | ${CMAKE_CURRENT_SOURCE_DIR}/embed_data.c 9 | RUN_OUTPUT_VARIABLE JSFUNCTION_CONTENTS 10 | ARGS ${ESPRIMA_FILE} ${UNUSED_CONTEXT_FILE} ${UNUSED_INDEX_FILE} 11 | ${IS_DOC_USED_FILE} ${BUILTIN_JS_FILE}) 12 | 13 | STRING(REPLACE "\r" "\n" JSFUNCTION_CONTENTS "${JSFUNCTION_CONTENTS}") 14 | FILE(WRITE ${CMAKE_CURRENT_BINARY_DIR}/jsfunctions_data.cc "${JSFUNCTION_CONTENTS}") 15 | -------------------------------------------------------------------------------- /src/mapreduce/jsfunctions/builtin.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @copyright 2016 Couchbase, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | **/ 16 | 17 | function sum(values) { 18 | var sum = 0; 19 | for (var i = 0; i < values.length; ++i) { 20 | sum += values[i]; 21 | } 22 | return sum; 23 | }; 24 | 25 | // I wish it was on the prototype, but that will require bigger 26 | // C changes as adding to the date prototype should be done on 27 | // process launch. The code you see here may be faster, but it 28 | // is less JavaScripty. 29 | // "Date.prototype.toArray = (function() {" 30 | function dateToArray(date) { 31 | date = date.getUTCDate ? date : new Date(date); 32 | return isFinite(date.valueOf()) ? 33 | [date.getUTCFullYear(), 34 | (date.getUTCMonth() + 1), 35 | date.getUTCDate(), 36 | date.getUTCHours(), 37 | date.getUTCMinutes(), 38 | date.getUTCSeconds()] : null; 39 | }; 40 | 41 | function decodeBase64(b64) { 42 | var i, j, l, tmp, scratch, arr = []; 43 | var lookup = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; 44 | if (typeof b64 !== 'string') { 45 | throw 'Input is not a string'; 46 | } 47 | if (b64.length % 4 > 0) { 48 | throw 'Invalid base64 source.'; 49 | } 50 | scratch = b64.indexOf('='); 51 | scratch = scratch > 0 ? b64.length - scratch : 0; 52 | l = scratch > 0 ? b64.length - 4 : b64.length; 53 | for (i = 0, j = 0; i < l; i += 4, j += 3) { 54 | tmp = (lookup.indexOf(b64[i]) << 18) | (lookup.indexOf(b64[i + 1]) << 12); 55 | tmp |= (lookup.indexOf(b64[i + 2]) << 6) | lookup.indexOf(b64[i + 3]); 56 | arr.push((tmp & 0xFF0000) >> 16); 57 | arr.push((tmp & 0xFF00) >> 8); 58 | arr.push(tmp & 0xFF); 59 | } 60 | if (scratch === 2) { 61 | tmp = (lookup.indexOf(b64[i]) << 2) | (lookup.indexOf(b64[i + 1]) >> 4); 62 | arr.push(tmp & 0xFF); 63 | } else if (scratch === 1) { 64 | tmp = (lookup.indexOf(b64[i]) << 10) | (lookup.indexOf(b64[i + 1]) << 4); 65 | tmp |= (lookup.indexOf(b64[i + 2]) >> 2); 66 | arr.push((tmp >> 8) & 0xFF); 67 | arr.push(tmp & 0xFF); 68 | } 69 | return arr; 70 | }; 71 | -------------------------------------------------------------------------------- /src/mapreduce/jsfunctions/embed_data.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @copyright 2016 Couchbase, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | **/ 16 | 17 | /* This code takes in list of file names in argv and embed the contents 18 | * into a const char array. 19 | **/ 20 | 21 | #include 22 | #include 23 | 24 | int main(int argc, char **argv) 25 | { 26 | FILE *fp; 27 | int i, j, ch; 28 | 29 | printf("extern const unsigned char jsFunction_src[] = {"); 30 | for(i = 1; i < argc; i++) { 31 | if ((fp = fopen(argv[i], "rb")) == NULL) { 32 | exit(EXIT_FAILURE); 33 | } 34 | else { 35 | for (j = 0; (ch = fgetc(fp)) != EOF; j++) { 36 | if ((j % 12) == 0) { 37 | printf("%c", '\n'); 38 | } 39 | printf(" %#02x,", ch); 40 | } 41 | fclose(fp); 42 | } 43 | } 44 | 45 | // Append zero byte at the end, to make text files appear in memory 46 | // as nul-terminated strings. 47 | printf("%s", " 0x00\n};\n"); 48 | 49 | return EXIT_SUCCESS; 50 | } 51 | -------------------------------------------------------------------------------- /src/mapreduce/jsfunctions/is_doc_used.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @copyright 2016 Couchbase, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | **/ 16 | 17 | /** 18 | * This function returns array of properties that match given key 19 | **/ 20 | function getObjects(obj, key) { 21 | var objects = []; 22 | for (var prop in obj) { 23 | if (prop == key ) { 24 | objects.push(obj[key]); 25 | } 26 | else if (typeof obj[prop] == 'object') { 27 | objects = objects.concat(getObjects(obj[prop], key)); 28 | } 29 | } 30 | return objects; 31 | } 32 | 33 | /** 34 | * This function checks if eval function is used or not by checking the names 35 | * of all `callee` properties in the AST generated for map function 36 | **/ 37 | function is_eval_used(obj) { 38 | var objects = getObjects(obj, 'callee'); 39 | for (var i = 0; i < objects.length; i++) { 40 | if (objects[i].name == 'eval') { 41 | return true; 42 | } 43 | } 44 | return false; 45 | } 46 | 47 | /** 48 | * This function calls esprima and unused functions to get AST 49 | * and unused variables of map functions (in our view definitions) 50 | * It will check if the first parameter which is document in map 51 | * function is used in the code or not as well as if the eval function 52 | * is used in map body or not. If eval function is used it is difficult 53 | * to determine if any doc parameters are evaluated or not. In this case 54 | * this function returns that document parameter is used otherwise it 55 | * returns if the document parameter is used or not. Specifically it 56 | * returns true if doc parameter is unused and false otherwise. 57 | **/ 58 | function is_doc_unused(src) { 59 | var unused_retval = unused(src); 60 | 61 | for (var i = 0; i < unused_retval.unused_vars.length; i++) { 62 | if (unused_retval.ast.body[0].expression.params[0].name == 63 | unused_retval.unused_vars[i].name && 64 | unused_retval.unused_vars[i].param == true) { 65 | return true && !is_eval_used(unused_retval.ast); 66 | } 67 | } 68 | return false && !is_eval_used(unused_retval.ast); 69 | } 70 | -------------------------------------------------------------------------------- /src/mapreduce/jsfunctions/jsfunctions_data.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @copyright 2016 Couchbase, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | **/ 16 | 17 | #ifndef _JSFUNCTION_DATA_H 18 | #define _JSFUNCTION_DATA_H 19 | 20 | extern const unsigned char jsFunction_src[]; 21 | 22 | #endif //_JSFUNCTION_DATA_H 23 | -------------------------------------------------------------------------------- /src/mapreduce/jsfunctions/unused/context.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | * 14 | */ 15 | 16 | var Context = function(parent) { 17 | var self = this; 18 | 19 | self.parent = parent; 20 | self.variables = {}; 21 | 22 | // map of used 23 | self.used = {}; 24 | }; 25 | 26 | Context.prototype.set = function(name, loc) { 27 | var self = this; 28 | 29 | // in javascript you can use variables before they are declared 30 | // yea, it is magical 31 | if (self.used[name]) { 32 | return; 33 | } 34 | 35 | self.variables[name] = loc; 36 | }; 37 | 38 | Context.prototype.get = function(name) { 39 | var self = this; 40 | 41 | var val = self.variables[name]; 42 | if (val) { 43 | return val; 44 | } 45 | 46 | if (!self.parent) { 47 | return; 48 | } 49 | 50 | return self.parent.get(name); 51 | }; 52 | 53 | Context.prototype.remove = function(name) { 54 | var self = this; 55 | 56 | self.used[name] = true; 57 | 58 | // if in our scope, remove 59 | // otherwise we will start checking parent scope 60 | if (self.variables[name]) { 61 | return delete self.variables[name]; 62 | } 63 | 64 | if (!self.parent) { 65 | return; 66 | } 67 | 68 | self.parent.remove(name); 69 | }; 70 | 71 | // return list of the unused variables in this context 72 | Context.prototype.unused = function() { 73 | var self = this; 74 | return Object.keys(self.variables).map(function(key) { 75 | return self.variables[key]; 76 | }); 77 | }; 78 | -------------------------------------------------------------------------------- /src/mapreduce/nif_stl_allocator.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @copyright 2013 Couchbase, Inc. 3 | * 4 | * @author Filipe Manana 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 7 | * use this file except in compliance with the License. You may obtain a copy of 8 | * the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 14 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 15 | * License for the specific language governing permissions and limitations under 16 | * the License. 17 | **/ 18 | 19 | #ifndef _NIF_STL_ALLOCATOR_H 20 | #define _NIF_STL_ALLOCATOR_H 21 | 22 | // Some information about STL allocators: 23 | // http://www.cplusplus.com/reference/std/memory/allocator/ 24 | // 25 | template class NifStlAllocator { 26 | public: 27 | typedef size_t size_type; 28 | typedef ptrdiff_t difference_type; 29 | typedef T* pointer; 30 | typedef const T* const_pointer; 31 | typedef T& reference; 32 | typedef const T& const_reference; 33 | typedef T value_type; 34 | 35 | NifStlAllocator() {} 36 | NifStlAllocator(const NifStlAllocator&) {} 37 | 38 | pointer allocate(size_type n, const void * = 0) { 39 | if (n > this->max_size()) { 40 | throw std::bad_alloc(); 41 | } 42 | pointer t = static_cast(enif_alloc(n * sizeof(value_type))); 43 | if (!t) { 44 | throw std::bad_alloc(); 45 | } 46 | return t; 47 | } 48 | 49 | void deallocate(void *p, size_type) { 50 | if (p) { 51 | enif_free(p); 52 | } 53 | } 54 | 55 | pointer address(reference x) const { 56 | return &x; 57 | } 58 | 59 | const_pointer address(const_reference x) const { 60 | return &x; 61 | } 62 | 63 | void construct(pointer p, const_reference val) { 64 | new (p) value_type(val); 65 | } 66 | 67 | void destroy(pointer p) { 68 | p->~T(); 69 | } 70 | 71 | size_type max_size() const { 72 | return size_t(-1) / sizeof(value_type); 73 | } 74 | 75 | template 76 | struct rebind { 77 | typedef NifStlAllocator other; 78 | }; 79 | 80 | template 81 | NifStlAllocator(const NifStlAllocator&) {} 82 | 83 | template 84 | NifStlAllocator& operator=(const NifStlAllocator&) { 85 | return *this; 86 | } 87 | }; 88 | 89 | template 90 | inline bool operator==(const NifStlAllocator&, const NifStlAllocator&) { 91 | return true; 92 | } 93 | 94 | template 95 | inline bool operator!=(const NifStlAllocator&, const NifStlAllocator&) { 96 | return false; 97 | } 98 | 99 | #endif 100 | -------------------------------------------------------------------------------- /src/mapreduce/src/mapreduce.app.src: -------------------------------------------------------------------------------- 1 | {application, mapreduce, 2 | [ 3 | {description, "MapReduce using V8 JavaScript engine"}, 4 | {vsn, "1.0.0"}, 5 | {registered, []}, 6 | {applications, [ 7 | kernel, 8 | stdlib 9 | ]}, 10 | {env, []}, 11 | {modules, [mapreduce]} 12 | ]}. 13 | -------------------------------------------------------------------------------- /src/mapreduce/src/mapreduce.erl: -------------------------------------------------------------------------------- 1 | % -*- Mode: Erlang; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */ 2 | 3 | %% @copyright 2012 Couchbase, Inc. 4 | %% 5 | %% @author Filipe Manana 6 | %% 7 | %% Licensed under the Apache License, Version 2.0 (the "License"); you may not 8 | %% use this file except in compliance with the License. You may obtain a copy of 9 | %% the License at 10 | %% 11 | %% http://www.apache.org/licenses/LICENSE-2.0 12 | %% 13 | %% Unless required by applicable law or agreed to in writing, software 14 | %% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | %% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | %% License for the specific language governing permissions and limitations under 17 | %% the License. 18 | 19 | -module(mapreduce). 20 | 21 | -export([start_map_context/2]). 22 | -export([map_doc/3]). 23 | 24 | -export([start_reduce_context/1]). 25 | -export([reduce/2, reduce/3]). 26 | -export([rereduce/3]). 27 | 28 | -export([set_timeout/1, set_max_kv_size_per_doc/1]). 29 | -export([is_doc_used/1, set_optimize_doc_load/1]). 30 | 31 | -on_load(init/0). 32 | 33 | 34 | init() -> 35 | SoName = case code:priv_dir(?MODULE) of 36 | {error, bad_name} -> 37 | case filelib:is_dir(filename:join(["..", "priv"])) of 38 | true -> 39 | filename:join(["..", "priv", "mapreduce_nif"]); 40 | false -> 41 | filename:join(["priv", "mapreduce_nif"]) 42 | end; 43 | Dir -> 44 | filename:join(Dir, "mapreduce_nif") 45 | end, 46 | erlang:load_nif(SoName, SoName). 47 | 48 | start_map_context(_Mod, _MapFunSources) -> 49 | erlang:nif_error(mapreduce_nif_not_loaded). 50 | 51 | 52 | map_doc(_Context, _Doc, _Meta) -> 53 | erlang:nif_error(mapreduce_nif_not_loaded). 54 | 55 | 56 | start_reduce_context(_ReduceFunSources) -> 57 | erlang:nif_error(mapreduce_nif_not_loaded). 58 | 59 | 60 | reduce(_Context, _KvList) -> 61 | erlang:nif_error(mapreduce_nif_not_loaded). 62 | 63 | 64 | reduce(_Context, _ReduceFunNumber, _KvList) -> 65 | erlang:nif_error(mapreduce_nif_not_loaded). 66 | 67 | 68 | rereduce(_Context, _ReduceFunNumber, _ReductionsList) -> 69 | erlang:nif_error(mapreduce_nif_not_loaded). 70 | 71 | 72 | set_timeout(_TimeoutMs) -> 73 | erlang:nif_error(mapreduce_nif_not_loaded). 74 | 75 | 76 | set_max_kv_size_per_doc(_Max) -> 77 | erlang:nif_error(mapreduce_nif_not_loaded). 78 | 79 | is_doc_used(_Ctx) -> 80 | erlang:nif_error(mapreduce_nif_not_loaded). 81 | 82 | set_optimize_doc_load(_Flag) -> 83 | erlang:nif_error(mapreduce_nif_not_loaded). 84 | -------------------------------------------------------------------------------- /src/mapreduce/test/03-builtin-functions.t: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env escript 2 | %% -*- Mode: Erlang; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */ 3 | %%! -smp enable 4 | 5 | % @copyright 2012 Couchbase, Inc. 6 | % 7 | % @author Filipe Manana 8 | % 9 | % Licensed under the Apache License, Version 2.0 (the "License"); you may not 10 | % use this file except in compliance with the License. You may obtain a copy of 11 | % the License at 12 | % 13 | % http://www.apache.org/licenses/LICENSE-2.0 14 | % 15 | % Unless required by applicable law or agreed to in writing, software 16 | % distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 17 | % WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 18 | % License for the specific language governing permissions and limitations under 19 | % the License. 20 | 21 | main(_) -> 22 | test_util:init_code_path(), 23 | 24 | etap:plan(3), 25 | case (catch test()) of 26 | ok -> 27 | etap:end_tests(); 28 | Other -> 29 | etap:diag(io_lib:format("Test died abnormally: ~p", [Other])), 30 | etap:bail(Other) 31 | end, 32 | ok. 33 | 34 | 35 | test() -> 36 | test_sum_function(), 37 | test_base64decode_function(), 38 | test_dateToArray_function(), 39 | ok. 40 | 41 | 42 | test_sum_function() -> 43 | {ok, Ctx} = mapreduce:start_map_context(mapreduce_view, [ 44 | <<"function(doc) { emit(doc._id, sum(doc.values)); }">> 45 | ]), 46 | Results = mapreduce:map_doc(Ctx, <<"{\"_id\": \"doc1\", \"values\": [1, 2, 3, 4]}">>, <<"{}">>), 47 | etap:is(Results, {ok, [[{<<"\"doc1\"">>, <<"10">>}]], []}, "sum() builtin function works"). 48 | 49 | test_base64decode_function() -> 50 | {ok, Ctx} = mapreduce:start_map_context(mapreduce_view, [ 51 | <<"function(doc) { emit(doc._id, String.fromCharCode.apply(this, decodeBase64(doc._bin))); }">> 52 | ]), 53 | Results = mapreduce:map_doc(Ctx, <<"{ \"_id\": \"counter\", \"_bin\": \"NQ==\" }">>, <<"{}">>), 54 | etap:is(Results, {ok,[[{<<"\"counter\"">>,<<"\"5\"">>}]], []}, "decodeBase64() builtin function works"). 55 | 56 | 57 | test_dateToArray_function() -> 58 | {ok, Ctx} = mapreduce:start_map_context(mapreduce_view, [ 59 | <<"function(doc, meta) { emit(dateToArray(doc.date), meta.id); }">> 60 | ]), 61 | Results = mapreduce:map_doc(Ctx, <<"{ \"date\":\"+033658-09-27T01:46:40.000Z\"}">>, <<"{\"id\":\"foo\"}">>), 62 | etap:is(Results, {ok,[[{<<"[33658,9,27,1,46,40]">>,<<"\"foo\"">>}]], []}, "dateToArray() builtin function works"). 63 | -------------------------------------------------------------------------------- /src/mapreduce/test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | SET(TEST_FILES 2 | 01-map.t 3 | 02-reduce.t 4 | 03-builtin-functions.t 5 | 04-optimize_doc_load.t) 6 | 7 | FOREACH (it ${TEST_FILES}) 8 | GET_FILENAME_COMPONENT(testname ${it} NAME_WE) 9 | GET_FILENAME_COMPONENT(fullpath ${it} REALPATH) 10 | ADD_TEST(couchdb-mapreduce-${testname} python3 11 | ${COUCHDB_RUNTEST} -c ${COUCHSTORE_BIN_PATH} -p ${COUCHDB_BIN_PATH}/src 12 | -e ${ESCRIPT_EXECUTABLE} -t ${fullpath} --verbose) 13 | ENDFOREACH (it) 14 | -------------------------------------------------------------------------------- /src/mapreduce/test/run.tpl: -------------------------------------------------------------------------------- 1 | #!/bin/sh -e 2 | 3 | # @copyright 2012 Couchbase, Inc. 4 | # 5 | # @author Filipe Manana 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may not 8 | # use this file except in compliance with the License. You may obtain a copy of 9 | # the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations under 17 | # the License. 18 | 19 | BUILDDIR="${CMAKE_CURRENT_BINARY_DIR}" 20 | export ERL_FLAGS="$ERL_FLAGS -pa $BUILDDIR/src/mapreduce/test/" 21 | 22 | $BUILDDIR/test/etap/run $@ 23 | -------------------------------------------------------------------------------- /src/mochiweb/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | SET(MOCHIWEB_VERSION "1.4.1") 2 | SET(MOCHIWEB_INSTALL_PREFIX ${CMAKE_ERL_LIB_INSTALL_PREFIX}/mochiweb-${MOCHIWEB_VERSION}) 3 | 4 | CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/src/mochiweb.app.src 5 | ${CMAKE_CURRENT_BINARY_DIR}/mochiweb.app) 6 | 7 | INSTALL(DIRECTORY ${COUCHDB_DEFAULT_LIB_DIR}/mochiweb/ebin 8 | DESTINATION ${MOCHIWEB_INSTALL_PREFIX}) 9 | -------------------------------------------------------------------------------- /src/mochiweb/include/internal.hrl: -------------------------------------------------------------------------------- 1 | 2 | -define(RECBUF_SIZE, 8192). 3 | 4 | -------------------------------------------------------------------------------- /src/mochiweb/src/mochifmt_records.erl: -------------------------------------------------------------------------------- 1 | %% @author Bob Ippolito 2 | %% @copyright 2008 Mochi Media, Inc. 3 | %% 4 | %% Permission is hereby granted, free of charge, to any person obtaining a 5 | %% copy of this software and associated documentation files (the "Software"), 6 | %% to deal in the Software without restriction, including without limitation 7 | %% the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | %% and/or sell copies of the Software, and to permit persons to whom the 9 | %% Software is furnished to do so, subject to the following conditions: 10 | %% 11 | %% The above copyright notice and this permission notice shall be included in 12 | %% all copies or substantial portions of the Software. 13 | %% 14 | %% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | %% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | %% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 | %% THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | %% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | %% FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 | %% DEALINGS IN THE SOFTWARE. 21 | 22 | %% @doc Formatter that understands records. 23 | %% 24 | %% Usage: 25 | %% 26 | %% 1> M = mochifmt_records:new([{rec, record_info(fields, rec)}]), 27 | %% M:format("{0.bar}", [#rec{bar=foo}]). 28 | %% foo 29 | 30 | -module(mochifmt_records). 31 | -author('bob@mochimedia.com'). 32 | -export([new/1, get_value/3]). 33 | 34 | new([{_Rec, RecFields}]=Recs) when is_list(RecFields) -> 35 | {?MODULE, Recs}. 36 | 37 | get_value(Key, Rec, {?MODULE, Recs}) 38 | when is_tuple(Rec) and is_atom(element(1, Rec)) -> 39 | try begin 40 | Atom = list_to_existing_atom(Key), 41 | {_, Fields} = proplists:lookup(element(1, Rec), Recs), 42 | element(get_rec_index(Atom, Fields, 2), Rec) 43 | end 44 | catch error:_ -> mochifmt:get_value(Key, Rec) 45 | end; 46 | get_value(Key, Args, {?MODULE, _Recs}) -> 47 | mochifmt:get_value(Key, Args). 48 | 49 | get_rec_index(Atom, [Atom | _], Index) -> 50 | Index; 51 | get_rec_index(Atom, [_ | Rest], Index) -> 52 | get_rec_index(Atom, Rest, 1 + Index). 53 | 54 | 55 | %% 56 | %% Tests 57 | %% 58 | -ifdef(TEST). 59 | -include_lib("eunit/include/eunit.hrl"). 60 | -endif. 61 | -------------------------------------------------------------------------------- /src/mochiweb/src/mochifmt_std.erl: -------------------------------------------------------------------------------- 1 | %% @author Bob Ippolito 2 | %% @copyright 2008 Mochi Media, Inc. 3 | %% 4 | %% Permission is hereby granted, free of charge, to any person obtaining a 5 | %% copy of this software and associated documentation files (the "Software"), 6 | %% to deal in the Software without restriction, including without limitation 7 | %% the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | %% and/or sell copies of the Software, and to permit persons to whom the 9 | %% Software is furnished to do so, subject to the following conditions: 10 | %% 11 | %% The above copyright notice and this permission notice shall be included in 12 | %% all copies or substantial portions of the Software. 13 | %% 14 | %% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | %% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | %% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 | %% THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | %% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | %% FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 | %% DEALINGS IN THE SOFTWARE. 21 | 22 | %% @doc Template module for a mochifmt formatter. 23 | 24 | -module(mochifmt_std). 25 | -author('bob@mochimedia.com'). 26 | -export([new/0, format/3, get_value/3, format_field/3, get_field/3, convert_field/3]). 27 | 28 | new() -> 29 | {?MODULE}. 30 | 31 | format(Format, Args, {?MODULE}=THIS) -> 32 | mochifmt:format(Format, Args, THIS). 33 | 34 | get_field(Key, Args, {?MODULE}=THIS) -> 35 | mochifmt:get_field(Key, Args, THIS). 36 | 37 | convert_field(Key, Args, {?MODULE}) -> 38 | mochifmt:convert_field(Key, Args). 39 | 40 | get_value(Key, Args, {?MODULE}) -> 41 | mochifmt:get_value(Key, Args). 42 | 43 | format_field(Arg, Format, {?MODULE}=THIS) -> 44 | mochifmt:format_field(Arg, Format, THIS). 45 | 46 | %% 47 | %% Tests 48 | %% 49 | -ifdef(TEST). 50 | -include_lib("eunit/include/eunit.hrl"). 51 | -endif. 52 | -------------------------------------------------------------------------------- /src/mochiweb/src/mochiweb.app.src: -------------------------------------------------------------------------------- 1 | %% This is generated from src/mochiweb.app.src 2 | {application, mochiweb, 3 | [{description, "MochiMedia Web Server"}, 4 | {vsn, "2.20.0"}, 5 | {modules, []}, 6 | {registered, []}, 7 | {env, []}, 8 | {applications, [kernel, stdlib, crypto, inets, ssl, xmerl, 9 | compiler, syntax_tools]}, 10 | 11 | {maintainers, ["Bob Ippolito"]}, 12 | {licenses, ["MIT"]}, 13 | {links, [{"Github", "https://github.com/mochi/mochiweb"}]} 14 | ] 15 | }. 16 | -------------------------------------------------------------------------------- /src/mochiweb/src/mochiweb_app.erl: -------------------------------------------------------------------------------- 1 | %% @author Bob Ippolito 2 | %% @copyright 2007 Mochi Media, Inc. 3 | 4 | %% @doc Callbacks for the mochiweb application. 5 | 6 | -module(mochiweb_app). 7 | -author('bob@mochimedia.com'). 8 | 9 | -behaviour(application). 10 | -export([start/2,stop/1]). 11 | 12 | %% @spec start(_Type, _StartArgs) -> ServerRet 13 | %% @doc application start callback for mochiweb. 14 | start(_Type, _StartArgs) -> 15 | mochiweb_sup:start_link(). 16 | 17 | %% @spec stop(_State) -> ServerRet 18 | %% @doc application stop callback for mochiweb. 19 | stop(_State) -> 20 | ok. 21 | 22 | %% 23 | %% Tests 24 | %% 25 | -include_lib("eunit/include/eunit.hrl"). 26 | -ifdef(TEST). 27 | -endif. 28 | -------------------------------------------------------------------------------- /src/mochiweb/src/mochiweb_echo.erl: -------------------------------------------------------------------------------- 1 | %% @author Bob Ippolito 2 | %% @copyright 2007 Mochi Media, Inc. 3 | %% 4 | %% Permission is hereby granted, free of charge, to any person obtaining a 5 | %% copy of this software and associated documentation files (the "Software"), 6 | %% to deal in the Software without restriction, including without limitation 7 | %% the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | %% and/or sell copies of the Software, and to permit persons to whom the 9 | %% Software is furnished to do so, subject to the following conditions: 10 | %% 11 | %% The above copyright notice and this permission notice shall be included in 12 | %% all copies or substantial portions of the Software. 13 | %% 14 | %% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | %% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | %% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 | %% THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | %% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | %% FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 | %% DEALINGS IN THE SOFTWARE. 21 | 22 | %% @doc Simple and stupid echo server to demo mochiweb_socket_server. 23 | 24 | -module(mochiweb_echo). 25 | -author('bob@mochimedia.com'). 26 | -export([start/0, stop/0, loop/1]). 27 | 28 | stop() -> 29 | mochiweb_socket_server:stop(?MODULE). 30 | 31 | start() -> 32 | mochiweb_socket_server:start([{link, false} | options()]). 33 | 34 | options() -> 35 | [{name, ?MODULE}, 36 | {port, 6789}, 37 | {ip, "127.0.0.1"}, 38 | {max, 1}, 39 | {loop, {?MODULE, loop}}]. 40 | 41 | loop(Socket) -> 42 | case mochiweb_socket:recv(Socket, 0, 30000) of 43 | {ok, Data} -> 44 | case mochiweb_socket:send(Socket, Data) of 45 | ok -> 46 | loop(Socket); 47 | _ -> 48 | exit(normal) 49 | end; 50 | _Other -> 51 | exit(normal) 52 | end. 53 | 54 | %% 55 | %% Tests 56 | %% 57 | -ifdef(TEST). 58 | -include_lib("eunit/include/eunit.hrl"). 59 | -endif. 60 | -------------------------------------------------------------------------------- /src/mochiweb/src/mochiweb_io.erl: -------------------------------------------------------------------------------- 1 | %% @author Bob Ippolito 2 | %% @copyright 2007 Mochi Media, Inc. 3 | %% 4 | %% Permission is hereby granted, free of charge, to any person obtaining a 5 | %% copy of this software and associated documentation files (the "Software"), 6 | %% to deal in the Software without restriction, including without limitation 7 | %% the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | %% and/or sell copies of the Software, and to permit persons to whom the 9 | %% Software is furnished to do so, subject to the following conditions: 10 | %% 11 | %% The above copyright notice and this permission notice shall be included in 12 | %% all copies or substantial portions of the Software. 13 | %% 14 | %% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | %% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | %% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 | %% THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | %% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | %% FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 | %% DEALINGS IN THE SOFTWARE. 21 | 22 | %% @doc Utilities for dealing with IO devices (open files). 23 | 24 | -module(mochiweb_io). 25 | -author('bob@mochimedia.com'). 26 | 27 | -export([iodevice_stream/3, iodevice_stream/2]). 28 | -export([iodevice_foldl/4, iodevice_foldl/3]). 29 | -export([iodevice_size/1]). 30 | -define(READ_SIZE, 8192). 31 | 32 | iodevice_foldl(F, Acc, IoDevice) -> 33 | iodevice_foldl(F, Acc, IoDevice, ?READ_SIZE). 34 | 35 | iodevice_foldl(F, Acc, IoDevice, BufferSize) -> 36 | case file:read(IoDevice, BufferSize) of 37 | eof -> 38 | Acc; 39 | {ok, Data} -> 40 | iodevice_foldl(F, F(Data, Acc), IoDevice, BufferSize) 41 | end. 42 | 43 | iodevice_stream(Callback, IoDevice) -> 44 | iodevice_stream(Callback, IoDevice, ?READ_SIZE). 45 | 46 | iodevice_stream(Callback, IoDevice, BufferSize) -> 47 | F = fun (Data, ok) -> Callback(Data) end, 48 | ok = iodevice_foldl(F, ok, IoDevice, BufferSize). 49 | 50 | iodevice_size(IoDevice) -> 51 | {ok, Size} = file:position(IoDevice, eof), 52 | {ok, 0} = file:position(IoDevice, bof), 53 | Size. 54 | 55 | 56 | %% 57 | %% Tests 58 | %% 59 | -ifdef(TEST). 60 | -include_lib("eunit/include/eunit.hrl"). 61 | -endif. 62 | -------------------------------------------------------------------------------- /src/mochiweb/src/mochiweb_sup.erl: -------------------------------------------------------------------------------- 1 | %% @author Bob Ippolito 2 | %% @copyright 2007 Mochi Media, Inc. 3 | 4 | %% @doc Supervisor for the mochiweb application. 5 | 6 | -module(mochiweb_sup). 7 | -author('bob@mochimedia.com'). 8 | 9 | -behaviour(supervisor). 10 | 11 | %% External exports 12 | -export([start_link/0, upgrade/0]). 13 | 14 | %% supervisor callbacks 15 | -export([init/1]). 16 | 17 | %% @spec start_link() -> ServerRet 18 | %% @doc API for starting the supervisor. 19 | start_link() -> 20 | supervisor:start_link({local, ?MODULE}, ?MODULE, []). 21 | 22 | %% @spec upgrade() -> ok 23 | %% @doc Add processes if necessary. 24 | upgrade() -> 25 | {ok, {_, Specs}} = init([]), 26 | [supervisor:start_child(?MODULE, Spec) || Spec <- Specs], 27 | ok. 28 | 29 | %% @spec init([]) -> SupervisorTree 30 | %% @doc supervisor callback, ensures yaws is in embedded mode and then 31 | %% returns the supervisor tree. 32 | init([]) -> 33 | Processes = [], 34 | {ok, {{one_for_one, 10, 10}, Processes}}. 35 | 36 | %% 37 | %% Tests 38 | %% 39 | -include_lib("eunit/include/eunit.hrl"). 40 | -ifdef(TEST). 41 | -endif. 42 | -------------------------------------------------------------------------------- /src/snappy/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | SET(COUCH_VIEW_SNAPPY_SRC src/snappy_nif.cc) 2 | SET(COUCH_SNAPPY_VERSION "1.0.4") 3 | SET(COUCH_SNAPPY_PREFIX ${CMAKE_ERL_LIB_INSTALL_PREFIX}/snappy-${COUCH_SNAPPY_VERSION}) 4 | SET(COUCH_SNAPPY_PRIV_PREFIX ${COUCH_SNAPPY_PREFIX}/priv) 5 | 6 | INCLUDE_DIRECTORIES(BEFORE ${SNAPPY_INCLUDE_DIR} 7 | ${ERLANG_INCLUDE_PATH}) 8 | 9 | ADD_LIBRARY(snappy_nif MODULE ${COUCH_VIEW_SNAPPY_SRC}) 10 | SET_TARGET_PROPERTIES(snappy_nif PROPERTIES PREFIX "") 11 | TARGET_LINK_LIBRARIES(snappy_nif ${COUCHBASE_UNRESOLVED} 12 | ${SNAPPY_LIBRARIES} 13 | ${COUCHBASE_MATH_LIBS}) 14 | 15 | SET_TARGET_PROPERTIES(snappy_nif PROPERTIES 16 | LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/priv" 17 | RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/priv" 18 | ) 19 | # snappy_nif is loaded into Erlang VM (beam.smp) which doesn't link 20 | # the sanitizer libs and hence cannot successfully load snappy_nif if 21 | # it has the sanitizers enabled. As such disable them. 22 | remove_sanitizers(snappy_nif) 23 | 24 | IF (UNIX) 25 | # It would be nice to share this code from 26 | # tlm/cmake/Modules/CouchbaseRpath.cmake, but unfortunately MacOS has 27 | # a distinction between @loader_path and @executable_path that doesn't 28 | # map to anything on other Unices, so it just has to be special 29 | IF (APPLE) 30 | SET (ORIGIN @loader_path) 31 | ELSE () 32 | SET (ORIGIN \$ORIGIN) 33 | ENDIF () 34 | # map from lib/couchdb/erlang/lib/snappy-1.0.4/priv/ to lib/ 35 | SET_TARGET_PROPERTIES(snappy_nif PROPERTIES 36 | INSTALL_RPATH "${ORIGIN}/../../../../..") 37 | ENDIF () 38 | 39 | INSTALL(TARGETS snappy_nif 40 | DESTINATION ${COUCH_SNAPPY_PRIV_PREFIX}) 41 | 42 | INSTALL(DIRECTORY ${COUCHDB_DEFAULT_LIB_DIR}/snappy/ebin 43 | DESTINATION ${COUCH_SNAPPY_PREFIX}) 44 | -------------------------------------------------------------------------------- /src/snappy/src/snappy.app.src: -------------------------------------------------------------------------------- 1 | {application, snappy, 2 | [ 3 | {description, "snappy compressor/decompressor Erlang NIF wrapper"}, 4 | {vsn, "1.0.3"}, 5 | {registered, []}, 6 | {applications, [ 7 | kernel, 8 | stdlib 9 | ]}, 10 | {env, []}, 11 | {modules, [snappy]} 12 | ]}. 13 | -------------------------------------------------------------------------------- /src/snappy/src/snappy.erl: -------------------------------------------------------------------------------- 1 | %% Copyright 2011, Filipe David Manana 2 | %% Web: http://github.com/fdmanana/snappy-erlang-nif 3 | %% 4 | %% Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | %% use this file except in compliance with the License. You may obtain a copy of 6 | %% the License at 7 | %% 8 | %% http://www.apache.org/licenses/LICENSE-2.0 9 | %% 10 | %% Unless required by applicable law or agreed to in writing, software 11 | %% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | %% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | %% License for the specific language governing permissions and limitations under 14 | %% the License. 15 | 16 | -module(snappy). 17 | 18 | -export([compress/1, decompress/1]). 19 | -export([uncompressed_length/1, is_valid/1]). 20 | 21 | -on_load(init/0). 22 | 23 | 24 | init() -> 25 | SoName = case code:priv_dir(?MODULE) of 26 | {error, bad_name} -> 27 | case filelib:is_dir(filename:join(["..", "priv"])) of 28 | true -> 29 | filename:join(["..", "priv", "snappy_nif"]); 30 | false -> 31 | filename:join(["priv", "snappy_nif"]) 32 | end; 33 | Dir -> 34 | filename:join(Dir, "snappy_nif") 35 | end, 36 | erlang:load_nif(SoName, 0). 37 | 38 | compress(_IoList) -> 39 | erlang:nif_error(snappy_nif_not_loaded). 40 | 41 | 42 | decompress(_IoList) -> 43 | erlang:nif_error(snappy_nif_not_loaded). 44 | 45 | 46 | uncompressed_length(_IoList) -> 47 | erlang:nif_error(snappy_nif_not_loaded). 48 | 49 | 50 | is_valid(_IoList) -> 51 | erlang:nif_error(snappy_nif_not_loaded). 52 | -------------------------------------------------------------------------------- /test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | ADD_SUBDIRECTORY(bench) 2 | ADD_SUBDIRECTORY(etap) 3 | ADD_SUBDIRECTORY(javascript) 4 | ADD_SUBDIRECTORY(functional_test) 5 | -------------------------------------------------------------------------------- /test/bench/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/run.tpl 2 | ${CMAKE_CURRENT_BINARY_DIR}/run) 3 | -------------------------------------------------------------------------------- /test/bench/benchbulk.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -e 2 | # Licensed under the Apache License, Version 2.0 (the "License"); you may not 3 | # use this file except in compliance with the License. You may obtain a copy of 4 | # the License at 5 | # 6 | # http://www.apache.org/licenses/LICENSE-2.0 7 | # 8 | # Unless required by applicable law or agreed to in writing, software 9 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 10 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 11 | # License for the specific language governing permissions and limitations under 12 | # the License. 13 | # 14 | 15 | # usage: time benchbulk.sh 16 | # it takes about 30 seconds to run on my old MacBook with bulksize 1000 17 | 18 | BULKSIZE=100 19 | DOCSIZE=10 20 | INSERTS=10 21 | ROUNDS=10 22 | DBURL="http://127.0.0.1:5984/benchbulk" 23 | POSTURL="$DBURL/_bulk_docs" 24 | 25 | function make_bulk_docs() { 26 | ROW=0 27 | SIZE=$(($1-1)) 28 | START=$2 29 | BODYSIZE=$3 30 | 31 | BODY=$(printf "%0${BODYSIZE}d") 32 | 33 | echo '{"docs":[' 34 | while [ $ROW -lt $SIZE ]; do 35 | printf '{"_id":"%020d", "body":"'$BODY'"},' $(($ROW + $START)) 36 | let ROW=ROW+1 37 | done 38 | printf '{"_id":"%020d", "body":"'$BODY'"}' $(($ROW + $START)) 39 | echo ']}' 40 | } 41 | 42 | echo "Making $INSERTS bulk inserts of $BULKSIZE docs each" 43 | 44 | echo "Attempt to delete db at $DBURL" 45 | curl -X DELETE $DBURL -w\\n 46 | 47 | echo "Attempt to create db at $DBURL" 48 | curl -X PUT $DBURL -w\\n 49 | 50 | echo "Running $ROUNDS rounds of $INSERTS concurrent inserts to $POSTURL" 51 | RUN=0 52 | while [ $RUN -lt $ROUNDS ]; do 53 | 54 | POSTS=0 55 | while [ $POSTS -lt $INSERTS ]; do 56 | STARTKEY=$[ POSTS * BULKSIZE + RUN * BULKSIZE * INSERTS ] 57 | echo "startkey $STARTKEY bulksize $BULKSIZE" 58 | DOCS=$(make_bulk_docs $BULKSIZE $STARTKEY $DOCSIZE) 59 | # echo $DOCS 60 | echo $DOCS | curl -T - -H Content-Type:application/json -X POST $POSTURL -w%{http_code}\ %{time_total}\ sec\\n >/dev/null 2>&1 & 61 | let POSTS=POSTS+1 62 | done 63 | 64 | echo "waiting" 65 | wait 66 | let RUN=RUN+1 67 | done 68 | 69 | curl $DBURL -w\\n 70 | -------------------------------------------------------------------------------- /test/bench/run.tpl: -------------------------------------------------------------------------------- 1 | #!/bin/sh -e 2 | 3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may not 4 | # use this file except in compliance with the License. You may obtain a copy of 5 | # the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | # License for the specific language governing permissions and limitations under 13 | # the License. 14 | 15 | SRC_DIR=@abs_top_srcdir@ 16 | SCRIPT_DIR=$SRC_DIR/share/www/script 17 | JS_TEST_DIR=$SRC_DIR/test/javascript 18 | JS_BENCH_DIR=$SRC_DIR/test/bench 19 | 20 | COUCHJS=@abs_top_srcdir@/src/couchdb/priv/couchjs 21 | 22 | cat $SCRIPT_DIR/json2.js \ 23 | $SCRIPT_DIR/couch.js \ 24 | $JS_TEST_DIR/couch_http.js \ 25 | $JS_BENCH_DIR/bench_marks.js \ 26 | $JS_TEST_DIR/cli_runner.js \ 27 | | $COUCHJS - 28 | -------------------------------------------------------------------------------- /test/ci/build: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | export PATH=$PATH:~/bin 4 | 5 | rm -rf ~/.ciscripts 6 | git clone -q git://github.com/couchbase/couchdb ~/.ciscripts 7 | cd ~/.ciscripts 8 | (source ~/.cienv; git checkout $BRANCH) 9 | 10 | while true; do 11 | git pull -q 12 | find test/ci -not -name 'build' -and -not -name '.*' -type f -exec cp -v {} ~/bin/ \; 13 | domain 14 | sleep 600 15 | done 16 | 17 | -------------------------------------------------------------------------------- /test/ci/domain: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ ! -f ~/.cienv ]; then 4 | cat > ~/.cienv <
' > /var/www/views-current.html
41 | chmod a+rx /var/www/views-current.html
42 | dobuild clean 1>>/var/www/views-current.html 2>&1; rc=$?
43 | test $rc -eq 0 && dotest 1>>/var/www/views-current.html 2>&1; rc=$?
44 | echo '
' >> /var/www/views-current.html 45 | if [ $rc -eq 0 ]; then status=pass; else status=fail; fi 46 | echo '
' >> /var/www/views-current.html
47 | gzip ${WORKSPACE}/logs.tar 2>&1 1>/dev/null
48 | echo "Version: versions-$TS.cfg" >> /var/www/views-current.html
49 | echo "Build Log: make-$TS.log" >> /var/www/views-current.html
50 | echo "Server Log: logs-$TS.tar.gz" >> /var/www/views-current.html
51 | echo "

Finished

" >> /var/www/views-current.html 52 | cp /var/www/views-current.html /var/www/views-$TS.$status.html 53 | mv ${WORKSPACE}/make.log /var/www/make-$TS.log 54 | mv ${WORKSPACE}/logs.tar.gz /var/www/logs-$TS.tar.gz 55 | mv ${WORKSPACE}/versions.cfg /var/www/versions-$TS.cfg 56 | dowatch 57 | -------------------------------------------------------------------------------- /test/ci/dotiming: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | source ~/.cienv 4 | 5 | -------------------------------------------------------------------------------- /test/ci/dowatch: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | source ~/.cienv 4 | 5 | if [ "$WORKSPACE" = "" ]; then 6 | echo 'WORKSPACE not set' 7 | exit 2 8 | fi 9 | 10 | for i in {1..240}; do 11 | cd $WORKSPACE 12 | sleep 60 13 | current="`git ls-remote git://github.com/couchbase/couchdb $BRANCH | awk '{print $1}'`" 14 | good="`cat ~/couchdb.good`" 15 | if [ "$current" != "$good" ]; then exit 0; fi 16 | done 17 | 18 | -------------------------------------------------------------------------------- /test/ci/kick: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | killall build 3 | killall domain 4 | killall dobuild 5 | killall dotest 6 | killall make 7 | pkill -e -f cluster_ 8 | pkill -e -f /opt/ 9 | killall beam.smp epmd 10 | killall python 11 | killall -9 memcached.json 12 | killall -9 memcached 13 | killall -9 eventing-consumer 14 | killall -9 eventing-producer 15 | -------------------------------------------------------------------------------- /test/ci/redo: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | cd $HOME/bin 3 | kick 4 | sleep 3 5 | build & 6 | 7 | -------------------------------------------------------------------------------- /test/ci/skip.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/couchbase/couchdb/54d030f7798f0317fea3502be73066c7cf0d03b0/test/ci/skip.txt -------------------------------------------------------------------------------- /test/etap/001-load.t: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env escript 2 | %% -*- erlang -*- 3 | %%! -smp enable 4 | 5 | % Licensed under the Apache License, Version 2.0 (the "License"); you may not 6 | % use this file except in compliance with the License. You may obtain a copy of 7 | % the License at 8 | % 9 | % http://www.apache.org/licenses/LICENSE-2.0 10 | % 11 | % Unless required by applicable law or agreed to in writing, software 12 | % distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 13 | % WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14 | % License for the specific language governing permissions and limitations under 15 | % the License. 16 | 17 | % Test that we can load each module. 18 | 19 | main(_) -> 20 | test_util:init_code_path(), 21 | etap:plan(31), 22 | Modules = [ 23 | couch_btree, 24 | couch_config, 25 | couch_config_writer, 26 | couch_db, 27 | couch_db_update_notifier, 28 | couch_db_update_notifier_sup, 29 | couch_db_updater, 30 | couch_doc, 31 | couch_event_sup, 32 | couch_file, 33 | couch_httpd, 34 | couch_httpd_db, 35 | couch_httpd_external, 36 | couch_httpd_misc_handlers, 37 | couch_httpd_view, 38 | couch_log, 39 | couch_os_process, 40 | couch_query_servers, 41 | couch_ref_counter, 42 | couch_replicator, 43 | couch_replicator_worker, 44 | couch_replicator_utils, 45 | couch_rep_sup, 46 | couch_server, 47 | couch_server_sup, 48 | couch_task_status, 49 | couch_util, 50 | couch_view, 51 | couch_view_compactor, 52 | couch_view_group, 53 | couch_view_updater 54 | ], 55 | 56 | lists:foreach( 57 | fun(Module) -> 58 | etap:loaded_ok( 59 | Module, 60 | lists:concat(["Loaded: ", Module]) 61 | ) 62 | end, Modules), 63 | etap:end_tests(). 64 | -------------------------------------------------------------------------------- /test/etap/002-write-guard.t: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env escript 2 | 3 | % Licensed under the Apache License, Version 2.0 (the "License"); you may not 4 | % use this file except in compliance with the License. You may obtain a copy of 5 | % the License at 6 | % 7 | % http://www.apache.org/licenses/LICENSE-2.0 8 | % 9 | % Unless required by applicable law or agreed to in writing, software 10 | % distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | % WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | % License for the specific language governing permissions and limitations under 13 | % the License. 14 | 15 | main(_) -> 16 | test_util:init_code_path(), 17 | etap:plan(6), 18 | case (catch test()) of 19 | ok -> 20 | etap:end_tests(); 21 | Other -> 22 | etap:diag(io_lib:format("Test died abnormally: ~p", [Other])), 23 | etap:bail() 24 | end, 25 | ok. 26 | 27 | 28 | loop() -> 29 | receive 30 | close -> ok 31 | end. 32 | 33 | 34 | test() -> 35 | couch_file_write_guard:sup_start_link(), 36 | Pid1 = spawn(fun() -> ok end), 37 | Pid2 = spawn(fun() -> loop() end), 38 | 39 | %% Added sleep timer in order to allow Pid1 to finish 40 | %% else is_process_alive(Pid1) will return true 41 | timer:sleep(1000), 42 | etap:is(is_process_alive(Pid1), false, "Process is not alive"), 43 | etap:is(couch_file_write_guard:add("index.1", Pid1), 44 | ok, 45 | "Added a file to non-existent pid mapping into write guard"), 46 | 47 | etap:is(couch_file_write_guard:add("index.1", Pid2), 48 | ok, 49 | "Added file to existing pid mapping into write guard"), 50 | 51 | etap:is(couch_file_write_guard:remove(Pid2), 52 | ok, 53 | "Removing ets table entry"), 54 | 55 | etap:is(couch_file_write_guard:add("index.1", Pid1), 56 | ok, 57 | "Added file"), 58 | 59 | etap:is(couch_file_write_guard:remove(Pid2), 60 | removing_unadded_file, 61 | "Removing unadded entry ets table entry"), 62 | 63 | Pid2 ! close, 64 | ok. 65 | -------------------------------------------------------------------------------- /test/etap/024-btree-guided-fold.t: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env escript 2 | %% -*- erlang -*- 3 | %%! -pa ./src/couchdb -sasl errlog_type error -noshell -smp enable 4 | 5 | % Licensed under the Apache License, Version 2.0 (the "License"); you may not 6 | % use this file except in compliance with the License. You may obtain a copy of 7 | % the License at 8 | % 9 | % http://www.apache.org/licenses/LICENSE-2.0 10 | % 11 | % Unless required by applicable law or agreed to in writing, software 12 | % distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 13 | % WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14 | % License for the specific language governing permissions and limitations under 15 | % the License. 16 | 17 | filename() -> "./test/etap/temp.024". 18 | 19 | 20 | main(_) -> 21 | test_util:init_code_path(), 22 | etap:plan(11), 23 | case (catch test()) of 24 | ok -> 25 | etap:end_tests(); 26 | Other -> 27 | etap:diag(io_lib:format("Test died abnormally: ~p", [Other])), 28 | etap:bail() 29 | end, 30 | ok. 31 | 32 | 33 | test() -> 34 | couch_file_write_guard:sup_start_link(), 35 | N = 77651, 36 | {ok, Btree, Fd} = create_btree(N), 37 | lists:foreach(fun(I) -> 38 | many_items_tree_test(Btree, I) 39 | end, [1, 6, 666, 669, 9999, 15001, 22228, 50703, 77000, 77651]), 40 | ok = couch_file:close(Fd), 41 | ok = file:delete(filename()). 42 | 43 | 44 | create_btree(N) -> 45 | ReduceFun = fun 46 | (reduce, KVs) -> 47 | length(KVs); 48 | (rereduce, Reds) -> 49 | lists:sum(Reds) 50 | end, 51 | 52 | {ok, Fd} = couch_file:open(filename(), [create, overwrite]), 53 | {ok, Btree} = couch_btree:open(nil, Fd, [{reduce, ReduceFun}]), 54 | 55 | KVs = [{I, I * I} || I <- lists:seq(1, N)], 56 | 57 | {ok, Btree2} = couch_btree:add_remove(Btree, KVs, []), 58 | ok = couch_file:flush(Fd), 59 | 60 | {ok, FullRed} = couch_btree:full_reduce(Btree2), 61 | etap:is(FullRed, N, "Initial reduce value equals N"), 62 | 63 | {ok, Btree2, Fd}. 64 | 65 | 66 | many_items_tree_test(Btree, ItemNumber) -> 67 | Acc0 = {1, undefined}, 68 | FoldFun = fun 69 | (value, KV, _Reds, {I, undefined}) -> 70 | case I == ItemNumber of 71 | true -> 72 | {stop, {I, KV}}; 73 | false -> 74 | {ok, {I + 1, undefined}} 75 | end; 76 | (branch, _K, Red, {I, undefined}) -> 77 | I2 = I + Red, 78 | case I2 >= ItemNumber of 79 | true -> 80 | {ok, {I, undefined}}; 81 | false -> 82 | {skip, {I2, undefined}} 83 | end 84 | end, 85 | {ok, _, FinalAcc} = couch_btree:fold(Btree, FoldFun, Acc0, []), 86 | io:format("FinalAcc: ~p~n", [FinalAcc]), 87 | etap:is(FinalAcc, 88 | {ItemNumber, {ItemNumber, ItemNumber * ItemNumber}}, 89 | "Got expected final acc"). 90 | -------------------------------------------------------------------------------- /test/etap/041-uuid-gen-seq.ini: -------------------------------------------------------------------------------- 1 | ; Licensed to the Apache Software Foundation (ASF) under one 2 | ; or more contributor license agreements. See the NOTICE file 3 | ; distributed with this work for additional information 4 | ; regarding copyright ownership. The ASF licenses this file 5 | ; to you under the Apache License, Version 2.0 (the 6 | ; "License"); you may not use this file except in compliance 7 | ; with the License. You may obtain a copy of the License at 8 | ; 9 | ; http://www.apache.org/licenses/LICENSE-2.0 10 | ; 11 | ; Unless required by applicable law or agreed to in writing, 12 | ; software distributed under the License is distributed on an 13 | ; "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | ; KIND, either express or implied. See the License for the 15 | ; specific language governing permissions and limitations 16 | ; under the License. 17 | 18 | [uuids] 19 | algorithm = sequential 20 | -------------------------------------------------------------------------------- /test/etap/041-uuid-gen-utc.ini: -------------------------------------------------------------------------------- 1 | ; Licensed to the Apache Software Foundation (ASF) under one 2 | ; or more contributor license agreements. See the NOTICE file 3 | ; distributed with this work for additional information 4 | ; regarding copyright ownership. The ASF licenses this file 5 | ; to you under the Apache License, Version 2.0 (the 6 | ; "License"); you may not use this file except in compliance 7 | ; with the License. You may obtain a copy of the License at 8 | ; 9 | ; http://www.apache.org/licenses/LICENSE-2.0 10 | ; 11 | ; Unless required by applicable law or agreed to in writing, 12 | ; software distributed under the License is distributed on an 13 | ; "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | ; KIND, either express or implied. See the License for the 15 | ; specific language governing permissions and limitations 16 | ; under the License. 17 | 18 | [uuids] 19 | algorithm = utc_random 20 | -------------------------------------------------------------------------------- /test/etap/070-couch-db.t: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env escript 2 | %% -*- erlang -*- 3 | %%! -smp enable 4 | 5 | % Licensed under the Apache License, Version 2.0 (the "License"); you may not 6 | % use this file except in compliance with the License. You may obtain a copy of 7 | % the License at 8 | % 9 | % http://www.apache.org/licenses/LICENSE-2.0 10 | % 11 | % Unless required by applicable law or agreed to in writing, software 12 | % distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 13 | % WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14 | % License for the specific language governing permissions and limitations under 15 | % the License. 16 | 17 | main(_) -> 18 | test_util:init_code_path(), 19 | 20 | etap:plan(4), 21 | case (catch test()) of 22 | ok -> 23 | etap:end_tests(); 24 | Other -> 25 | etap:diag(io_lib:format("Test died abnormally: ~p", [Other])), 26 | etap:bail(Other) 27 | end, 28 | ok. 29 | 30 | test() -> 31 | 32 | couch_server_sup:start_link(test_util:config_files()), 33 | 34 | couch_db:create(<<"etap-test-db">>, []), 35 | {ok, AllDbs} = couch_server:all_databases(), 36 | etap:ok(lists:member(<<"etap-test-db">>, AllDbs), "Database was created."), 37 | 38 | couch_server:delete(<<"etap-test-db">>, []), 39 | {ok, AllDbs2} = couch_server:all_databases(), 40 | etap:ok(not lists:member(<<"etap-test-db">>, AllDbs2), 41 | "Database was deleted."), 42 | 43 | MkDbName = fun(Int) -> list_to_binary("lru-" ++ integer_to_list(Int)) end, 44 | 45 | lists:foreach(fun(Int) -> 46 | {ok, TestDbs} = couch_server:all_databases(), 47 | ok = case lists:member(MkDbName(Int), TestDbs) of 48 | true -> couch_server:delete(MkDbName(Int), []); 49 | _ -> ok 50 | end, 51 | {ok, Db} = couch_db:create(MkDbName(Int), []), 52 | ok = couch_db:close(Db) 53 | end, lists:seq(1, 6)), 54 | 55 | {ok, AllDbs3} = couch_server:all_databases(), 56 | NumCreated = lists:foldl(fun(Int, Acc) -> 57 | true = lists:member(MkDbName(Int), AllDbs3), 58 | Acc+1 59 | end, 0, lists:seq(1, 6)), 60 | etap:is(6, NumCreated, "Created all databases."), 61 | 62 | lists:foreach(fun(Int) -> 63 | ok = couch_server:delete(MkDbName(Int), []) 64 | end, lists:seq(1, 6)), 65 | 66 | {ok, AllDbs4} = couch_server:all_databases(), 67 | NumDeleted = lists:foldl(fun(Int, Acc) -> 68 | false = lists:member(MkDbName(Int), AllDbs4), 69 | Acc+1 70 | end, 0, lists:seq(1, 6)), 71 | etap:is(6, NumDeleted, "Deleted all databases."), 72 | 73 | ok. 74 | -------------------------------------------------------------------------------- /test/etap/081-config-override.1.ini: -------------------------------------------------------------------------------- 1 | ; Licensed to the Apache Software Foundation (ASF) under one 2 | ; or more contributor license agreements. See the NOTICE file 3 | ; distributed with this work for additional information 4 | ; regarding copyright ownership. The ASF licenses this file 5 | ; to you under the Apache License, Version 2.0 (the 6 | ; "License"); you may not use this file except in compliance 7 | ; with the License. You may obtain a copy of the License at 8 | ; 9 | ; http://www.apache.org/licenses/LICENSE-2.0 10 | ; 11 | ; Unless required by applicable law or agreed to in writing, 12 | ; software distributed under the License is distributed on an 13 | ; "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | ; KIND, either express or implied. See the License for the 15 | ; specific language governing permissions and limitations 16 | ; under the License. 17 | 18 | [couchdb] 19 | max_dbs_open=10 20 | 21 | [httpd] 22 | port=4895 23 | -------------------------------------------------------------------------------- /test/etap/081-config-override.2.ini: -------------------------------------------------------------------------------- 1 | ; Licensed to the Apache Software Foundation (ASF) under one 2 | ; or more contributor license agreements. See the NOTICE file 3 | ; distributed with this work for additional information 4 | ; regarding copyright ownership. The ASF licenses this file 5 | ; to you under the Apache License, Version 2.0 (the 6 | ; "License"); you may not use this file except in compliance 7 | ; with the License. You may obtain a copy of the License at 8 | ; 9 | ; http://www.apache.org/licenses/LICENSE-2.0 10 | ; 11 | ; Unless required by applicable law or agreed to in writing, 12 | ; software distributed under the License is distributed on an 13 | ; "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | ; KIND, either express or implied. See the License for the 15 | ; specific language governing permissions and limitations 16 | ; under the License. 17 | 18 | [httpd] 19 | port = 80 20 | 21 | [fizbang] 22 | unicode = normalized 23 | -------------------------------------------------------------------------------- /test/etap/083-config-no-files.t: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env escript 2 | %% -*- erlang -*- 3 | %%! -smp enable 4 | 5 | % Licensed under the Apache License, Version 2.0 (the "License"); you may not 6 | % use this file except in compliance with the License. You may obtain a copy of 7 | % the License at 8 | % 9 | % http://www.apache.org/licenses/LICENSE-2.0 10 | % 11 | % Unless required by applicable law or agreed to in writing, software 12 | % distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 13 | % WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14 | % License for the specific language governing permissions and limitations under 15 | % the License. 16 | 17 | default_config() -> 18 | test_util:build_file("etc/couchdb/default_dev.ini"). 19 | 20 | main(_) -> 21 | test_util:init_code_path(), 22 | etap:plan(3), 23 | case (catch test()) of 24 | ok -> 25 | etap:end_tests(); 26 | Other -> 27 | etap:diag(io_lib:format("Test died abnormally: ~p", [Other])), 28 | etap:bail(Other) 29 | end, 30 | ok. 31 | 32 | check([]) -> 33 | true; 34 | check([{initialization_done,true}|T]) -> 35 | check(T); 36 | check(_) -> 37 | false. 38 | 39 | test() -> 40 | couch_system_event:start_link(), 41 | couch_config:start_link([]), 42 | 43 | etap:fun_is( 44 | fun(KVPairs) -> check(KVPairs) end, 45 | couch_config:all(), 46 | "No INI files specified returns 0 key/value pairs." 47 | ), 48 | 49 | ok = couch_config:set("httpd", "port", "80", false), 50 | 51 | etap:is( 52 | couch_config:get("httpd", "port"), 53 | "80", 54 | "Created a new non-persisted k/v pair." 55 | ), 56 | 57 | {Field, Addr} = case misc:is_ipv6() of 58 | true -> {"ip6_bind_address", "::1"}; 59 | false -> {"ip4_bind_address", "127.0.0.1"} 60 | end, 61 | 62 | ok = couch_config:set("httpd", Field, Addr), 63 | etap:is( 64 | couch_config:get("httpd", Field), 65 | Addr, 66 | "Asking for a persistent key/value pair doesn't choke." 67 | ), 68 | 69 | ok. 70 | -------------------------------------------------------------------------------- /test/etap/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | SET(TEST_FILES 2 | 001-load.t 3 | 002-write-guard.t 4 | 010-file-basics.t 5 | 011-file-headers.t 6 | 020-btree-basics.t 7 | 021-btree-reductions.t 8 | 022-btree-copy.t 9 | 023-btree-guided-purge.t 10 | 024-btree-guided-fold.t 11 | 030-doc-from-json.t 12 | 031-doc-to-json.t 13 | 032-doc-to-binary-views.t 14 | 033-doc-from-binary.t 15 | 040-util.t 16 | 041-uuid-gen.t 17 | 042-work-queue.t 18 | 070-couch-db.t 19 | #071-couch-db-external-write.t 20 | 073-changes.t 21 | 080-config-get-set.t 22 | 081-config-override.t 23 | 082-config-register.t 24 | 083-config-no-files.t 25 | 090-task-status.t 26 | 100-ref-counter.t 27 | 150-invalid-view-seq.t 28 | 190-json-stream-parse.t 29 | 201-view-group-shutdown.t 30 | 202-dev-view-group-shutdown.t) 31 | 32 | FOREACH (it ${TEST_FILES}) 33 | GET_FILENAME_COMPONENT(testname ${it} NAME_WE) 34 | GET_FILENAME_COMPONENT(fullpath ${it} REALPATH) 35 | ADD_TEST(couchdb-etap-${testname} python3 ${COUCHDB_RUNTEST} 36 | -c ${COUCHSTORE_BIN_PATH} -p ${COUCHDB_BIN_PATH}/src 37 | -e ${ESCRIPT_EXECUTABLE} -t ${fullpath} --verbose) 38 | ENDFOREACH (it) 39 | 40 | CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/test_util.erl.in 41 | ${CMAKE_CURRENT_BINARY_DIR}/test_util.erl) 42 | 43 | 44 | CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/run.tpl 45 | ${CMAKE_CURRENT_BINARY_DIR}/run) 46 | 47 | ERL_BUILD(APPNAME "etap_test" 48 | SOURCES test_web.erl misc.erl ${CMAKE_CURRENT_BINARY_DIR}/test_util.erl) 49 | -------------------------------------------------------------------------------- /test/etap/misc.erl: -------------------------------------------------------------------------------- 1 | % Licensed under the Apache License, Version 2.0 (the "License"); you may not 2 | % use this file except in compliance with the License. You may obtain a copy of 3 | % the License at 4 | % 5 | % http://www.apache.org/licenses/LICENSE-2.0 6 | % 7 | % Unless required by applicable law or agreed to in writing, software 8 | % distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 9 | % WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | % License for the specific language governing permissions and limitations under 11 | % the License. 12 | 13 | -module(misc). 14 | 15 | -export([is_ipv6/0, 16 | get_net_family/0, 17 | localhost/2]). 18 | 19 | % This is a fake misc service (provided by ns_server in couchbase stack) 20 | % This is used only in standalone couchdb unit tests 21 | 22 | is_ipv6() -> 23 | case os:getenv("ipv6") of 24 | "true" -> true; 25 | _ -> false 26 | end. 27 | 28 | get_net_family() -> 29 | case is_ipv6() of 30 | true -> inet6; 31 | false -> inet 32 | end. 33 | 34 | localhost(inet, _Options) -> "127.0.0.1"; 35 | localhost(inet6, [url]) -> "[::1]"; 36 | localhost(inet6, []) -> "::1". 37 | -------------------------------------------------------------------------------- /test/etap/random_port.ini: -------------------------------------------------------------------------------- 1 | ; Licensed to the Apache Software Foundation (ASF) under one 2 | ; or more contributor license agreements. See the NOTICE file 3 | ; distributed with this work for additional information 4 | ; regarding copyright ownership. The ASF licenses this file 5 | ; to you under the Apache License, Version 2.0 (the 6 | ; "License"); you may not use this file except in compliance 7 | ; with the License. You may obtain a copy of the License at 8 | ; 9 | ; http://www.apache.org/licenses/LICENSE-2.0 10 | ; 11 | ; Unless required by applicable law or agreed to in writing, 12 | ; software distributed under the License is distributed on an 13 | ; "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | ; KIND, either express or implied. See the License for the 15 | ; specific language governing permissions and limitations 16 | ; under the License. 17 | 18 | [httpd] 19 | port = 0 20 | 21 | [dcp] 22 | port = 0 23 | -------------------------------------------------------------------------------- /test/etap/run.tpl: -------------------------------------------------------------------------------- 1 | #!/bin/sh -e 2 | 3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may not 4 | # use this file except in compliance with the License. You may obtain a copy of 5 | # the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | # License for the specific language governing permissions and limitations under 13 | # the License. 14 | 15 | SRCDIR="@abs_top_srcdir@" 16 | BUILDDIR="@abs_top_builddir@" 17 | export ERL_LIBS="$BUILDDIR/src/:$ERL_LIBS" 18 | export ERL_FLAGS="$ERL_FLAGS -pa $BUILDDIR/test/etap/ -pa $BUILDDIR/src/mapreduce/ -pa $BUILDDIR/src/couch_index_merger/ -pa $BUILDDIR/src/couch_view_parser/" 19 | 20 | if test $# -eq 1; then 21 | if test "x${ETAP_VERBOSE}" != "x"; then 22 | OPTS="-v" 23 | else 24 | OPTS="" 25 | fi 26 | TGT=$1 27 | else 28 | OPTS=$1 29 | TGT=$2 30 | fi 31 | 32 | if test -f $TGT; then 33 | prove $OPTS $TGT 34 | else 35 | prove $OPTS $TGT/*.t 36 | fi 37 | -------------------------------------------------------------------------------- /test/etap/test_cfg_register.c: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the "License"); you may not 2 | // use this file except in compliance with the License. You may obtain a copy of 3 | // the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 9 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | // License for the specific language governing permissions and limitations under 11 | // the License. 12 | 13 | #include 14 | #include 15 | 16 | int 17 | main(int argc, const char * argv[]) 18 | { 19 | char c = '\0'; 20 | size_t num = 1; 21 | 22 | fprintf(stdout, "[\"register\", \"s1\"]\n"); 23 | fprintf(stdout, "[\"register\", \"s2\", \"k\"]\n"); 24 | fflush(stdout); 25 | 26 | while(c != '\n' && num > 0) { 27 | num = fread(&c, 1, 1, stdin); 28 | } 29 | 30 | exit(0); 31 | } 32 | -------------------------------------------------------------------------------- /test/etap/test_util.erl.in: -------------------------------------------------------------------------------- 1 | % Licensed under the Apache License, Version 2.0 (the "License"); you may not 2 | % use this file except in compliance with the License. You may obtain a copy of 3 | % the License at 4 | % 5 | % http://www.apache.org/licenses/LICENSE-2.0 6 | % 7 | % Unless required by applicable law or agreed to in writing, software 8 | % distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 9 | % WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | % License for the specific language governing permissions and limitations under 11 | % the License. 12 | 13 | -module(test_util). 14 | 15 | -export([init_code_path/0]). 16 | -export([source_file/1, build_file/1, config_files/0]). 17 | -export([run/2]). 18 | -export([request/3, request/4]). 19 | 20 | -define(REQ_TIMEOUT, 30000). 21 | 22 | srcdir() -> 23 | "@abs_top_srcdir@". 24 | 25 | builddir() -> 26 | "@abs_top_builddir@". 27 | 28 | init_code_path() -> 29 | Paths = [ 30 | "etap", 31 | "couchdb", 32 | "ejson", 33 | "erlang-oauth", 34 | "lhttpc", 35 | "mochiweb", 36 | "snappy" 37 | ], 38 | lists:foreach(fun(Name) -> 39 | code:add_patha(filename:join([builddir(), "src", Name])) 40 | end, Paths). 41 | 42 | source_file(Name) -> 43 | filename:join([srcdir(), Name]). 44 | 45 | build_file(Name) -> 46 | filename:join([builddir(), Name]). 47 | 48 | config_files() -> 49 | [ 50 | build_file("etc/couchdb/default_dev.ini"), 51 | source_file("test/etap/random_port.ini"), 52 | build_file("etc/couchdb/local_dev.ini") 53 | ]. 54 | 55 | 56 | run(Plan, Fun) -> 57 | test_util:init_code_path(), 58 | etap:plan(Plan), 59 | case (catch Fun()) of 60 | ok -> 61 | etap:end_tests(); 62 | Other -> 63 | etap:diag(io_lib:format("Test died abnormally:~n~p", [Other])), 64 | timer:sleep(500), 65 | etap:bail(Other) 66 | end, 67 | ok. 68 | 69 | 70 | request(Url, Headers, Method) -> 71 | request(Url, Headers, Method, []). 72 | 73 | request(Url, Headers, Method, Body) -> 74 | request(Url, Headers, Method, Body, 3). 75 | 76 | request(_Url, _Headers, _Method, _Body, 0) -> 77 | {error, request_failed}; 78 | request(Url, Headers, Method, Body, N) -> 79 | case code:is_loaded(lhttpc) of 80 | false -> 81 | _ = ssl:start(), 82 | ok = lhttpc:start(); 83 | _ -> 84 | ok 85 | end, 86 | case lhttpc:request(Url, Method, Headers, Body, ?REQ_TIMEOUT) of 87 | {ok, {{Code, _}, RespHeaders, RespBody}} -> 88 | {ok, Code, RespHeaders, RespBody}; 89 | {error, connection_closed} -> 90 | % Connection closed right after a successful request that 91 | % used the same connection. 92 | request(Url, Headers, Method, Body, N - 1); 93 | Error -> 94 | Error 95 | end. 96 | -------------------------------------------------------------------------------- /test/functional_test/00-setup.t: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env escript 2 | %% @author Couchbase 3 | %% @copyright 2018 Couchbase, Inc. 4 | %% 5 | %% Licensed under the Apache License, Version 2.0 (the "License"); 6 | %% you may not use this file except in compliance with the License. 7 | %% You may obtain a copy of the License at 8 | %% 9 | %% http://www.apache.org/licenses/LICENSE-2.0 10 | %% 11 | %% Unless required by applicable law or agreed to in writing, software 12 | %% distributed under the License is distributed on an "AS IS" BASIS, 13 | %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | %% See the License for the specific language governing permissions and 15 | %% limitations under the License. 16 | 17 | main(_) -> 18 | %% test depends on port 9000 to port 9003 running 19 | %% check if all ports are running or not 20 | %% it will give econnrefused error when cluster_run is not running 21 | case cluster_ops:check_cluster_ports() of 22 | ok -> 23 | etap:plan(1), 24 | case (catch test()) of 25 | ok -> 26 | etap:end_tests(); 27 | Other -> 28 | etap:diag(io_lib:format("Test died abnormally: ~p", [Other])), 29 | etap:bail(Other) 30 | end; 31 | Reason -> 32 | etap:plan({skip, Reason}) 33 | end. 34 | 35 | test() -> 36 | Ok = cluster_ops:init_setup(), 37 | etap:is_ok(Ok, "Cluster setup done"). 38 | -------------------------------------------------------------------------------- /test/functional_test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/run.tpl 2 | ${CMAKE_CURRENT_BINARY_DIR}/run) 3 | 4 | SET(TEST_FILES 5 | 00-setup.t 6 | 01-node_to_node_encryption_test.t) 7 | 8 | 9 | FOREACH (it ${TEST_FILES}) 10 | GET_FILENAME_COMPONENT(testname ${it} NAME_WE) 11 | GET_FILENAME_COMPONENT(fullpath ${it} REALPATH) 12 | ADD_TEST(functional_test-${testname} python3 13 | ${COUCHDB_RUNTEST} -c ${COUCHSTORE_BIN_PATH} -p ${COUCHDB_BIN_PATH}/src 14 | -e ${ESCRIPT_EXECUTABLE} -t ${fullpath} --verbose) 15 | ENDFOREACH (it) 16 | 17 | ERL_BUILD(APPNAME "bucket_ops" SOURCES bucket_ops.erl) 18 | ERL_BUILD(APPNAME "cluster_ops" SOURCES cluster_ops.erl) 19 | -------------------------------------------------------------------------------- /test/functional_test/defs.hrl: -------------------------------------------------------------------------------- 1 | %% @author Couchbase 2 | %% @copyright 2018 Couchbase, Inc. 3 | %% 4 | %% Licensed under the Apache License, Version 2.0 (the "License"); 5 | %% you may not use this file except in compliance with the License. 6 | %% You may obtain a copy of the License at 7 | %% 8 | %% http://www.apache.org/licenses/LICENSE-2.0 9 | %% 10 | %% Unless required by applicable law or agreed to in writing, software 11 | %% distributed under the License is distributed on an "AS IS" BASIS, 12 | %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | %% See the License for the specific language governing permissions and 14 | %% limitations under the License. 15 | 16 | -define(NODE_INIT_URL, "127.0.0.1:9000/nodes/self/controller/settings"). 17 | -define(NODE_RENAME_URL, "127.0.0.1:9000/node/controller/rename"). 18 | -define(CREATE_BUCKET_URL, "127.0.0.1:9000/pools/default/buckets"). 19 | -define(NODE_CRUD_SETUP_URL, "127.0.0.1:9000/settings/web"). 20 | -define(SERVICE_SETUP_URL, "127.0.0.1:9000/node/controller/setupServices"). 21 | -define(QUOTA_SETUP_URL, "127.0.0.1:9000/pools/default"). 22 | -define(ADD_NODE_URL, "127.0.0.1:9000/controller/addNode"). 23 | -define(REBALANCE_URL, "127.0.0.1:9000/controller/rebalance"). 24 | -define(CLUSTER_INFO, "127.0.0.1:9000/pools/default"). 25 | -define(REBALANCE_PROGRESS_URL, "127.0.0.1:9000/pools/default/rebalanceProgress"). 26 | -define(DOC_OPS, "127.0.0.1:9000/pools/default/buckets/"). 27 | -define(VIEW_URL, "127.0.0.1:9500/"). 28 | -define(SECURITY_URL, "127.0.0.1:9000/settings/security"). 29 | -define(DIAG_EVAL, "127.0.0.1:9001/diag/eval"). 30 | 31 | -define(DEFAULT_BUCKET, "Couch_Test"). 32 | -define(USERNAME, "Administrator"). 33 | -define(PASSWORD, "asdasd"). 34 | -define(BUCKET_QUOTA, "1024"). 35 | -------------------------------------------------------------------------------- /test/functional_test/run.tpl: -------------------------------------------------------------------------------- 1 | #!/bin/sh -e 2 | 3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may not 4 | # use this file except in compliance with the License. You may obtain a copy of 5 | # the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | # License for the specific language governing permissions and limitations under 13 | # the License. 14 | 15 | BUILDDIR="@abs_top_builddir@" 16 | export ERL_FLAGS="$ERL_FLAGS -pa $BUILDDIR/src/mapreduce/" 17 | 18 | $BUILDDIR/test/etap/run $@ 19 | -------------------------------------------------------------------------------- /test/javascript/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/run.tpl 2 | ${CMAKE_CURRENT_BINARY_DIR}/run) 3 | -------------------------------------------------------------------------------- /test/javascript/cli_runner.js: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the "License"); you may not 2 | // use this file except in compliance with the License. You may obtain a copy of 3 | // the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 9 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | // License for the specific language governing permissions and limitations under 11 | // the License. 12 | 13 | var console = { 14 | log: function(arg) { 15 | var msg = (arg.toString()).replace(/\n/g, "\n "); 16 | print("# " + msg); 17 | } 18 | }; 19 | 20 | function T(arg1, arg2) { 21 | if(!arg1) { 22 | throw((arg2 ? arg2 : arg1).toString()); 23 | } 24 | } 25 | 26 | function runTestConsole(num, name, func) { 27 | try { 28 | func(); 29 | print("ok " + num + " " + name); 30 | } catch(e) { 31 | msg = e.toString(); 32 | msg = msg.replace(/\n/g, "\n "); 33 | print("not ok " + num + " " + name + " " + msg); 34 | } 35 | } 36 | 37 | function runAllTestsConsole() { 38 | var numTests = 0; 39 | for(var t in couchTests) { numTests += 1; } 40 | print("1.." + numTests); 41 | var testId = 0; 42 | for(var t in couchTests) { 43 | testId += 1; 44 | runTestConsole(testId, t, couchTests[t]); 45 | } 46 | }; 47 | 48 | try { 49 | runAllTestsConsole(); 50 | } catch (e) { 51 | p("# " + e.toString()); 52 | } 53 | -------------------------------------------------------------------------------- /test/javascript/couch_http.js: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the "License"); you may not 2 | // use this file except in compliance with the License. You may obtain a copy of 3 | // the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 9 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | // License for the specific language governing permissions and limitations under 11 | // the License. 12 | 13 | (function() { 14 | CouchHTTP.prototype.base_url = "http://127.0.0.1:5984" 15 | 16 | if(typeof(CouchHTTP) != "undefined") { 17 | CouchHTTP.prototype.open = function(method, url, async) { 18 | if(!/^\s*http:\/\//.test(url)) { 19 | if(/^[^\/]/.test(url)) { 20 | url = this.base_url + "/" + url; 21 | } else { 22 | url = this.base_url + url; 23 | } 24 | } 25 | 26 | return this._open(method, url, async); 27 | }; 28 | 29 | CouchHTTP.prototype.setRequestHeader = function(name, value) { 30 | // Drop content-length headers because cURL will set it for us 31 | // based on body length 32 | if(name.toLowerCase().replace(/^\s+|\s+$/g, '') != "content-length") { 33 | this._setRequestHeader(name, value); 34 | } 35 | } 36 | 37 | CouchHTTP.prototype.send = function(body) { 38 | this._send(body || ""); 39 | var headers = {}; 40 | this._headers.forEach(function(hdr) { 41 | var pair = hdr.split(":"); 42 | var name = pair.shift(); 43 | headers[name] = pair.join(":").replace(/^\s+|\s+$/g, ""); 44 | }); 45 | this.headers = headers; 46 | }; 47 | 48 | CouchHTTP.prototype.getResponseHeader = function(name) { 49 | for(var hdr in this.headers) { 50 | if(hdr.toLowerCase() == name.toLowerCase()) { 51 | return this.headers[hdr]; 52 | } 53 | } 54 | return null; 55 | }; 56 | } 57 | })(); 58 | 59 | CouchDB.urlPrefix = ""; 60 | CouchDB.newXhr = function() { 61 | return new CouchHTTP(); 62 | }; 63 | -------------------------------------------------------------------------------- /test/javascript/run.tpl: -------------------------------------------------------------------------------- 1 | #!/bin/sh -e 2 | 3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may not 4 | # use this file except in compliance with the License. You may obtain a copy of 5 | # the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | # License for the specific language governing permissions and limitations under 13 | # the License. 14 | 15 | SRC_DIR=@abs_top_srcdir@ 16 | SCRIPT_DIR=$SRC_DIR/share/www/script 17 | JS_TEST_DIR=$SRC_DIR/test/javascript 18 | 19 | COUCHJS=@abs_top_srcdir@/src/couchdb/priv/couchjs 20 | 21 | if [ "$#" -eq 0 ]; 22 | then 23 | TEST_SRC="$SCRIPT_DIR/test/*.js" 24 | else 25 | TEST_SRC="$1" 26 | if [ ! -f $TEST_SRC ]; then 27 | TEST_SRC="$SCRIPT_DIR/test/$1" 28 | if [ ! -f $TEST_SRC ]; then 29 | TEST_SRC="$SCRIPT_DIR/test/$1.js" 30 | if [ ! -f $TEST_SRC ]; then 31 | echo "file $1 does not exist" 32 | exit 33 | fi 34 | fi 35 | fi 36 | fi 37 | 38 | cat $SCRIPT_DIR/json2.js \ 39 | $SCRIPT_DIR/sha1.js \ 40 | $SCRIPT_DIR/oauth.js \ 41 | $SCRIPT_DIR/couch.js \ 42 | $SCRIPT_DIR/couch_test_runner.js \ 43 | $SCRIPT_DIR/couch_tests.js \ 44 | $TEST_SRC \ 45 | $JS_TEST_DIR/couch_http.js \ 46 | $JS_TEST_DIR/cli_runner.js \ 47 | | $COUCHJS -H - 48 | -------------------------------------------------------------------------------- /test/python/lib/couchdb/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # Copyright (C) 2007 Christopher Lenz 4 | # All rights reserved. 5 | # 6 | # This software is licensed as described in the file COPYING, which 7 | # you should have received as part of this distribution. 8 | 9 | from couchdb.client import Database, Document, Server 10 | from couchdb.http import HTTPError, PreconditionFailed, Resource, \ 11 | ResourceConflict, ResourceNotFound, ServerError, Session, Unauthorized 12 | 13 | try: 14 | __version__ = __import__('pkg_resources').get_distribution('CouchDB').version 15 | except: 16 | __version__ = '?' 17 | -------------------------------------------------------------------------------- /test/python/set_view/include_docs.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | try: import simplejson as json 4 | except ImportError: import json 5 | import couchdb 6 | import httplib 7 | import urllib 8 | import common 9 | import unittest 10 | 11 | 12 | HOST = "localhost:5984" 13 | SET_NAME = "test_suite_set_view_compact" 14 | NUM_PARTS = 4 15 | NUM_DOCS = 40000 16 | DDOC = { 17 | "_id": "_design/test", 18 | "language": "javascript", 19 | "views": { 20 | "mapview1": { 21 | "map": "function(doc) { emit(doc.integer, doc.string); }" 22 | } 23 | } 24 | } 25 | 26 | 27 | class TestIncludeDocs(unittest.TestCase): 28 | 29 | def setUp(self): 30 | self._params = { 31 | "host": HOST, 32 | "ddoc": DDOC, 33 | "nparts": NUM_PARTS, 34 | "ndocs": NUM_DOCS, 35 | "setname": SET_NAME, 36 | "server": couchdb.Server(url = "http://" + HOST) 37 | } 38 | # print "Creating databases" 39 | common.create_dbs(self._params) 40 | common.populate( 41 | self._params, 42 | make_doc = lambda i: {"_id": str(i), "integer": i, "string": str(i)} 43 | ) 44 | common.define_set_view(self._params, range(NUM_PARTS), []) 45 | # print "Databases created" 46 | 47 | 48 | def tearDown(self): 49 | # print "Deleting test data" 50 | common.create_dbs(self._params, True) 51 | 52 | 53 | def test_include_docs(self): 54 | # print "Querying map view" 55 | (map_resp, map_view_result) = common.query(self._params, "mapview1", {"include_docs": "true"}) 56 | map_etag = map_resp.getheader("ETag") 57 | 58 | self.assertEqual(map_view_result["total_rows"], self._params["ndocs"], 59 | "Query returned %d total_rows" % self._params["ndocs"]) 60 | self.assertEqual(len(map_view_result["rows"]), self._params["ndocs"], 61 | "Query returned %d rows" % self._params["ndocs"]) 62 | 63 | common.test_keys_sorted(map_view_result) 64 | 65 | for row in map_view_result["rows"]: 66 | self.assertTrue("doc" in row, 'row has a "doc" property') 67 | doc = row["doc"] 68 | self.assertEqual(doc["integer"], row["key"], "doc.integer same as row.key") 69 | self.assertEqual(doc["string"], str(row["key"]), "doc.string same as String(row.key)") 70 | -------------------------------------------------------------------------------- /test/python/set_view/run.py.tpl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import sys 4 | sys.path.insert(0, "${CMAKE_CURRENT_BINARY_DIR}/test/python/lib") 5 | sys.path.insert(0, "${CMAKE_CURRENT_BINARY_DIR}/test/python/set_view") 6 | sys.path.insert(0, "${CMAKE_CURRENT_BINARY_DIR}/test/python/set_view/common") 7 | import unittest 8 | from subprocess import call 9 | from time import sleep 10 | 11 | # set view test files 12 | from include_docs import TestIncludeDocs 13 | from stale import TestStale 14 | from updates import TestUpdates 15 | from passive_partitions import TestPassivePartitions 16 | from passive_partitions_update import TestPassivePartitionsUpdate 17 | from cleanup import TestCleanup 18 | from compaction import TestCompaction 19 | from compaction_transitions import TestCompactionTransitions 20 | from update_cleanup import TestUpdateCleanup 21 | from filter_partitions import TestFilterPartitions 22 | from view_merge import TestViewMerge 23 | from burst_state_updates import TestBurstStateUpdates 24 | from many_partitions import TestManyPartitions 25 | from erlang_views import TestErlangViews 26 | from replica_index import TestReplicaIndex 27 | from view_params import TestViewParams 28 | 29 | 30 | def stop_couch(): 31 | call(["${CMAKE_CURRENT_BINARY_DIR}/utils/run", "-d"]) 32 | 33 | def start_couch(): 34 | stop_couch() 35 | call(["${CMAKE_CURRENT_BINARY_DIR}/utils/run", "-b"]) 36 | sleep(5) 37 | 38 | 39 | def main(): 40 | print "\nStarting set view tests\n" 41 | suite = unittest.TestSuite() 42 | 43 | suite.addTest(unittest.makeSuite(TestIncludeDocs)) 44 | suite.addTest(unittest.makeSuite(TestStale)) 45 | suite.addTest(unittest.makeSuite(TestViewParams)) 46 | suite.addTest(unittest.makeSuite(TestUpdates)) 47 | suite.addTest(unittest.makeSuite(TestManyPartitions)) 48 | suite.addTest(unittest.makeSuite(TestPassivePartitions)) 49 | suite.addTest(unittest.makeSuite(TestPassivePartitionsUpdate)) 50 | suite.addTest(unittest.makeSuite(TestCleanup)) 51 | suite.addTest(unittest.makeSuite(TestCompaction)) 52 | suite.addTest(unittest.makeSuite(TestCompactionTransitions)) 53 | suite.addTest(unittest.makeSuite(TestUpdateCleanup)) 54 | suite.addTest(unittest.makeSuite(TestFilterPartitions)) 55 | suite.addTest(unittest.makeSuite(TestViewMerge)) 56 | suite.addTest(unittest.makeSuite(TestBurstStateUpdates)) 57 | # Only JavaScript is supported at the moment (and actually faster 58 | # than erlang views). 59 | # suite.addTest(unittest.makeSuite(TestErlangViews)) 60 | suite.addTest(unittest.makeSuite(TestReplicaIndex)) 61 | 62 | start_couch() 63 | result = None 64 | 65 | try: 66 | result = unittest.TextTestRunner(verbosity = 2).run(suite) 67 | finally: 68 | stop_couch() 69 | 70 | print "\nFinished execution of the set view tests\n" 71 | sys.exit(len(result.failures) + len(result.errors)) 72 | 73 | 74 | main() 75 | -------------------------------------------------------------------------------- /test/view_server/run_native_process.es: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env escript 2 | 3 | % Licensed under the Apache License, Version 2.0 (the "License"); you may not 4 | % use this file except in compliance with the License. You may obtain a copy of 5 | % the License at 6 | % 7 | % http://www.apache.org/licenses/LICENSE-2.0 8 | % 9 | % Unless required by applicable law or agreed to in writing, software 10 | % distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | % WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | % License for the specific language governing permissions and limitations under 13 | % the License. 14 | 15 | read() -> 16 | case io:get_line('') of 17 | eof -> stop; 18 | Data -> couch_util:json_decode(Data) 19 | end. 20 | 21 | send(Data) when is_binary(Data) -> 22 | send(binary_to_list(Data)); 23 | send(Data) when is_list(Data) -> 24 | io:format(Data ++ "\n", []). 25 | 26 | write(Data) -> 27 | % log("~p", [Data]), 28 | case (catch couch_util:json_encode(Data)) of 29 | % when testing, this is what prints your errors 30 | {json_encode, Error} -> write({[{<<"error">>, Error}]}); 31 | Json -> send(Json) 32 | end. 33 | 34 | % log(Mesg) -> 35 | % log(Mesg, []). 36 | % log(Mesg, Params) -> 37 | % io:format(standard_error, Mesg, Params). 38 | % jlog(Mesg) -> 39 | % write([<<"log">>, list_to_binary(io_lib:format("~p",[Mesg]))]). 40 | 41 | loop(Pid) -> 42 | case read() of 43 | stop -> ok; 44 | Json -> 45 | case (catch couch_native_process:prompt(Pid, Json)) of 46 | {error, Reason} -> 47 | ok = write([error, Reason, Reason]); 48 | Resp -> 49 | ok = write(Resp), 50 | loop(Pid) 51 | end 52 | end. 53 | 54 | main([]) -> 55 | code:add_pathz("src/couchdb"), 56 | code:add_pathz("src/mochiweb"), 57 | {ok, Pid} = couch_native_process:start_link(), 58 | loop(Pid). 59 | 60 | --------------------------------------------------------------------------------