couchdb-setup.sh
#!/bin/bash
# Function for upsert of design & other configuration docs
upsert_doc() {
DB=$1
DOC_NAME=$2
DOC_LOC=$3
# Default method is PUT, fourth argument overrides
METHOD=${4:-"PUT"}
DOC=$(curl $COUCHURL/$DB/$DOC_NAME $PROXYHEADER)
# If DOC includes a rev then it exists so we need to update
# Otherwise we simply insert
if [[ $DOC == *rev* ]]; then
DOC_REV=$(echo $DOC | jq -r '. | ._rev')
curl -H 'Content-Type: application/json' -X $METHOD $COUCHURL/$DB/$DOC_NAME?rev=$DOC_REV -d $DOC_LOC $PROXYHEADER
else
curl -H 'Content-Type: application/json' -X $METHOD $COUCHURL/$DB/$DOC_NAME -d $DOC_LOC $PROXYHEADER
fi
}
# Function for insert mock data docs
insert_docs() {
DB=$1
DOC_LOC=$2
curl -H 'Content-Type: application/json' -X POST $COUCHURL/$DB/_bulk_docs -d @$DOC_LOC $PROXYHEADER
}
# Function to add databases
insert_dbs() {
DBS=$1
for DB in "${DBS[@]}"
do
curl -X PUT $COUCHURL/$DB $PROXYHEADER
done
}
set_couch_per_user() {
CONFIGURATION=$(curl "$COUCHURL/configurations/_all_docs?include_docs=true" $PROXYHEADER)
CODE=$(echo $CONFIGURATION | jq -rj '.["rows"][0]["doc"]["code"] // empty')
HEXCODE=$(echo $CODE | tr -d \\n | hexdump -v -e '/1 "%02x"')
upsert_doc _node/nonode@nohost/_config couch_peruser/database_prefix '"userdb-'$HEXCODE'-"'
upsert_doc _node/nonode@nohost/_config couch_peruser/delete_dbs '"true"'
upsert_doc _node/nonode@nohost/_config couch_peruser/enable '"true"'
}
# Options are -u for username -w for passWord and -p for port number
while getopts "u:w:p:h:ix" option; do
case $option in
u) COUCHUSER=${OPTARG};;
w) COUCHPASSWORD=${OPTARG};;
p) PORT=${OPTARG};;
h) HOST=${OPTARG};;
i) INSTALLFLAG=1;;
x) PROXYHEADER="-H X-Auth-CouchDB-Roles:_admin -H X-Auth-CouchDB-UserName:username";;
esac
done
ISINSTALL=${INSTALLFLAG:-0}
if [ -z "$HOST" ]
then
HOST=127.0.0.1
fi
# Default port for CouchDB accessed from host machine is 2200
PORT=${PORT:-2200}
if [ -z "$COUCHUSER" ]
then
COUCHURL=http://$HOST:$PORT
else
COUCHURL=http://$COUCHUSER:$COUCHPASSWORD@$HOST:$PORT
fi
# Adding attachments to database documents
# To add attachment added two file (resources-mock.json and resources-attachment-mockup.json)
# Ids must match between two files
insert_attachments() {
DB=$1
DOC_LOC=$2
# Use echo $(<$DOC_LOC) to be able to run in Windows
INPUTS=$(echo $(<$DOC_LOC) | jq -c '.[]')
for i in $INPUTS
do
ID=$(echo $i | jq -r '.doc_id' )
FILE_NAME=$(echo $i | jq -r '.file_name')
FILE_LOCATION=$(echo $i | jq -r '.file_location')
FILE_TYPE=$(echo $i | jq -r '.file_type')
REV=$(curl $COUCHURL/$DB/$ID | jq -r '._rev' $PROXYHEADER)
curl -X PUT $COUCHURL/$DB/$ID/$FILE_NAME?rev=$REV --data-binary @$FILE_LOCATION -H Content-Type:$FILE_TYPE $PROXYHEADER
done
}
# Reads one JSON file to update multiple databases
# JSON file needs a 'dbName' field with a string and
# a 'json' field with the JSON to be updated
multi_db_update() {
DOC_LOC=$1
DOC_NAME=$2
INPUTS=$(echo $DOC_LOC | jq -c '.[]')
for i in $INPUTS
do
JSON=$(echo $i | jq -c '. | .json' )
DB_NAME=$(echo $i | jq -r '. | .dbName')
upsert_doc $DB_NAME $DOC_NAME $JSON
done
}
add_security_admin_roles() {
JSON=$1
ROLE_NAME=$2
NEW_DOCS=$(echo $(<$JSON) | jq '.[].json.admins.roles += ["'$ROLE_NAME'"]')
echo $NEW_DOCS | jq -c '.'
}
DBS=(
# CouchDB standard databases
"_users"
"_replicator"
"_global_changes"
# Planet app databases
"meetups"
"resources"
"courses"
"certifications"
"exams"
"nations"
"communityregistrationrequests"
"feedback"
"resource_activities"
"configurations"
"login_activities"
"notifications"
"ratings"
"shelf"
"submissions"
"courses_progress"
"attachments"
"send_items"
"teams"
"tablet_users"
"child_users"
"replicator_users"
"admin_activities"
"child_statistics"
"tags"
"apk_logs"
"hubs"
"achievements"
"myplanet_activities"
"news"
"parent_users"
"team_activities"
"tasks"
"health"
"messages"
"course_activities"
"search_activities"
"community_meetups"
"chat_history"
)
insert_dbs $DBS
# Create design documents
node ./design/create-design-docs.js
# Add or update design docs
upsert_doc nations _design/nation-validators @./design/nations/nation-validators.json
upsert_doc resources _design/resources @./design/resources/resources-design.json
upsert_doc health _design/health @./design/health/health-design.json
upsert_doc _users _design/_auth @./design/users/_auth.json
upsert_doc resource_activities _design/resource_activities @./design/activities/activities-design.json
upsert_doc login_activities _design/login_activities @./design/activities/activities-design.json
upsert_doc courses_progress _design/courses_progress @./design/courses_progress/courses_progress-design.json
# Insert indexes
# Note indexes will not overwrite if fields value changes, so make sure to remove unused indexes after changing
upsert_doc login_activities _index '{"index":{"fields":[{"loginTime":"desc"}]},"name":"time-index"}' POST
upsert_doc notifications _index '{"index":{"fields":[{"time":"desc"}]},"name":"time-index"}' POST
upsert_doc ratings _index '{"index":{"fields":[{"item":"desc"}]},"name":"parent-index"}' POST
upsert_doc feedback _index '{"index":{"fields":[{"openTime":"desc"}]},"name":"time-index"}' POST
upsert_doc communityregistrationrequests _index '{"index":{"fields":[{"createdDate":"desc"}]},"name":"time-index"}' POST
upsert_doc resources _index '{"index":{"fields":[{"title":"asc"}]},"name":"time-index"}' POST
upsert_doc news _index '{"index":{"fields":[{"time":"desc"}]},"name":"time-index"}' POST
upsert_doc tags _index '{"index":{"fields":[{"name":"asc"}]},"name":"name-index"}' POST
upsert_doc team_activities _index '{"index":{"fields":[{"time":"desc"}]},"name":"time-index"}' POST
# Only insert dummy data and update security on install
# _users security is set in app and auto accept will be overwritten if set here
if (($ISINSTALL))
then
# Insert dummy data docs
insert_docs meetups ./design/meetups/meetups-mockup.json
insert_docs courses ./design/courses/courses-mockup.json
insert_docs resources ./design/resources/resources-mockup.json
insert_attachments resources ./design/resources/resources-attachment-mockup.json
# When attachment database is implemented in app, uncomment below line and delete above line
# insert_attachments attachments ./design/resources/resources-attachment-mockup.json
# Add permission in databases
SECURITY=$(add_security_admin_roles ./design/security-update/security-update-once.json manager)
multi_db_update $SECURITY _security
fi
SECURITY=$(add_security_admin_roles ./design/security-update/security-update.json manager)
multi_db_update $SECURITY _security
set_couch_per_user
# Increase session timeout
upsert_doc _node/nonode@nohost/_config couch_httpd_auth/timeout '"2400"'
# Increse http request size for large attachments
upsert_doc _node/nonode@nohost/_config httpd/max_http_request_size '"1073741824"'
# Increse replication timeout
upsert_doc _node/nonode@nohost/_config replicator/connection_timeout '"300000"'
# Make user database public
upsert_doc _node/nonode@nohost/_config couch_httpd_auth/users_db_public '"true"'
# Specify user public fields (note: adding spaces to string breaks upsert_doc)
upsert_doc _node/nonode@nohost/_config couch_httpd_auth/public_fields '"name,firstName,middleName,lastName,roles,isUserAdmin,joinDate,email,phoneNumber,gender,planetCode,parentCode,language,birthDate,level,birthplace"'