/* Extend the Fossil bits a bit... */
/* Reminder: CLI args:

  The th1ish shell passed flags _after_ -- (two dashes)
  on to the script. It expects them to be in one of these
  forms:

  -f (boolean flag)
  -f=xxx (value - it tries to determine the type automatically)

  Any number of '-' may preceed a flag - they are all equivalent.

  Any such flags are stored as properties in ARGV.flags. Any
  arguments which do not start with a dash are presumed to be filenames
  or app commands and are added to ARGV.nonFlags.

  ARGV flags supported by this code:

  -R=/path/to/repo.fsl  tells it to open a repository db.

  -c (boolean) means to open the checkout and repo DBs associated
  with the current directory (just like the fossil binary does).

  -S (boolean) enables fossil-level SQL tracing. This applies to any
  DBs opened via a Fossil context (as opposed to directly opening them
  with Fossil.Db.open().

*/

assert Fossil.Db
assert 'function' === typename Fossil.Db.open
assert Fossil.Db.Stmt
Fossil.createContext = proc(obj){
    if(!obj){
        const rdb = ARGV.flags.R
        obj = object{
            repoDb: rdb,
            traceSql: ARGV.flags.S,
            checkout: rdb ? undefined : [getenv 'PWD']
        }
    }
    var f = [this.Context obj]
    obj || return f
    if('string'===typename obj.repoDb){
        [f.openRepo obj.repoDb]
        // run it again to test an exception:
        //[f.openRepo obj.repoDb]
    }
    if('string'===typename obj.checkout){
        [f.openCheckout obj.checkout]
        // run it again to test an exception:
        //[f.openCheckout obj.checkout]
    }
    return f
}

/**
  SELECT's the first column of the first row
  of the result set of the given SQL.
  If the bind argument is passed in then
  it is passed on to the Stmt.bind() method
  of the underlying statement. Use an array to
  bind multiple values.
*/
Fossil.Context.selectVal = proc(sql,bind){
    const st = [this.db.prepare sql]
    var rc
    const ex = catch {
        (1<[argv.length]) && [st.bind bind] // TODO: slice argv if 'bind' is not an array
        [st.step] && (rc = [st.get 0])
    }
    [st.finalize]
    ex && throw ex
    return rc;
}

Fossil.Context.dumpQuery = proc(sql,bind, separator='\t'){
    const params object{
        sql:sql,
        mode:1,
        bind:bind, // note that undefined value is treated as non-existent here
        callback:proc(){
            (1===rowNumber) && [print [columnNames.join separator]]
            [print [this.join separator]]
        }
    }
    [this.db.each params]
}
