/* 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.
-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().
-C (boolean) suppresses the automatic attempt to open an existing
checkout under the current directory. Implied by -R.
*/
assert Fossil.Db
assert 'function' === typename Fossil.Db.open
assert Fossil.Db.Stmt
/**
createContext() extends the Context constructor
to support more options. obj may be a falsy value
or an Object with any of these properties:
repoDb: path to repository DB. Default is ARGV.flags.R.
traceSql: if true, enable SQL tracing on the context.
checkout: a path to look for a checkout in. Not used if repoDb
is set. Default is getenv('PWD') unless ARGV.flags.C is truthy,
in which case no checkout is opened by default.
*/
Fossil.createContext = function(obj){
if(!obj){
const rdb = ARGV.flags.R
obj = object{
repoDb: rdb,
traceSql: !!ARGV.flags.S,
checkout: rdb ? undefined
: (ARGV.flags.C ? 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]
}
else 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]
}