utils/kamctl/kamdbctl.db_berkeley
9bbc7f82
 #
ef7704a8
 # $Id$
9bbc7f82
 #
860c33c5
 # Script for maintaining Kamailio Berkeley DB tables
9bbc7f82
 # Copyright (C) 2007 Cisco Systems
 #
860c33c5
 # This file is part of Kamailio, a free SIP server.
9bbc7f82
 #
860c33c5
 # Kamailio is free software; you can redistribute it and/or modify
9bbc7f82
 # it under the terms of the GNU General Public License as published by
 # the Free Software Foundation; either version 2 of the License, or
 # (at your option) any later version
 #
860c33c5
 # Kamailio is distributed in the hope that it will be useful,
9bbc7f82
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU General Public License for more details.
 #
 # You should have received a copy of the GNU General Public License 
 # along with this program; if not, write to the Free Software 
9e1ff448
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
9bbc7f82
 # 
 # History:
 # --------
 # 2007-09-19  genesis (wiquan)
 #
df68a2c2
 
 #constants
 PATH=$PATH:/usr/local/BerkeleyDB.4.6/bin
 DELIM="|"
 BACKUP_CMD="tar czvf "
 RESTORE_CMD="tar xzvf "
 
 #berkeley db utility program that writes out db to plain text
5bf60862
 #small hack to autodetect the db dump command, debian prefix the version..
 
 which db_dump > /dev/null
 ret=$?
 if [ $ret -eq 0 ] ; then
 	DUMP_CMD="db_dump"
 fi ;
 
 which db4.4_dump > /dev/null
 ret=$?
 if [ $ret -eq 0 ] ; then
 	DUMP_CMD="db4.4_dump"
 fi ;
 
 which db4.5_dump > /dev/null
 ret=$?
 if [ $ret -eq 0 ] ; then
 	DUMP_CMD="db4.5_dump"
 fi ;
 
 which db4.6_dump > /dev/null
 ret=$?
 if [ $ret -eq 0 ] ; then
 	DUMP_CMD="db4.6_dump"
 fi ;
 
df68a2c2
 
 #berkeley db utility program that imports data from plain text file
5bf60862
 #small hack to autodetect the db load command, debian prefix the version..
 
 which db_load > /dev/null
 ret=$?
 if [ $ret -eq 0 ] ; then
 	LOAD_CMD="db_load"
 fi ;
 
 which db4.4_load > /dev/null
 ret=$?
 if [ $ret -eq 0 ] ; then
 	LOAD_CMD="db4.4_load"
 fi ;
 
 which db4.5_load > /dev/null
 ret=$?
 if [ $ret -eq 0 ] ; then
 	LOAD_CMD="db4.5_load"
 fi ;
 
 which db4.6_load > /dev/null
 ret=$?
 if [ $ret -eq 0 ] ; then
 	LOAD_CMD="db4.6_load"
 fi ;
df68a2c2
 
 # path to the database schemas
860c33c5
 DATA_DIR="/usr/local/share/kamailio"
 if [ -d "$DATA_DIR/db_berkeley/kamailio" ] ; then
 	DB_SCHEMA="$DATA_DIR/db_berkeley/kamailio"
df68a2c2
 else
860c33c5
 	DB_SCHEMA="./db_berkeley/kamailio"
df68a2c2
 fi
 
78045945
 # path to the db_berkeley database
 if [ -z "$DB_PATH" ]; then
860c33c5
 	DB_PATH="/usr/local/etc/kamailio/db_berkeley"
df68a2c2
 fi
 
78045945
 berkeley_usage() 
df68a2c2
 {
 COMMAND=`basename $0`
 cat <<EOF
860c33c5
 Script for maintaining Kamailio Berkeley DB tables
78045945
        $COMMAND list      (lists the underlying db files in DB_PATH)
        $COMMAND cat       <db>  (db_dump the underlying db file to STDOUT)
        $COMMAND swap      <db>  (installs db.new by db -> db.old; db.new -> db)
        $COMMAND append    <db> <datafile> (appends data to an existing db;output DB_PATH/db.new)
        $COMMAND newappend <db> <datafile> (appends data to a new instance of db; output DB_PATH/db.new)
0328f22f
        $COMMAND export  <dump_dir> (exports table data to plain-txt files in dump_dir)
        $COMMAND import  <dump_dir> (imports plain-txt table data and creates new db tables in db_path)
df68a2c2
 EOF
 } #usage
 
 
78045945
 #
 # 
 #
e102ae72
 kamailio_berkeley()  # parms: <op> <arg1> <arg2>
78045945
 {
 	case $1 in
 		list|ls)
 			ls -l $DB_PATH
 			exit $?
 			;;
 		cat)
 			shift
e102ae72
 			kamailio_cat $1 $DB_PATH
78045945
 			exit $?
 			;;
 
 		swap)
 			shift
e102ae72
 			kamailio_swap $1 $DB_PATH
78045945
 			exit $?
 			;;
 
 		append)
 			shift
e102ae72
 			kamailio_append  $1 $2 $DB_PATH
78045945
 			exit $?
 			;;
 
 		newappend)
 			shift
e102ae72
 			kamailio_newappend  $1 $2 $DB_PATH
78045945
 			exit $?
 			;;
 
0328f22f
 		export)
 			shift
e102ae72
 			kamailio_export  $1 $DB_PATH
0328f22f
 			exit $?
 			;;
 
 		migrate)
 			shift
e102ae72
 			kamailio_migrate $1 $DB_PATH
0328f22f
 			exit $?
 			;;
 
 		import)
 			shift
e102ae72
 			kamailio_import  $1 $DB_PATH
0328f22f
 			exit $?
 			;;
 
78045945
 		*)
 			berkeley_usage
 			exit 1;
 			;;
 esac
 }
 
0328f22f
 
 
 ##
 # EXPORT existing data to plain-txt files in DUMP_DIR
 # eg.  DB_PATH/version ---> DUMP_DIR/version.txt
 #
 # Export is used as part of a DB migration process to another 
 # major version of berkeley db.
e102ae72
 kamailio_export()  # parms: <DUMP_DIR> [DB_PATH]
0328f22f
 {
 	if [ $# -lt 2  ]; then
e102ae72
 		echo  "kamailio_dump parms: <DUMP_DIR> [DB_PATH]"
0328f22f
 		exit 1
 	fi
 	
 	# Assert: the DB_PATH directory should already exist
 	if [ ! -d $2 ] ; then
 		merr "BerkeleyDB directory does not exist at: [$2]"
 		exit 1
 	fi
 	
 	# Assert: DB_PATH directory should already contain table 'version'
 	if [ ! -f $2/version ] ; then
 		merr "BerkeleyDB directory does not have VERSION table at: [$2]"
 		exit 1
 	fi
 	
 	# Create dir at <DUMP_DIR> to store the exported data
 	if [ ! -d $1 ] ; then
 		minfo "creating DUMP_DIR at: [$1]"
 		mkdir -p $1
 	else
 		mdbg "Cleaning out DUMP_DIR to get ready for new data"
 		rm -rf $1/*
 	fi
 	
 	# DUMP_CMD will result in something like this:
 	#
 	#	VERSION=3
 	#	format=print
 	#	type=hash
 	#	h_nelem=2
 	#	db_pagesize=4096
 	#	HEADER=END
 	#	 METADATA_COLUMNS
 	#	 callid(str) method(str) from_tag(str) to_tag(str) sip_code(str) sip_reason(str) time(datetime)
 	#	 METADATA_KEY
 	#	 0
 	#	DATA=END
 	#
 	# However, we are only interested in the indented stuff between 
 	#  'HEADER=END' and 'DATA=END',
 	#  as everything else is DB instance specific. That is, we are interested in this part:
 	#
 	# METADATA_COLUMNS
 	# callid(str) method(str) from_tag(str) to_tag(str) sip_code(str) sip_reason(str) time(datetime)
 	# METADATA_KEY
 	# 0
 	#
 	# The following PERL filter will do this processing.
 	#
 	# perl -pe 's/^\w.*// ; s/^\s(.*)/$1/'
 
 	# Dump the STANDARD tables to plain-text files in DUMP_DIR
 	for TABLE in $STANDARD_TABLES; do
 	    if [ -f $2/$TABLE ] ; then
 		    mdbg "Exporting standard table: $TABLE"
c327195e
 		    $DUMP_CMD -p -h $2 $TABLE  | perl -pe 's/^\w.*// ; s/^\s(.*)/$1/' > $1/$TABLE.txt
0328f22f
 		    
 		    # Check return code to make sure the export worked ok
 		    if [ $? -ne 0 ] ; then
 			merr "Export of standard table failed [$TABLE]"
 			# there was a problem, but it is not something
 			# we can handle here; We can deal with this at import
 			# time.
 		    fi
 	    else
 	    	    mwarn "Table not found: [$TABLE]"
 	    fi
 	done
 	
 	# Dump the PRESENCE tables to plain-text files in DUMP_DIR
 	for TABLE in $PRESENCE_TABLES; do
 	    if [ -f $2/$TABLE ] ; then
 		    mdbg "Exporting presence table: $TABLE"
c327195e
 		    $DUMP_CMD -p -h $2 $TABLE  | perl -pe 's/^\w.*// ; s/^\s(.*)/$1/' > $1/$TABLE.txt
0328f22f
 		    if [ $? -ne 0 ] ; then
 			merr "Export of presence table failed [$TABLE]"
 		    fi
 	    else
 	    	    mwarn "Table not found: [$TABLE]"
 	    fi
 	done
 	
 	# Dump the EXTRA tables to plain-text files in DUMP_DIR
 	for TABLE in $EXTRA_TABLES; do
 	    if [ -f $2/$TABLE ] ; then
 		    mdbg "Exporting extra table: $TABLE"
c327195e
 		    $DUMP_CMD -p -h $2 $TABLE  | perl -pe 's/^\w.*// ; s/^\s(.*)/$1/' > $1/$TABLE.txt
0328f22f
 		    if [ $? -ne 0 ] ; then
 			merr "Export of extra table failed [$TABLE]"
 		    fi
 	    else
 	    	    mwarn "Table not found: [$TABLE]"
 	    fi
 	done
 	
 	mdbg "All tables are now exported to DUMP_DIR: [$1]"
 	return 0
 
 }
 
 
 ##
 # MIGRATE (schema)
 # Examine each plain-txt file in DUMP_DIR
e102ae72
 #  (Assumes that kamailio_export was already invoked)
0328f22f
 #
 # Migrate converts data from schema-old to schema-new in place.
 #
 # After this step is complete the IMPORT should be executed.
e102ae72
 kamailio_migrate()  # parms: <DUMP_DIR> [DB_PATH]
0328f22f
 {
 	merr "db_berkeley migrate not implemented"
 	exit 1
 }
 
 
 ##
 # IMPORT existing plain-txt files from DUMP_DIR to DB_PATH
 # eg.  DUMP_DIR/version.txt  --> DB_PATH/version
 #
 # import is used as part of DB migrate to another major version of berkeley db.
 # this will over-write anything in DB_PATH
e102ae72
 kamailio_import()  # parms: <DUMP_DIR> [DB_PATH]
0328f22f
 {
 	if [ $# -lt 2  ]; then
e102ae72
 		echo  "kamailio_dump parms: <DUMP_DIR> [DB_PATH]"
0328f22f
 		exit 1
 	fi
 	
 	# Assert: DUMP_DIR (source dir) already exists
 	if [ ! -d $1 ] ; then
 		merr "Berkeley DUMP_DIR directory does not exist: [$1]"
 		exit 1;
 	fi
 	
 	# Assert: DUMP_DIR directory should already contain table 'version.txt'
 	if [ ! -f $1/version.txt ] ; then
 		merr "DUMP_DIR directory does not have VERSION.txt data at: [$1]"
 		exit 1
 	fi
 	
 	# Assert: destination dir exists [DB_PATH]
 	if [ ! -d $2 ] ; then
 		mdbg "Berkeley DB_PATH directory is being created: [$2]"
 		mkdir -p $2
 	else
 		# Wipe out the destination dir to make room for new data
 		mwarn "Berkeley DB_PATH directory is being purged at: [$2]"
 		rm -rf $2/*
 	fi
 	
 	# Creates STANDARD tables from plain-text files in DUMP_DIR
 	for TABLE in $STANDARD_TABLES; do
a0954c73
 	    if [ -s $1/$TABLE.txt ] ; then
0328f22f
 		    mdbg "Importing standard table: $TABLE"
c327195e
 		    $LOAD_CMD -T -t hash -f $1/$TABLE.txt -h $2 $TABLE
0328f22f
 		    
 		    # Check return code to make sure the export worked ok
 		    if [ $? -ne 0 ] ; then
 			merr "Import of standard table failed [$TABLE.txt]"
1c07bd7b
 			merr "Create this missing table with kambdb_recover."
0328f22f
 		    fi
 	    else
 	    	    merr "Import data not found for table: [$TABLE.txt]" 
1c07bd7b
 		    merr "Create this missing table with kambdb_recover."
0328f22f
 	    fi
 	done
 	
 
 	# Creates PRESENCE tables from plain-text files in DUMP_DIR
 	for TABLE in $PRESENCE_TABLES; do
a0954c73
 	    if [ -s $1/$TABLE.txt ] ; then
0328f22f
 		    mdbg "Importing presence table: $TABLE"
c327195e
 		    $LOAD_CMD -T -t hash -f $1/$TABLE.txt -h $2 $TABLE
0328f22f
 		    
 		    # Check return code to make sure the export worked ok
 		    if [ $? -ne 0 ] ; then
 			merr "Import of presence table failed [$TABLE.txt]"
1c07bd7b
 			merr "Create this missing table with kambdb_recover."
0328f22f
 		    fi
 	    else
 		    mwarn "Import data not found for table: [$TABLE.txt]"
 	    fi
 	done
 
 	# Creates EXTRA tables from plain-text files in DUMP_DIR
 	for TABLE in $EXTRA_TABLES; do
a0954c73
 	    if [ -s $1/$TABLE.txt ] ; then
0328f22f
 		    mdbg "Importing extra table: $TABLE"
c327195e
 		    $LOAD_CMD -T -t hash -f $1/$TABLE.txt -h $2 $TABLE
0328f22f
 		    
 		    # Check return code to make sure the export worked ok
 		    if [ $? -ne 0 ] ; then
 			merr "Import of extra table failed [$TABLE.txt]"
1c07bd7b
 			merr "Create this missing table with kambdb_recover."
0328f22f
 		    fi
 	    else
 		    mwarn "Import data not found for table: [$TABLE.txt]"
 	    fi
 	done
 	
 	mdbg "All tables are now imported to DB_PATH: [$2]"
 	return 0
 
 }
 
 
e102ae72
 kamailio_swap()  # parms: <db> [DB_PATH]
df68a2c2
 {
 	if [ $# -lt 2  ]; then
e102ae72
 		echo  "kamailio_swap parms: <db> [DB_PATH]"
df68a2c2
 		exit 1
 	fi
 	
 	DB=$2/$1
 	DBNEW=$DB.new
 	DBOLD=$DB.old
 	cp $DB $DBOLD
 	mv $DBNEW $DB
 }
 
 #####
 # append process is:
78045945
 # 1. copy DB_PATH/db to DB_PATH/db.new
 # 2. appends contents of newdata to DB_PATH/db.new
df68a2c2
 #
e102ae72
 kamailio_append()  # parms: <db> <newdata> [DB_PATH]
df68a2c2
 {
 	if [ $# -lt 3  ]; then
e102ae72
 		echo  "kamailio_append parms: <db> <newdata> [DB_PATH]"
df68a2c2
 		exit 1
 	fi
 	
 	DB=$3/$1
 	DBNEW=$DB.new
 	if [ -f $DB.new ] ; then
 		rm $DB.new
 	fi
 	
 	cp $DB $DBNEW
c327195e
 # echo "$LOAD_CMD -T -t hash -f $2 -h $3 $1.new"
 	$LOAD_CMD -T -t hash -f $2 -h $3 $1.new
df68a2c2
 	
c327195e
 # echo "$LOAD_CMD -r fileid -h $3 $1.new"
   	$LOAD_CMD -r fileid -h $3 $1.new
df68a2c2
 }
 
 
 #####
 # newappend process is:
 # 1. create a new temp DBENV in /tmp/sc-<processID>
 # 2. appends contents of newdata to /tmp/sc-<processID>/db
78045945
 # 3. move /tmp/sc-<processID>/db over to DB_PATH/db.new
df68a2c2
 # 4. delete temp DBENV dir /tmp/sc-<processID>
 #
e102ae72
 kamailio_newappend()  # parms: <db> <newdata> [DB_PATH]
df68a2c2
 {
 	if [ $# -lt 3  ]; then
e102ae72
 		echo  "kamailio_append parms: <db> <newdata> [DB_PATH]"
df68a2c2
 		exit 1
 	fi
 	
 	DB=$3/$1
 	DBNEW=$DB.new
 	if [ -f $DBNEW ] ; then
 		rm $DBNEW
 	fi
 	TMPENV=/tmp/sc-$$
e102ae72
 	kamailio_create $TMPENV
df68a2c2
 	cd $OLDPWD
c327195e
 	$LOAD_CMD -T -t hash -f $2 -h $TMPENV $1
df68a2c2
 	mv $TMPENV/$1 $DBNEW
 	rm -rf $TMPENV
 }
 
 
78045945
 # cat all rows to STDOUT
e102ae72
 kamailio_cat()  # pars: <database name> <DB_PATH>
df68a2c2
 {
 	if [ $# -ne 2 ] ; then
e102ae72
 		echo  "kamailio_cat params <db> [DB_PATH]"
df68a2c2
 		exit 1
 	fi
 	
c327195e
 	$DUMP_CMD -p -h $2 $1
df68a2c2
 }
 
e102ae72
 kamailio_drop()  # pars:  <DB_PATH>
df68a2c2
 {
 	if [ $# -ne 1 ] ; then
e102ae72
 		echo "kamailio_drop function takes one param"
df68a2c2
 		exit 1
 	fi
 	
 	if [ ! -d $1 ] ; then
 		echo "Directory does not exist:  $1"
 	fi
 	
 	minfo "Dropping Berkeley DB database at: $1 ..."
 	
 	# core
 	if [ -f $1/version ] ; then
 		for TABLE in $STANDARD_TABLES; do
 		    mdbg "Dropping core table: $TABLE"
 		    rm -f $1/$TABLE
 		done
 	fi
 	
 	# presence
 	if [ -f $1/presentity ] ; then
 		for TABLE in $PRESENCE_TABLES; do
 		    mdbg "Dropping presence table: $TABLE"
 		    rm -f $1/$TABLE
 		done
 	fi
 	
 	# extra tables
 	if [ -f $1/cpl ] ; then
 		for TABLE in $EXTRA_TABLES; do
 		    mdbg "Dropping extra table: $TABLE"
 		    rm -f $1/$TABLE
 		done
 	fi
bf54395d
 
 	# delete db files and directory
 	rm -rf $1/__db.001
 	rm -rf $1/__db.002
 	rm -rf $1/__db.003
 	rm -rf $1/__db.004
 	rmdir $1
df68a2c2
 }
 
 
e102ae72
 kamailio_create() # pars: <DB_PATH>
df68a2c2
 {
 	if [ $# -ne 1 ] ; then
e102ae72
 		echo "kamailio_create param [DB_PATH]"
df68a2c2
 		exit 1
 	fi
 	
78045945
 	DB_PATH=$1
 	if [ ! -d $1 ] ; then
 		minfo "creating Berkeley DB database at: [$1]"
 		mkdir -p $DB_PATH
 	fi
df68a2c2
 	
 	for TABLE in $STANDARD_TABLES; do
78045945
 	    mdbg "Creating standard table: $TABLE"
c327195e
 	    $LOAD_CMD -T -t hash -f $DB_SCHEMA/$TABLE -h $1 $TABLE
df68a2c2
 	    if [ $? -ne 0 ] ; then
78045945
 		merr "Creating standard tables failed!"
df68a2c2
 		exit 1
 	    fi
 	done
bf54395d
 
 	get_answer $INSTALL_PRESENCE_TABLES "Install presence related tables? (y/n): "
 	if [ "$ANSWER" = "y" ]; then
 		presence_create $1
 	fi
 
 	get_answer $INSTALL_EXTRA_TABLES "Install tables for $EXTRA_MODULES? (y/n): "
 	if [ "$ANSWER" = "y" ]; then
 		extra_create $1
 	fi
 
e102ae72
 } # kamailio_create
df68a2c2
 
 
78045945
 presence_create() # pars: <DB_PATH>
df68a2c2
 {
 	if [ $# -ne 1 ] ; then
78045945
 		merr "presence_create param [DB_PATH]"
df68a2c2
 		exit 1
 	fi
 	
78045945
 	DB_PATH=$1
 	if [ ! -d $1 ] ; then
 		# Assert: the directory should already exist
 		merr "BerkeleyDB directory does not exist at: [$1]"
 		exit 1
 	fi
 
 	if [ ! -f $1/version ] ; then
 		# Assert: directory should already contain table 'version'
 		merr "BerkeleyDB directory does not have VERSION table at: [$1]"
 		exit 1
 	fi
df68a2c2
 	
 	for TABLE in $PRESENCE_TABLES; do
 	    mdbg "Creating presence table: $TABLE"
c327195e
 	    $LOAD_CMD -T -t hash -f $DB_SCHEMA/$TABLE -h $1 $TABLE
df68a2c2
 	    if [ $? -ne 0 ] ; then
 		merr "Creating presence tables failed!"
 		exit 1
 	    fi
 	done
 	
 }  # end presence_create
 
 
78045945
 extra_create() # pars: <DB_PATH>
df68a2c2
 {
 
 	if [ $# -ne 1 ] ; then
78045945
 		merr "extra_create function takes one param (DB_PATH)"
df68a2c2
 		exit 1
 	fi
 	
78045945
 	DB_PATH=$1
 	if [ ! -d $1 ] ; then
 		# Assert: the directory should already exist
 		merr "BerkeleyDB directory does not exist at: [$1]"
 		exit 1
 	fi
 
 	if [ ! -f $1/version ] ; then
 		# Assert: directory should already contain table 'version'
 		merr "BerkeleyDB directory does not have VERSION table at: [$1]"
 		exit 1
 	fi
df68a2c2
 	
 	for TABLE in $EXTRA_TABLES; do
 	    mdbg "Creating extra table: $TABLE"
c327195e
 	    $LOAD_CMD -T -t hash -f $DB_SCHEMA/$TABLE -h $1 $TABLE
df68a2c2
 	    if [ $? -ne 0 ] ; then
 		merr "Creating extra tables failed!"
 		exit 1
 	    fi
 	done
 	
 }  # end extra_create