signature DBMS = sig
val validDbname : string -> bool
+ val validEncoding : string option -> bool
type handler = {getpass : (unit -> Client.passwd_result) option,
adduser : {user : string, passwd : string option} -> string option,
passwd : {user : string, passwd : string} -> string option,
- createdb : {user : string, dbname : string} -> string option,
+ createdb : {user : string, dbname : string, encoding : string option} -> string option,
dropdb : {user : string, dbname : string} -> string option,
grant : {user : string, dbname : string} -> string option}
open DataStructures
val validDbname = CharVector.all (fn ch => Char.isAlphaNum ch orelse ch = #"_")
+fun validEncoding encoding =
+ case encoding of
+ NONE => true
+ | SOME e => size e > 0 andalso size e < 20 andalso CharVector.all Char.isAlphaNum e
type handler = {getpass : (unit -> Client.passwd_result) option,
adduser : {user : string, passwd : string option} -> string option,
passwd : {user : string, passwd : string} -> string option,
- createdb : {user : string, dbname : string} -> string option,
+ createdb : {user : string, dbname : string, encoding : string option} -> string option,
dropdb : {user : string, dbname : string} -> string option,
grant : {user : string, dbname : string} -> string option}
end
| ["createdb", dbname] =>
if Dbms.validDbname dbname then
- Main.requestDbTable {dbtype = dbtype, dbname = dbname}
+ Main.requestDbTable {dbtype = dbtype, dbname = dbname, encoding = NONE}
else
print ("Invalid database name " ^ dbname ^ ".\n")
+ | ["createdb", dbname, encoding] =>
+ if not (Dbms.validDbname dbname) then
+ print ("Invalid database name " ^ dbname ^ ".\n")
+ else if not (Dbms.validEncoding (SOME encoding)) then
+ print ("Invalid encoding name " ^ encoding ^ ".\n")
+ else
+ Main.requestDbTable {dbtype = dbtype, dbname = dbname, encoding = SOME encoding}
| ["dropdb", dbname] =>
if Dbms.validDbname dbname then
Main.requestDbDrop {dbtype = dbtype, dbname = dbname}
val requestDbUser : {dbtype : string, passwd : string option} -> unit
val requestDbPasswd : {dbtype : string, passwd : string} -> unit
- val requestDbTable : {dbtype : string, dbname : string} -> unit
+ val requestDbTable : {dbtype : string, dbname : string, encoding : string option} -> unit
val requestDbDrop : {dbtype : string, dbname : string} -> unit
val requestDbGrant : {dbtype : string, dbname : string} -> unit
SOME ("Error adding user: " ^ msg)))
(fn () => ())
- | MsgCreateDb {dbtype, dbname} =>
+ | MsgCreateDb {dbtype, dbname, encoding} =>
doIt (fn () =>
if Dbms.validDbname dbname then
case Dbms.lookup dbtype of
NONE => ("Database creation request with unknown datatype type " ^ dbtype,
SOME ("Unknown database type " ^ dbtype))
| SOME handler =>
- case #createdb handler {user = user, dbname = dbname} of
- NONE => ("Created database " ^ user ^ "_" ^ dbname ^ ".",
- NONE)
- | SOME msg => ("Error creating database " ^ user ^ "_" ^ dbname ^ ": " ^ msg,
- SOME ("Error creating database: " ^ msg))
+ if not (Dbms.validEncoding encoding) then
+ ("Invalid encoding " ^ valOf encoding ^ " requested for database creation.",
+ SOME "Invalid encoding")
+ else
+ case #createdb handler {user = user, dbname = dbname, encoding = encoding} of
+ NONE => ("Created database " ^ user ^ "_" ^ dbname ^ ".",
+ NONE)
+ | SOME msg => ("Error creating database " ^ user ^ "_" ^ dbname ^ ": " ^ msg,
+ SOME ("Error creating database: " ^ msg))
else
("Invalid database name " ^ user ^ "_" ^ dbname,
SOME ("Invalid database name " ^ dbname)))
| MsgCreateDbUser {dbtype, passwd} => (OpenSSL.writeInt (bio, 16);
OpenSSL.writeString (bio, dbtype);
sendOption OpenSSL.writeString (bio, passwd))
- | MsgCreateDb {dbtype, dbname} => (OpenSSL.writeInt (bio, 17);
- OpenSSL.writeString (bio, dbtype);
- OpenSSL.writeString (bio, dbname))
+ | MsgCreateDb {dbtype, dbname, encoding} => (OpenSSL.writeInt (bio, 17);
+ OpenSSL.writeString (bio, dbtype);
+ OpenSSL.writeString (bio, dbname);
+ sendOption OpenSSL.writeString (bio, encoding))
| MsgNewMailbox {domain, user, passwd, mailbox} =>
(OpenSSL.writeInt (bio, 18);
OpenSSL.writeString (bio, domain);
(SOME dbtype, SOME passwd) =>
SOME (MsgCreateDbUser {dbtype = dbtype, passwd = passwd})
| _ => NONE)
- | 17 => (case (OpenSSL.readString bio, OpenSSL.readString bio) of
- (SOME dbtype, SOME dbname) =>
- SOME (MsgCreateDb {dbtype = dbtype, dbname = dbname})
+ | 17 => (case (OpenSSL.readString bio, OpenSSL.readString bio, recvOption OpenSSL.readString bio) of
+ (SOME dbtype, SOME dbname, SOME encoding) =>
+ SOME (MsgCreateDb {dbtype = dbtype, dbname = dbname, encoding = encoding})
| _ => NONE)
| 18 => (case (OpenSSL.readString bio, OpenSSL.readString bio,
OpenSSL.readString bio, OpenSSL.readString bio) of
* that user and no one else has rights. *)
| MsgCreateDbUser of {dbtype : string, passwd : string option}
(* Request creation of a user for the named DBMS type *)
- | MsgCreateDb of {dbtype : string, dbname : string}
+ | MsgCreateDb of {dbtype : string, dbname : string, encoding : string option}
(* Request creation of a DBMS database *)
| MsgDropDb of {dbtype : string, dbname : string}
(* Request dropping of a DBMS database *)
createdb)
USERNAME=$2
DBNAME_BASE=$3
+ ENCODING=$4
DBNAME="${USERNAME}_${DBNAME_BASE}"
- sudo -u postgres createdb -O $USERNAME -D user_$USERNAME $DBNAME
+ if [ -n $ENCODING ]; then
+ ENCODING="-E $ENCODING"
+ fi
+
+ sudo -u postgres createdb -O $USERNAME -D user_$USERNAME $ENCODING $DBNAME
;;
dropdb)
else
SOME "Password contains characters besides letters, digits, and !.-_"
-fun createdb {user, dbname} =
- Option.map (fn s => "Error executing CREATE DATABASE script:\n" ^ s)
- (Slave.shellOutput [Config.MySQL.createdb, user, " ", dbname])
+fun createdb {user, dbname, encoding} =
+ case encoding of
+ SOME _ => SOME "MySQL doesn't support specifying encodings"
+ | NONE =>
+ Option.map (fn s => "Error executing CREATE DATABASE script:\n" ^ s)
+ (Slave.shellOutput [Config.MySQL.createdb, user, " ", dbname])
fun dropdb {user, dbname} =
Option.map (fn s => "Error executing DROP DATABASE script:\n" ^ s)
fun passwd _ = SOME "We don't use PostgreSQL passwords."
-fun createdb {user, dbname} =
+fun createdb {user, dbname, encoding} =
Option.map (fn s => "Error executing CREATE DATABASE script:\n" ^ s)
- (Slave.shellOutput [Config.Postgres.createdb, user, " ", dbname])
+ (Slave.shellOutput [Config.Postgres.createdb,
+ " ", user, " ", dbname,
+ case encoding of NONE => "" | SOME e => " " ^ e])
fun dropdb {user, dbname} =
Option.map (fn s => "Error executing DROP DATABASE script:\n" ^ s)