Anyway, to draw a line under this non-discussion with myself, as you may have gathered, I have been spending the last few days putting together a picoLisp admin website and Over-The-Air-Update (OTAU) facility for my employer, who has a large archive of their APK builds for many flavors and devices going back over 20 years - not many will request the Android API 1 APK for arm16 these days I hope, but they could - so I have been using and learning picoLisp's Database and piLog database query facilities for the first time in-depth.
picoLisp does a great job in a few lines of code at parsing the output of 'aapk' and 'apkanalyzer' into a LARGE database: $ ls -ltr db/APK/ total 174844 -rw-r--r--. 1 jvd devel 64 May 7 23:22 AC -rw-r--r--. 1 jvd devel 64 May 7 23:22 AB -rw-r--r--. 1 jvd devel 64 May 7 23:22 AA -rw-r--r--. 1 jvd devel 64 May 7 23:22 A@ -rw-r--r--. 1 jvd devel 1039104 May 9 02:51 A -rw-r--r--. 1 jvd devel 384 May 9 02:51 @ -rw-r--r--. 1 jvd devel 7409792 May 9 02:51 C -rw-r--r--. 1 jvd devel 1470720 May 9 02:51 G -rw-r--r--. 1 jvd devel 1867904 May 9 02:51 F -rw-r--r--. 1 jvd devel 4962432 May 9 02:51 E -rw-r--r--. 1 jvd devel 7409792 May 9 02:51 D -rw-r--r--. 1 jvd devel 2321728 May 9 02:51 J -rw-r--r--. 1 jvd devel 201344 May 9 02:51 I -rw-r--r--. 1 jvd devel 7807552 May 9 02:51 H -rw-r--r--. 1 jvd devel 5638912 May 9 02:51 O -rw-r--r--. 1 jvd devel 5638912 May 9 02:51 N -rw-r--r--. 1 jvd devel 4587968 May 9 02:51 M -rw-r--r--. 1 jvd devel 2362432 May 9 02:51 L -rw-r--r--. 1 jvd devel 6214016 May 9 02:51 K -rw-r--r--. 1 jvd devel 119984384 May 9 02:51 B $ ls -ltr db/APK/ total 174844 -rw-r--r--. 1 jvd devel 64 May 7 23:22 AC -rw-r--r--. 1 jvd devel 64 May 7 23:22 AB -rw-r--r--. 1 jvd devel 64 May 7 23:22 AA -rw-r--r--. 1 jvd devel 64 May 7 23:22 A@ -rw-r--r--. 1 jvd devel 1039104 May 9 02:51 A -rw-r--r--. 1 jvd devel 384 May 9 02:51 @ -rw-r--r--. 1 jvd devel 7409792 May 9 02:51 C -rw-r--r--. 1 jvd devel 1470720 May 9 02:51 G -rw-r--r--. 1 jvd devel 1867904 May 9 02:51 F -rw-r--r--. 1 jvd devel 4962432 May 9 02:51 E -rw-r--r--. 1 jvd devel 7409792 May 9 02:51 D -rw-r--r--. 1 jvd devel 2321728 May 9 02:51 J -rw-r--r--. 1 jvd devel 201344 May 9 02:51 I -rw-r--r--. 1 jvd devel 7807552 May 9 02:51 H -rw-r--r--. 1 jvd devel 5638912 May 9 02:51 O -rw-r--r--. 1 jvd devel 5638912 May 9 02:51 N -rw-r--r--. 1 jvd devel 4587968 May 9 02:51 M -rw-r--r--. 1 jvd devel 2362432 May 9 02:51 L -rw-r--r--. 1 jvd devel 6214016 May 9 02:51 K -rw-r--r--. 1 jvd devel 119984384 May 9 02:51 B So these are keyed on Inode#, Path, and I can traverse the whole database in < 100msec with: (collect 'ino '+APK 1 (- (>> -64 1) 1)) Great! So my (APK~apks ( Flv Vrn Blt Mtm Abi . Fun ) ...) function simply traverses the whole database each time for APKs that match, and calls Fun with them : (when (and (= Flv (apk_attr apk "flv")) (>= (apk_attr apk "vrn") Vrn) (>= (apk_attr apk "blt") Blt) (>= (apk_attr apk "mtm") Mtm) (abi_within (apk_attr apk "AB>") Abi (apk_attr apk "AB>") ) ) (pass (car Fun) apk) ) But, in trying to investigate use of piLog's '(solve ...) and '(select/3 ...) and (range/3 ...) , I am at a loss as to how to get them to behave reliably. It seems, if somthing fails within a piLog '(solve ...) query, then the database becomes unusable , then '(db ..) and '(collect ...) statements that succeeded before start failing, and I have to exit the process and re-initialize. I was just wondering how to achieve something like the above with a piLog query that does NOT have to traverse the entire database each time, and does NOT run the risk of making the database inaccessable on some kind of internal failure as seems to be happening whenever I try to use '(solve ...) . Some clarification from the expert on this would be MUCH APPRECIATED! Thank you, despite some niggles picoLisp is my favorite scripting language these days. All the best, Jason On 10/05/2022, Jason Vas Dias <jason.vas.d...@gmail.com> wrote: > I guess for a short term fix, I will have to write a function > that calls '(collect 'tree +APK ...) without use of piLog's '(solve ...), > then do a manual join + filter on the results of each list, > because use of piLog's '(solve ...)' is unreliable ? > > There is no mention in the '(solve ...) documentation or in select.html > that the database trees need re-initializing (end the process and restart + > re-initialize (reload of the .l file that calls '(class ...) '(rel ..) ... > and > '(pool ...) on load ) in order for it to work again - there should be ! > > Is '(solve ...) likely to be re-usable (or its result usable in same > process by '(for x (res)(...)) soon ? > > Else I guess the best long-term fix IS to use SQLite3 / SolidDB / DB2 > instead. > > On 10/05/2022, Jason Vas Dias <jason.vas.d...@gmail.com> wrote: >> Actually, it appears to be after the first time I call '(for x >> (qry)(...)) >> where 'qry is a function that calls '(solve ...), then the solve function >> stops working: >> >> >> APK: (de G4S_APKS () (solve >> (quote >> @FLV "G4S_PRF" >> @VER (cons 302010010) >> (select (@APK) >> ( (flv +APK @FLV) (vrn +APK @VER) >> ) (same @FLV @APK flv) (range @VER @APK vrn) >> ) >> ) @APK >> )) >> -> G4S_APKS >> APK: >> APK: (G4S_APKS) >> -> ({A13000} {A34401} {A33002} {A32405} {A13006} {A34410} {A7416} >> {A34420} {A11423} {A7424} {A36024} {A26025} {A34430} {A11431} {A31432} >> {A26033} {A10034} {A34034} {A31441} {A30442} {A10043} {A22443} >> {A33045} {A30451} {A22452} {A35144} {A6055} {A17061} {A6063} {A10464} >> {A17070} {A21471} {A5073} {A10473} {A4076} {A12477} {A21500} {A5101} >> {A34103} {A4104} {A12505} {A14523} {A30124} {A25125} {A15126} {A33126} >> {A15531} {A14532} {A30132} {A25134} {A15135} {A15540} {A7145} {A34152} >> {A7153} {A13553} {A13561} {A14163} {A26163} {A11165} {A24565} {A26171} >> {A14172} {A11173} {A24574} {A10176} {A6577} {A32200} {A17601} {A5605} >> {A6605} {A10205} {A32206} {A33207} {A17610} {A7611}) >> APK: (symbols '(pico)) >> >> >> (de apk_str (a) >> (mapcar >> '((c) >> (pack (cdr c) " : " (car c)) >> ) >> (getl a) >> ) >> ) >> : (APK~G4S_APKS) >> -> ({A13000} {A34401} {A33002} {A32405} {A13006} {A34410} {A7416} >> {A34420} {A11423} {A7424} {A36024} {A26025} {A34430} {A11431} {A31432} >> {A26033} {A10034} {A34034} {A31441} {A30442} {A10043} {A22443} >> {A33045} {A30451} {A22452} {A35144} {A6055} {A17061} {A6063} {A10464} >> {A17070} {A21471} {A5073} {A10473} {A4076} {A12477} {A21500} {A5101} >> {A34103} {A4104} {A12505} {A14523} {A30124} {A25125} {A15126} {A33126} >> {A15531} {A14532} {A30132} {A25134} {A15135} {A15540} {A7145} {A34152} >> {A7153} {A13553} {A13561} {A14163} {A26163} {A11165} {A24565} {A26171} >> {A14172} {A11173} {A24574} {A10176} {A6577} {A32200} {A17601} {A5605} >> {A6605} {A10205} {A32206} {A33207} {A17610} {A7611}) >> : (de show_apks (apks) >> (prog >> (let >> (s "") >> (prog >> (for a apks >> (setq s >> (join "^I" (apk_str a)) >> ) >> ) >> ) >> ) >> s >> ) >> ) >> # show_apks redefined >> -> show_apks >> >> : (show_apks (APK~G4S_APKS)) >> -> NIL >> : >> : (for a (APK~G4S_APKS) (prinl (join "^I" (apk_str a)))) >> -> NIL >> : >> : (for a (APK~G4S_APKS) (prinl (sym a))) >> -> NIL >> : (APK~G4S_APKS) >> -> NIL >> : >> >> Now, any function that calls '(solve ...) stops working - why ? >> >> I guess picoLisp's DB is kind of a work-in-progress / unfinished idea ? >> >> >> >> >> >> >> >> >> >> >> On 10/05/2022, Jason Vas Dias <jason.vas.d...@gmail.com> wrote: >>> I am also finding that when I run a function that calls '(solve ...) , >>> it works the first few times, but after a few calls, it stops returning >>> any ext symbols. Why ? >>> >>> I have read all documentation I can find on pil Database & piLog >>> (best is doc/select.html), but I cannot find any answers. >>> >>> If I haven't solved this today, I'll have to start using an SQLite3 >>> wrapper library tomorrow , which would be a shame, since >>> pico does seem to be doing a great job at parsing our collection >>> of about 40,000 APKs into its built-in BTREE database format OK, >>> then the first few invocations of '(solve ..) work OK, and then >>> they start returning NIL - why ? >>> >>> Any help would be much appreciated. >>> >>> >>> On 10/05/2022, Jason Vas Dias <jason.vas.d...@gmail.com> wrote: >>>> Good day - >>>> >>>> I'd still love to hear some explanation about how >>>> the global '(pico~args)' symbol gets blown out >>>> by a function parameter named 'args', not within >>>> that function, but within a function it calls. >>>> >>>> Also, how does one define new piLog Predicates ? >>>> >>>> I'm trying to create a Database of APKs : >>>> >>>> (class +APK +Entity) >>>> # APK POC Package Database Class >>>> (rel apk (+Need +Idx +String)) # APK Path >>>> (rel app (+Need +Idx +String)) # APK Package >>>> (rel aid (+Need +Idx +String)) # APK Application ID >>>> (rel ino (+Need +Idx +Number)) # FS Inode of APK on SharePoint >>>> filesystem (UUID) >>>> (rel flv (+Need +Idx +String)) # APK Build Flavor >>>> (rel bty (+Need +Idx +String)) # APK Build Type >>>> (rel vrn (+Need +Idx +Number)) # APK VersionCode >>>> (rel vrs (+Need +Idx +String)) # APK VersionName >>>> (rel gin (+Idx +String)) # APK GIT Info String >>>> (rel dbg (+Idx +Bool)) # APK has Debug Logging enabled >>>> (rel blt (+Need +Idx +Number)) # APK BuildTime >>>> (rel bls (+Need +Idx +String)) # APK BuildTimeString >>>> (rel ctm (+Need +Idx +Number)) # APK Creation Time >>>> (rel mtm (+Need +Idx +String)) # APK Modification Time >>>> (rel AB> (*Idx +Number)) # APK MinSdkVersion (Android ABI #) >>>> (rel AB< (*Idx +Number)) # APK MaxSdkVersion (Android ABI #) >>>> (rel AB@ (*Idx +Number)) # APK TargetSdkVersion (Android ABI #) >>>> (rel AB$ (*Idx +Number)) # APK CompileSdkVersion (Android ABI #) >>>> >>>> >>>> and define a query : >>>> >>>> >>>> (de apks ( Flv Ver Blt Abi Mtm ) >>>> (if (or (not (bool Flv)) (not (str? Flv)) >>>> (not (bool Ver)) (not (num? Ver)) >>>> (not (bool Blt)) (not (num? Blt)) >>>> (not (bool Abi)) (not (num? Abi)) >>>> ) >>>> (throw (pack "apks: Invalid Parameters: flv:" (sym Flv) " vrn:" (sym >>>> Ver) " Mtm:" (sym Mtm) " Abi:" (sym Abi))) >>>> (if (not (bool Mtm)) >>>> (symbols '(APK pico) >>>> (solve >>>> (quote >>>> @FLV Flv >>>> @VER (cons Ver) >>>> @BLT (cons Blt) >>>> @AB> (cons NIL Abi) >>>> @AB< (cons Abi) >>>> (select (@APK) >>>> ((flv +APK @FLV) >>>> (vrn +APK @VER) >>>> (blt +APK @BLT) >>>> (AB> +APK @AB>) >>>> (AB< +APK @AB<) >>>> ) >>>> (same @FLV @APK flv) >>>> (range @VER @APK vrn) >>>> (range @BLT @APK blt) >>>> (range @AB> @APK AB>) >>>> (range @AB< @APK AB<) >>>> ) >>>> ) @APK >>>> )) >>>> (symbols '(APK pico) >>>> (solve >>>> (quote >>>> @FLV Flv >>>> @VER (cons Ver) >>>> @BLT (cons Blt) >>>> @AB> (cons NIL Abi) >>>> @AB< (cons Abi) >>>> @MTM (cons Mtm) >>>> (select (@APK) >>>> ( (flv +APK @FLV) >>>> (vrn +APK @VER) >>>> (blt +APK @BLT) >>>> (mtm +APK @MTM) >>>> (AB> +APK @AB>) >>>> (AB< +APK @AB<) >>>> ) >>>> (same @FLV @APK flv) >>>> (range @VER @APK vrn) >>>> (range @BLT @APK blt) >>>> (range @MTM @APK mtm) >>>> (range @AB> @APK AB>) >>>> (range @AB< @APK AB<) >>>> ) >>>> ) @APK >>>> )) >>>> ) >>>> ) >>>> ) >>>> >>>> >>>> to select APKs which : >>>> o have a given 'flv' (flavor) attribute == Flv >>>> o have a version >= Ver >>>> o have a min api # <= Abi >>>> o have a max api # >= Abi >>>> o have a build time >= Blt >>>> o have a modification time >= Mtm >>>> >>>> but the above query always returns NIL , I think because >>>> many APKs do not specify any 'maxSdkVersion', so get >>>> 'AB<' set to 0 : >>>> I want to define a piLog Predicate that says: >>>> (or ( (=0 @APK AB<) (range @AB< @APK AB<)) >>>> how would I do this? >>>> >>>> Thanks, Best Regards, >>>> Jason >>>> >>>> >>>> >>>> >>>> On 07/05/2022, Jason Vas Dias <jason.vas.d...@gmail.com> wrote: >>>>> Good day Alex, picoLisp list - >>>>> >>>>> Why does declaring a parameter named 'args', in a function that does >>>>> NOT use the '(args)' call, break things severely ? >>>>> >>>>> I had a function that does NOT use the built-in 'args, but which >>>>> declared a parameter named 'args : >>>>> >>>>> (de a ( fun data args ) >>>>> (let >>>>> ( (flg list x) args ) # destructuring bind >>>>> (prog ... >>>>> # eventually, fun gets called with unpacked args: >>>>> (fun data flg list x) >>>>> ) >>>>> ) >>>>> ) >>>>> >>>>> Then eventually 'fun calls a function that calls '(args) : >>>>> '(request! >>>>> '(+myDbCls) ... >>>>> ) >>>>> which DOES use args, at which point I got an error: >>>>> >>>>> !? ((0 NIL 16661165511231956559 (15935676839705835219 >>>>> (12638994734423517827 ... >>>>> 0 -- Variable expected >>>>> >>>>> Renaming the parameter 'ars (or 'as :-) ) fixed the problem. >>>>> >>>>> Why ? >>>>> >>>>> I thought parameters and '(let ..) variables are in their own >>>>> dynamic lexical scope, so that even if the 'args call is hidden >>>>> in the 'a function, if 'a calls another function 'fun, and that >>>>> calls a function which calls 'request!, the binding of 'args >>>>> in request cannot possibly be affected by the binding of 'args >>>>> in 'a. This turns out to be incorrect ! Where am I going wrong ? >>>>> >>>>> This took me a LONG time to find. My only clue was that 'list does >>>>> look like : >>>>> ((0 NIL 16661165511231956559 (15935676839705835219 >>>>> (12638994734423517827 >>>>> ... >>>>> >>>>> Any suggestions as to exactly how the binding of 'args in 'a gets >>>>> called by 'request! would be much appreciated. >>>>> >>>>> Thank You & Best Regards, >>>>> Jason >>>>> >>>> >>> >> > -- UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe