:- lib(stoics_lib:en_list/2).
:- lib(stoics_lib:select_all/4).
:- lib(chess_db_exists/1).
chess_db_connect_defaults( Defs ) :-
Defs = [profile(true), create(false), position(true), db(_), handles(_)].
/** chess_db_connect( +DbS ).
chess_db_connect( +DbS, +Opts ).
Connect to a number of chess_dbs (DbS) and provide make their db handles available
to a number of predicates that access the information: eg chess_db_opening/3.
The library provides two conveniencies for locating chess dbs. First, via aliases:
chess_db (by default expands to pack(chess_db_data/dbs)). Second, via dir(Dir) option.
In this case Dbs are looked for relative to all Dir locations provided.
Note that commonly used database directories can be defined long term in
~/.pl/chess_db_connect.pl
(see options_append/4).
Opts
* create(Create=false)
if true create dir and/or db files if they do not exist
if =|true|= create ChessDb if doesn't exist (and use current if it does)
if =|false|= only proceed if ChessDb exists
if =|new|= only proceed if ChessDb does not exist (call creates it)
if =|fresh|= overwrites if a current exists
* db(Db)
returns the absolute locations of the dbs successfully connected (a list iff more than one)
* dir(Dir)
parent directory of chess database (mutliple are allowed)
* handles(Handles)
returns the handles term of connected databases (a list if multiple were established)
* profile(Prof=Prof)
whether to mix, true, or ignore, false, profile based dir options (see options_append/4)
if no dir(Dir) option is present in Opts, then Prof is ignored
==
% connect with alias
?- Db = chess_db('18.03-candidates'),
( chess_db_connect(Db, db(AbsDb) ) -> true
; chess_db( pgn('18.03-candidates'), Db, create(true) ),
chess_db_connect( Db, db(AbsDb) )
).
Db = chess_db('18.03-candidates'),
AbsDb = ['/usr/local/users/nicos/local/git/lib/swipl-7.7.18/pack/chess_db_data/dbs/18.03-candidates'].
?- chess_db_disconnect( Db ).
Db = '/usr/local/users/nicos/local/git/lib/swipl-7.7.18/pack/chess_db_data/dbs/18.03-candidates'.
% connect with dir option in profile options...
?- shell( 'cat ~/.pl/chess_db_connect.pl' ).
dir( '/usr/local/users/chess/chess_db' ).
dir( '/usr/local/users/nicos/local/git/lib/swipl/pack/chess_db_data/dbs' ).
true.
?- read_link( '/usr/local/users/nicos/local/git/lib/swipl', A, B ).
A = 'swipl-7.7.18/',
B = '/usr/local/users/nicos/local/git/lib/swipl-7.7.18/'.
?- chess_db_connect('18.03-candidates', db(Db) ).
Db = ['/usr/local/users/nicos/local/git/lib/swipl-7.7.18/pack/chess_db_data/dbs/18.03-candidates'].
==
@author nicos angelopoulos
@version 0.1 2018/3/15
@version 0.2 2018/8/17, added aliases, better locator (and order), fixes, docs/examples
@see chess_db_opening/3
*/
chess_db_connect( DbS ) :-
chess_db_connect( DbS, [] ).
chess_db_connect( DbS, ArgS ) :-
en_list( DbS, Dbs ),
en_list( ArgS, Args ),
select_all( Args, dir(_D), Sel, Rem ),
options_append( chess_db_connect, Rem, OptsPrv ),
options( profile(Prof), OptsPrv ),
chess_db_sel_connect_dirs( Sel, Prof, OptsPrv, Opts ),
findall( Dir, member(dir(Dir),Opts), Dirs ),
options( create(Create), Opts ),
options( position(Pos), Opts ),
chess_db_connect_dirs( Dbs, Dirs, Create, Pos, CdbHssPrv, AbssPrv ),
de_list( AbssPrv, Abss ),
de_list( CdbHssPrv, CdbHss ),
memberchk( db(Abss), Opts ),
memberchk( handles(CdbHss), Opts ).
de_list( List, Elem ) :- % move to pack(stoics_lib)
is_list( List ),
List = [Elem],
!.
de_list( Other, Other ).
chess_db_connect_dirs( [], _Dirs, _Create, _Pos, [], [] ).
chess_db_connect_dirs( [Db|Dbs], Dirs, Create, Pos, CdbHss, Abss ) :-
chess_db_connect_db( Create, Pos, Db, Dirs, CdbHs, Abs ),
( Abs == [] -> Abss = TAbss ; Abss = [Abs|TAbss] ),
( CdbHs == [] -> CdbHss = TCdbHss ; CdbHss = [CdbHs|TCdbHss] ),
chess_db_connect_dirs( Dbs, Dirs, Create, Pos, TCdbHss, TAbss ).
chess_db_connect_db( false, Pos, Db, Dirs, CdbHs, AbsConn ) :-
% append( Dirs, [''], Airs ),
member( Dir, [''|Dirs] ),
Apts = [relative_to(Dir),solutions(all),file_type(directory)], % fixme non dir dbs...
absolute_file_name( Db, Abs, Apts ),
chess_db_exists( Abs ),
chess_db_connect_abs_dir( Abs, false, Pos, CdbHs, AbsConn ),
!.
chess_db_connect_db( new, Pos, Db, Dirs, CdbHs, AbsConn ) :-
append( Dirs, [''], Airs ),
member( Dir, Airs ),
Apts = [relative_to(Dir),solutions(all)], % fixme non dir dbs...
absolute_file_name( Db, Abs, Apts ),
chess_db_connect_abs_dir( Abs, true, Pos, CdbHs, AbsConn ),
!.
chess_db_connect_db( true, Pos, Db, Dirs, CdbHs, AbsConn ) :-
( chess_db_connect_db( false, Pos, Db, Dirs, CdbHs, AbsConn ) ->
true
;
chess_db_connect_db( new, Pos, Db, Dirs, CdbHs, AbsConn )
).
chess_db_connect_db( fresh, Pos, Db, Dirs, CdbHs, AbsConn ) :-
member( Dir, [''|Dirs] ),
Apts = [relative_to(Dir),solutions(all),file_type(directory)], % fixme non dir dbs...
absolute_file_name( Db, Abs, Apts ),
chess_db_exists( Abs ),
!,
debug( chess_db(true), 'Deleting chess_db at: ~p', [Abs] ),
delete_directory_and_contents( Abs ),
chess_db_connect_abs_dir( Abs, true, Pos, CdbHs, AbsConn ).
chess_db_connect_db( _Create, _Pos, Dir, [], [] ) :-
debug( chess_db(true), 'Failed to connect to chess_db at dir: ~p', [Dir] ).
chess_db_connect_abs_dir( Abs, _Create, _Pos, CdbHs, [] ) :-
chess_db_handles( Abs, CdbHs ),
!,
debug( chess_db(info), 'Handles already exist, for chess_db directory: ~p', [Abs] ).
chess_db_connect_abs_dir( Abs, Create, Pos, CdbHs, Abs ) :-
chess_db_handles( Create, Pos, Abs, CdbHs, _AbsDir ),
!,
assertz( chess_db_handles(Abs,CdbHs) ).
chess_db_sel_connect_dirs( [], _Prof, OptsPrv, Opts ) :-
Opts = OptsPrv.
chess_db_sel_connect_dirs( [H|T], Prof, OptsPrv, Opts ) :-
( Prof == false ->
select_all( OptsPrv, dir(_D), _, OptsNonD ),
append( [H|T], OptsNonD, Opts )
;
append( [H|T], OptsPrv, Opts )
).