Very cool! I was going to implement a keyed file system according to the idea present in my April 1 message. Sounds like you are 80% there. I'll leave it up to you (since you are so close), or pick it up when you need a break. Let me know if I can help. Thanks!!
Blake On Sat, Apr 19, 2014 at 4:05 PM, David B. Lamkins <dlamk...@gmail.com>wrote: > Here's a really simple component-file implementation I cobbled together > last night and this morning. This has been tested only lightly; I > wouldn't advise pushing this code into production. ;) > > The implementation consists of nine functions and one variable. > > Call cf∆init to load the apl-sqlite library from the location specified > by cf∆∆libpath. You can skip this step if you've already fixed the > library to SQL. > > Component files are opened and closed using cf∆tie and cf∆untie, > respectively. cf∆tie returns a tie number that's used as a handle by all > subsequent calls. > > Append a component to the file using cf∆append, which returns the > component number. > > Inquire the largest component number using cf∆max_cn. Note that this is > not necessarily the number of components. > > An existing component can be replaced using cf∆replace. The left > argument is a list of the tie number and the component number. > > An existing component can be dropped using cf∆drop. > > A component's presence may be inquired using cf∆exists. This is handy if > you need to preflight an operation that assumes an existing component. > (I intentionally didn't include this in operations that assume presence > of a component. If you need the check, do it yourself; if you know that > the check is unnecessary, don't bother.) > > An existing component is read using cf∆read. > > I'm currently using 2⎕tf and ⍎ to encode and decode stored component > data. SQLite seems to accept Unicode data just fine. > > There are presently no facilities to support concurrency or sharing. > Error checking is almost entirely nonexistent. > > You'll probably need to adjust cf∆∆libpath for your installation. > > > cf∆∆libpath←'apl-sqlite/lib_sqlite.so' > > ∇z←tn cf∆append data > ⍝ Add a new component and return its component number. > 'insert into component ( data ) values ( ? )' SQL[4,tn] ⊂5↓2⎕tf 'data' > z←cf∆max tn > ∇ > > ∇tn cf∆drop cn > ⍝ Drop an existing component. > 'delete from component where oid = ?' SQL[4,tn] cn > ∇ > > ∇z←tn cf∆exists cn > ⍝ Inquire whether a component exists. > z←↑,'select 1 from component where oid = ?' SQL[3,tn] cn > ∇ > > ∇cf∆init > ⍝ Ensure that the apl-sqlite library is loaded. > →(0≠⎕nc 'SQL')/0 > cf∆∆libpath ⎕fx 'SQL' > ∇ > > ∇z←cf∆max_cn tn > ⍝ Return the component file's largest component number. > z←'select max(oid) from component' SQL[4,tn] ⍬ > ∇ > > ∇z←tn cf∆read cn > ⍝ Read an existing component. > z←⍎,⊃'select data from component where oid = ?' SQL[3,tn] cn > ∇ > > ∇where cf∆replace data;tn;cn > ⍝ Replace an existing component. > tn←1↑where > cn←1↓where > 'replace into component ( oid, data ) values ( ?, ? )' SQL[4,tn] (cn) > (5↓2⎕tf 'data') > ∇ > > ∇z←cf∆tie path > ⍝ Get a reference to a named component file. Create the file if needed. > z←'sqlite' SQL[1] path > 'create table if not exists component ( data text )' SQL[4,z] ⍬ > ∇ > > ∇cf∆untie tn > ⍝ Close the referenced component file. > SQL[2] tn > ∇ > > > >