             opts.cb?(err, result)
         return
 
+    _ensure_database_exists: (cb) =>
+        dbg = @_dbg("_ensure_database_exists")
+        dbg("ensure database '#{@_database}' exists")
+        misc_node.execute_code
+            command : 'psql'
+            args    : ['--host', @_host, '--port', @_port,
+                       '--list', '--tuples-only']
+            cb      : (err, output) =>
+                if err
+                    cb(err)
+                    return
+                databases = (x.split('|')[0].trim() for x in output.stdout.split('\n') when x)
+                if @_database in databases
+                    dbg("database '#{@_database}' already exists")
+                    cb()
+                    return
+                dbg("creating database '#{@_database}'")
+                misc_node.execute_code
+                    command : 'createdb'
+                    args    : ['--host', @_host, '--port', @_port, @_database]
+                    cb      : cb
+
     _ensure_trigger_exists: (table, columns, cb) =>
         dbg = @_dbg("_ensure_trigger_exists(#{table})")
         dbg("columns=#{misc.to_json(columns)}")



exports.pg = (opts) ->
    new PostgreSQL(opts)

class PostgreSQL
    constructor: (opts) ->
        opts = defaults opts,
            host     : 'localhost'
            database : 'smc'
            debug    : true
            cb       : undefined
        @_debug    = opts.debug
        @_host     = opts.host
        @_database = opts.database
        @_connect(opts.cb)

    _connect: (cb) =>
        dbg = @_dbg("connect"); dbg()
        pg.connect "postgres://#{@_host}/#{@_database}", (err, client) =>
            if err
                dbg("Failed to connect to database -- #{err}")
                cb?(err)
            else
                dbg("connected!")
                @_client = client
                @_client.on('notification', @_notification)
                cb?()

    _dbg: (f) =>
        if @_debug


    # Ensure that the actual schema in the database matches the one defined in SCHEMA
    update_schema: (opts) =>
        opts = defaults opts,
            cb : undefined
         dbg = @_dbg("update_schema"); dbg()
         async.series([
            (cb) =>
                cb()
         ], (err) =>
            opts.cb?(err)
         )

    delete_entire_database: (opts) =>
        throw Error("NotImplementedError")

    concurrent: () =>
        throw Error("NotImplementedError")
