/* 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]
}