common_check_connect(){

	log_tc "successful connect"
	mockup -i ${test_dbtype}
	_dbc_${test_dbtype}_check_connect </dev/null
	assertTrue "${test_dbtype}_check_connect failed" $?
	subst_tmpfile dbconfig-common_my.cnf.XXXXXX "$mockup_cmdline"
	assertFilesEqual ./data/${test_dbtype}_check_connect.txt "$mockup_cmdline"
	assertFileEmpty "unexpected input to ${test_dbtype}_check_connect" "$mockup_inputfile"

	log_tc "fail to connect with error code"
	mockup -r 1 -i ${test_dbtype}
	_dbc_${test_dbtype}_check_connect </dev/null 2>/dev/null
	assertFalse "${test_dbtype}_check_connect should have failed" $?

}

dbc_common_exec_file(){
	local _dbc_nodb sql

	sql=`mktemp -t`

	mockup -i ${test_dbtype}

	log_tc "expected behaviour for existing file"
	dbc_${test_dbtype}_exec_file "$sql" >/dev/null
	assertTrue "dbc_${test_dbtype}_exec_file (withdb) failed" $?
	subst_tmpfile dbconfig-common_my.cnf.XXXXXX "$mockup_cmdline"
	assertFilesEqual ./data/dbc_${test_dbtype}_exec_file.withdb.txt "$mockup_cmdline"

	log_tc "expected behaviour for missing file"
	dbc_${test_dbtype}_exec_file "does not exist.sql" >/dev/null
	assertFalse "dbc_${test_dbtype}_exec_file (withdb) should have failed" $?
	subst_tmpfile dbconfig-common_my.cnf.XXXXXX "$mockup_cmdline"
	assertFilesEqual ./data/dbc_${test_dbtype}_exec_file.withdb.txt "$mockup_cmdline"

	mockup -i ${test_dbtype}

	# same as before, but with _dbc_nodb set
	_dbc_nodb=yes
	log_tc "expected behaviour for existing file, no database"
	dbc_${test_dbtype}_exec_file "$sql"
	assertTrue "dbc_${test_dbtype}_exec_file (nodb) failed" $?
	subst_tmpfile dbconfig-common_my.cnf.XXXXXX "$mockup_cmdline"
	assertFilesEqual ./data/dbc_${test_dbtype}_exec_file.nodb.txt "$mockup_cmdline"

	log_tc "expected behaviour for missing file, no database"
	dbc_${test_dbtype}_exec_file "does not exist.sql" >/dev/null
	assertFalse "dbc_${test_dbtype}_exec_file (nodb) should have failed" $?
	subst_tmpfile dbconfig-common_my.cnf.XXXXXX "$mockup_cmdline"
	assertFilesEqual ./data/dbc_${test_dbtype}_exec_file.nodb.txt "$mockup_cmdline"

	rm -f "$sql"
}

common_exec_command(){
	mockup -i ${test_dbtype}
	dbc_${test_dbtype}_exec_command "select * from foo where bar = 1"
	assertTrue "dbc_${test_dbtype}_exec_command failed" $?
	assertFilesEqual ./data/${test_dbtype}_exec_command.sql.txt "$mockup_inputfile"
}

dbc_common_check_database(){
	mockup -i -o ./data/dbc_${test_dbtype}_check_database.exists.stdout.txt ${test_dbtype}
	log_tc "database exists"
	_dbc_${test_dbtype}_check_database "$dbc_dbname"
	assertTrue "_dbc_${test_dbtype}_check_database failed to find db" $?

	log_tc "database does not exist"
	mockup -i -o ./data/dbc_${test_dbtype}_check_database.missing.stdout.txt ${test_dbtype}
	_dbc_${test_dbtype}_check_database "$dbc_dbname"
	assertFalse "_dbc_${test_dbtype}_check_database shouldn't have found db" $?
}

dbc_common_check_user(){
	local dbc_dballow

	log_tc "existing user, with grant, localhost"
	mockup -i -o ./data/dbc_${test_dbtype}_check_user.localhost.exists.stdout.txt ${test_dbtype}
	dbc_${test_dbtype}_check_user
	assertTrue "dbc_${test_dbtype}_check_user failed to find user" $?

	log_tc "user does not exist at all"
	mockup -i ${test_dbtype}
	dbc_${test_dbtype}_check_user
	assertFalse "dbc_${test_dbtype}_check_user shouldn't have found user" $?

	log_tc "user exists, does not have grant"
	mockup -i -o ./data/dbc_${test_dbtype}_check_user.localhost.nogrant.stdout.txt ${test_dbtype}
	dbc_${test_dbtype}_check_user
	assertFalse "dbc_${test_dbtype}_check_user shouldn't have found grant" $?

	log_tc "user exists on remote host"
	dbc_dballow="host2"
	mockup -i -o ./data/dbc_${test_dbtype}_check_user.remote.exists.stdout.txt ${test_dbtype}
	dbc_${test_dbtype}_check_user
	assertTrue "dbc_${test_dbtype}_check_user failed to find user on remote" $?
}

dbc_common_createdb(){
	local output

	log_tc "checkconnect fails"
	mockup _dbc_sanity_check
	mockup -r 1 _dbc_${test_dbtype}_check_connect
	dbc_${test_dbtype}_createdb >/dev/null 
	assertFalse "dbc_${test_dbtype}_createdb (checkconnect) should have failed" $?

	log_tc "database already exists"
	mockup _dbc_sanity_check
	mockup _dbc_${test_dbtype}_check_connect
	mockup _dbc_${test_dbtype}_check_database
	output=`dbc_${test_dbtype}_createdb 2>&1`
	assertTrue "dbc_${test_dbtype}_createdb (exists) failed" $?
	assertEquals "creating database testdbname: already exists." "$output"

	log_tc "database does not exist, creation successful"
	cat </dev/null > "$_dbc_logfile"
	mockup _dbc_sanity_check
	mockup _dbc_${test_dbtype}_check_connect
	mockup -r 1 _dbc_${test_dbtype}_check_database
	mockup dbc_${test_dbtype}_exec_command
	mockup _dbc_${test_dbtype}_check_database
	dbc_${test_dbtype}_createdb >/dev/null 2>&1
	assertTrue "dbc_${test_dbtype}_createdb failed" $?
	assertFilesEqual "./data/dbc_${test_dbtype}_createdb.verifyok.txt" "$_dbc_logfile"

	log_tc "database does not exist, creation failed"
	cat </dev/null > "$_dbc_logfile"
	mockup _dbc_sanity_check
	mockup _dbc_${test_dbtype}_check_connect
	mockup -r 1 _dbc_${test_dbtype}_check_database
	mockup -r 1 dbc_${test_dbtype}_exec_command
	output=`dbc_${test_dbtype}_createdb 2>&1`
	assertFalse "dbc_${test_dbtype}_createdb should have failed" $?
	assertEquals "creating database testdbname: failed." "$output"

	log_tc "database does not exist, creation ok, verify failed"
	mockup _dbc_sanity_check
	mockup _dbc_${test_dbtype}_check_connect
	mockup -r 1 _dbc_${test_dbtype}_check_database
	mockup dbc_${test_dbtype}_exec_command
	mockup -r 1 _dbc_${test_dbtype}_check_database
	cat </dev/null > "$_dbc_logfile"
	dbc_${test_dbtype}_createdb >/dev/null 2>&1
	assertFalse "dbc_${test_dbtype}_createdb should have failed" $?
	assertFilesEqual "./data/dbc_${test_dbtype}_createdb.verifyfail.txt" "$_dbc_logfile"
}

dbc_common_dropdb(){
	local output

	log_tc "unable to connect"
	mockup _dbc_sanity_check
	mockup -r 1 _dbc_${test_dbtype}_check_connect
	dbc_${test_dbtype}_dropdb
	assertFalse "dbc_${test_dbtype}_dropdb should have failed to connect" $?

	log_tc "database does not exist"
	mockup _dbc_sanity_check
	mockup _dbc_${test_dbtype}_check_connect
	mockup -r 1 _dbc_${test_dbtype}_check_database
	output=`dbc_${test_dbtype}_dropdb 2>&1`
	assertTrue "dbc_${test_dbtype}_dropdb failed" $?
	assertEquals "dropping database testdbname: database does not exist." "$output"

	log_tc "database exists, drop successful"
	cat </dev/null > "$_dbc_logfile"
	mockup _dbc_sanity_check
	mockup _dbc_${test_dbtype}_check_connect
	mockup _dbc_${test_dbtype}_check_database
	mockup dbc_${test_dbtype}_exec_command
	mockup -r 1 _dbc_${test_dbtype}_check_database

	output=`dbc_${test_dbtype}_dropdb 2>&1`
	assertTrue "dbc_${test_dbtype}_dropdb failed" $?
	assertFilesEqual "./data/dbc_${test_dbtype}_dropdb.verifyok.txt" "$_dbc_logfile"

	log_tc "database exists, drop failed"
	cat </dev/null > "$_dbc_logfile"
	mockup _dbc_sanity_check
	mockup _dbc_${test_dbtype}_check_connect
	mockup _dbc_${test_dbtype}_check_database
	mockup -r 1 dbc_${test_dbtype}_exec_command

	output=`dbc_${test_dbtype}_dropdb 2>&1`
	assertFalse "dbc_${test_dbtype}_dropdb should have failed" $?
	assertEquals "dropping database testdbname: failed." "$output"

	log_tc "database exists, drop ok, verify failed"
	cat </dev/null > "$_dbc_logfile"
	mockup _dbc_sanity_check
	mockup _dbc_${test_dbtype}_check_connect
	mockup _dbc_${test_dbtype}_check_database
	mockup dbc_${test_dbtype}_exec_command
	mockup _dbc_${test_dbtype}_check_database
	output=`dbc_${test_dbtype}_dropdb 2>&1`
	assertFalse "dbc_${test_dbtype}_dropdb should have failed" $?
	assertFilesEqual "./data/dbc_${test_dbtype}_dropdb.verifyfailed.txt" "$_dbc_logfile"

}

dbc_common_createuser(){
	local output sqllog
	local dbc_dballow dbc_dbserver
	dbc_dballow=localhost

	# what's being checked, roughly:
	# connecting with no hostname
	#    grant input
	# connecting with hostname
	#    grant input
	# connecting with no hostname
	#   user exists
	#   user does not exist
	#    grant input
	#     creation succeeds
	#       verify succeeds
	#         log message
	#       verify fails
	#         log message
	#     creation fails
	#       log message
	# connecting with hostname
	#   user exists
	#   user does not exist
	#    grant input
	#     creation succeeds
	#       verify succeeds
	#         log message
	#       verify fails
	#         log message
	#     creation fails
	#       log message

	log_tc "connect fails"
	mockup _dbc_sanity_check
	mockup -r 1 _dbc_${test_dbtype}_check_connect
	output=`dbc_${test_dbtype}_createuser 2>&1`
	assertFalse "dbc_${test_dbtype}_createuser should have failed to connect" $?

	log_tc "local host, user does not exist, creation success, verify ok"
	cat </dev/null > "$_dbc_logfile"
	mockup _dbc_sanity_check
	mockup _dbc_${test_dbtype}_check_connect
	mockup -r 1 dbc_${test_dbtype}_check_user
	mockup -i ${test_dbtype}
	sqllog="${mockup_inputfile}"
	mockup dbc_${test_dbtype}_check_user
	output=`dbc_${test_dbtype}_createuser 2>&1`
	assertTrue "dbc_${test_dbtype}_createuser failed" $?
	assertFilesEqual "./data/dbc_${test_dbtype}_createuser.nohost.sql.txt" "${sqllog}"
	assertFilesEqual "data/dbc_${test_dbtype}_createuser.nohost.log.verifyok.txt" "$_dbc_logfile"

	log_tc "remote host, user does not exist, creation success, verify ok"
	cat </dev/null > "$_dbc_logfile"
	dbc_dballow="host2"
	mockup _dbc_sanity_check
	mockup _dbc_${test_dbtype}_check_connect
	mockup -r 1 dbc_${test_dbtype}_check_user
	mockup -i ${test_dbtype}
	sqllog="${mockup_inputfile}"
	mockup dbc_${test_dbtype}_check_user
	output=`dbc_${test_dbtype}_createuser 2>&1`
	assertTrue "dbc_${test_dbtype}_createuser failed" $?
	assertFilesEqual "./data/dbc_${test_dbtype}_createuser.remote.sql.txt" "${sqllog}"
	assertFilesEqual "data/dbc_${test_dbtype}_createuser.remote.log.verifyok.txt" "$_dbc_logfile"

	log_tc "local host, user exists"
	dbc_dballow="localhost"
	mockup _dbc_sanity_check
	mockup _dbc_${test_dbtype}_check_connect
	mockup dbc_${test_dbtype}_check_user
	output=`dbc_${test_dbtype}_createuser 2>&1`
	assertTrue "dbc_${test_dbtype}_createuser failed" $?
	assertEquals "granting access to database testdbname for testdbuser@localhost: already exists." "$output"

	log_tc "local host, user does not exist, creation success, verify fails"
	cat </dev/null > "$_dbc_logfile"
	mockup _dbc_sanity_check
	mockup _dbc_${test_dbtype}_check_connect
	mockup -r 1 dbc_${test_dbtype}_check_user
	mockup -i -o ./data/dbc_${test_dbtype}_check_user.localhost.exists.stdout.txt ${test_dbtype}
	mockup -r 1 dbc_${test_dbtype}_check_user
	output=`dbc_${test_dbtype}_createuser 2>&1`
	assertFalse "dbc_${test_dbtype}_createuser should have failed" $?
	assertFilesEqual "data/dbc_${test_dbtype}_createuser.nohost.log.verifyfail.txt" "$_dbc_logfile"

	log_tc "local host, user does not exist, creation fails"
	cat </dev/null > "$_dbc_logfile"
	mockup _dbc_sanity_check
	mockup _dbc_${test_dbtype}_check_connect
	mockup -r 1 dbc_${test_dbtype}_check_user
	mockup -r 1 dbc_${test_dbtype}_exec_file
	output=`dbc_${test_dbtype}_createuser 2>&1`
	assertFalse "dbc_${test_dbtype}_createuser should have failed" $?
	assertEquals "granting access to database testdbname for testdbuser@localhost: failed." "$output"

	log_tc "remote host, user exists"
	export dbc_dballow="host2"
	mockup _dbc_sanity_check
	mockup _dbc_${test_dbtype}_check_connect
	mockup dbc_${test_dbtype}_check_user
	output=`dbc_${test_dbtype}_createuser 2>&1`
	assertTrue "dbc_${test_dbtype}_createuser failed" $?
	assertEquals "granting access to database testdbname for testdbuser@host2: already exists." "$output"

	log_tc "remote host, user does not exist, creation success, verify fails"
	cat </dev/null > "$_dbc_logfile"
	mockup _dbc_sanity_check
	mockup _dbc_${test_dbtype}_check_connect
	mockup -r 1 dbc_${test_dbtype}_check_user
	mockup dbc_${test_dbtype}_exec_file
	mockup -r 1 dbc_${test_dbtype}_check_user
	output=`dbc_${test_dbtype}_createuser 2>&1`
	assertFalse "dbc_${test_dbtype}_createuser should have failed" $?
	assertFilesEqual "data/dbc_${test_dbtype}_createuser.remote.log.verifyfail.txt" "$_dbc_logfile"

	log_tc "remote host, user does not exist, creation fails"
	cat </dev/null > "$_dbc_logfile"
	mockup _dbc_sanity_check
	mockup _dbc_${test_dbtype}_check_connect
	mockup -r 1 dbc_${test_dbtype}_check_user
	mockup -r 1 dbc_${test_dbtype}_exec_file
	output=`dbc_${test_dbtype}_createuser 2>&1`
	assertFalse "dbc_${test_dbtype}_createuser should have failed" $?
	assertEquals "granting access to database testdbname for testdbuser@host2: failed." "$output"
}

dbc_common_dropuser(){
	local output dbc_dballow dbc_dbserver
	dbc_dballow=localhost

	# to check:
	# connect failure
	# connecting with no hostname
	#   user doesn't exist
	#   user exists
	#     revoke input
	#     revoke fails
	#         log msg
	#     revoke succeeds
	#       verifying revoke succeeds
	#         log msg
	#       verifying revoke fails
	#         log msg
	# connecting with hostname
	#   user doesn't exist
	#   user exists
	#     revoke input
	#     revoke fails
	#       log msg
	#     revoke succeeds
	#       verifying revoke succeeds
	#         log msg
	#       verifying revoke fails
	#         log msg

	log_tc "connect fails"
	mockup _dbc_sanity_check
	mockup -r 1 _dbc_${test_dbtype}_check_connect
	dbc_${test_dbtype}_dropuser 2>/dev/null
	assertFalse "dbc_${test_dbtype}_dropuser should have failed to connect" $?

	. ${_dbc_root}/internal/${test_dbtype}
	log_tc "localhost, user exists, revoke fails"
	mockup _dbc_sanity_check
	mockup _dbc_${test_dbtype}_check_connect
	mockup dbc_${test_dbtype}_check_user
	mockup -i -r 1 ${test_dbtype}
	dbc_${test_dbtype}_dropuser >/dev/null 2>&1
	assertFalse "dbc_${test_dbtype}_dropuser should have failed" $?
	assertFilesEqual ./data/dbc_${test_dbtype}_dropuser.nohost.sql.txt ${mockup_inputfile}
	assertFilesEqual ./data/dbc_${test_dbtype}_dropuser.nohost.log.fail.txt $_dbc_logfile

	log_tc "localhost, user exists, revoke succeeds, (TODO verify ok)"
	cat </dev/null > "$_dbc_logfile"
	mockup _dbc_sanity_check
	mockup _dbc_${test_dbtype}_check_connect
	mockup dbc_${test_dbtype}_check_user
	mockup dbc_${test_dbtype}_exec_file
	dbc_${test_dbtype}_dropuser >/dev/null 2>&1
	assertTrue "dbc_${test_dbtype}_dropuser should not have failed" $?
	assertFilesEqual ./data/dbc_${test_dbtype}_dropuser.nohost.log.verifyok.txt $_dbc_logfile

	log_tc "TODO localhost, user exists, revoke fails"

	. ${_dbc_root}/internal/${test_dbtype}
	rm -f ./tmp/mockup/mockup.control
	export dbc_dballow="host2"
	cat </dev/null > "$_dbc_logfile"
	log_tc "remote, user exists, revoke fails"
	mockup _dbc_sanity_check
	mockup _dbc_${test_dbtype}_check_connect
	mockup dbc_${test_dbtype}_check_user
	mockup -i -r 1 ${test_dbtype}
	dbc_${test_dbtype}_dropuser >/dev/null 2>&1
	assertFalse "dbc_${test_dbtype}_dropuser should have failed" $?
	assertFilesEqual ./data/dbc_${test_dbtype}_dropuser.remote.sql.txt ${mockup_inputfile}
	assertFilesEqual ./data/dbc_${test_dbtype}_dropuser.remote.log.fail.txt $_dbc_logfile

	log_tc "remote, user exists, revoke succeeds, (TODO verify ok)"
	cat </dev/null > "$_dbc_logfile"
	mockup _dbc_sanity_check
	mockup _dbc_${test_dbtype}_check_connect
	mockup dbc_${test_dbtype}_check_user
	mockup dbc_${test_dbtype}_exec_file
	dbc_${test_dbtype}_dropuser >/dev/null 2>&1
	assertTrue "dbc_${test_dbtype}_dropuser should not have failed" $?
	assertFilesEqual ./data/dbc_${test_dbtype}_dropuser.remote.log.verifyok.txt $_dbc_logfile

	log_tc "TODO remote, user exists, revoke fails"
}

dbc_common_dump(){
	# to check:
	# ${test_dbtype}dump cmdline
	# ${test_dbtype}dump succeeds
	#   log msg
	# ${test_dbtype}dump fails
	#   log msg
	. ${_dbc_root}/internal/${test_dbtype}
	rm -f ./tmp/mockup/mockup.control

	log_tc "${test_dbtype}dump succeeds"
	mockup _dbc_sanity_check
	mockup _dbc_${test_dbtype}_check_connect
	mockup _dbc_${test_dbtype}_check_database
	mockup -o ./data/dbc_logline.simple.txt ${test_dbtype}dump 
	dbc_${test_dbtype}_dump good
	assertTrue "${test_dbtype} dump should have succeeded" $?
	assertTrue "${test_dbtype} dump should have created a dumpfile" "[ -s good ]"

	log_tc "${test_dbtype}dump fails"
	mockup _dbc_sanity_check
	mockup _dbc_${test_dbtype}_check_connect
	mockup _dbc_${test_dbtype}_check_database
	mockup -r 1 -o ./data/dbc_logline.simple.txt ${test_dbtype}dump 
	dbc_${test_dbtype}_dump bad
	assertFalse "${test_dbtype} dump should have failed" $?
	assertTrue "${test_dbtype} dump should have created a dumpfile" "[ -s bad ]"

	rm -f good bad
}

dbc_common_db_installed(){

	log_tc "${test_dbtype}d in path"
	touch ./tmp/${test_dbtype}d
	chmod +x ./tmp/${test_dbtype}d
	( PATH="/bin:./tmp"; dbc_${test_dbtype}_db_installed )
	assertTrue "${test_dbtype}d should have been found" $?
	rm -f ./tmp/${test_dbtype}d

	log_tc "${test_dbtype}d not in path"
	( PATH="/bin"; dbc_${test_dbtype}_db_installed )
	assertFalse "${test_dbtype}d should not have been found" $?
}

dbc_common_escape_str(){
	local str t

	t=`mktemp`
	# normal string
	log_tc "escaping normal string"
	str=`dbc_${test_dbtype}_escape_str "this is a normal string"`
	assertTrue "error escaping string" "[ '$str' = 'this is a normal string' ]"
	# string with \
	log_tc "escaping string w/backslash"
	dbc_${test_dbtype}_escape_str 'should have 1 backslash (\) but escape to 2' > "$t"
	assertFilesEqual ./data/${test_dbtype}_escape_str.backslash.txt "$t"
	# string with '
	log_tc "escaping string w/single quote"
	dbc_${test_dbtype}_escape_str "it isn't unusual to find quotes" > "$t"
	assertFilesEqual ./data/${test_dbtype}_escape_str.quote.txt "$t"

	rm -f "$t"
}
