nsmcp::AccessRecordStoreSQLite method prepare (public)

 <instance of nsmcp::AccessRecordStoreSQLite[i]> prepare file

Defined in /usr/local/ns/tcl/nsmcp/log-traffic-record-store.tcl

Parameters:
file (required)

Testcases:
No testcase defined.
Source code:
file stat [dict get $file path] actual
set identity [dict get $file identity]
set policy [expr {[dict exists ${:settings} policy] ? [dict get ${:settings} policy] : {}}]
set key [ns_crypto::md string -digest sha256 -- [list schema1 $identity $policy]]
set fid {}
set old [${:db} execute {SELECT * FROM nsmcp_records.files WHERE k=$key}]
set f [open [dict get $file path] rb]
try {
    set reset false
    if {$old ne {}} {
        set old [lindex $old 0]; set fid [dict get $old fid]
        set prefix [ns_crypto::md string -digest sha256 -binary -- [read $f [dict get $old plen]]]
        if {[dict get $old high]>$actual(size) || $prefix ne [dict get $old prefix]
            || ([dict get $old high]==$actual(size) && [dict get $old stamp]!=$actual(mtime))} {set reset true}
        if {!$reset} {
            # A small boundary anchor per contiguous imported range
            # detects rewrites near committed cursors before reuse.
            foreach span [${:db} execute {SELECT hi,anchor FROM nsmcp_records.ranges WHERE fid=$fid LIMIT 4097}] {
                set hi [dict get $span hi]; seek $f [expr {max(0,$hi-64)}]
                if {[ns_crypto::md string -digest sha256 -binary -- [read $f [expr {min(64,$hi)}]]] ne [dict get $span anchor]} {set reset true; break}
            }
        }
    }
    if {${:mode} eq "reader"} {return [expr {$old eq {} || $reset || ![dict get $old active] ? -1 : $fid}]}
    if {$old eq {} || $reset} {
        set plen [expr {min(64,[dict get $file size])}]; seek $f 0
        set prefix [ns_crypto::md string -digest sha256 -binary -- [read $f $plen]]
        set high 0; set stamp [dict get $file mtime]; set now [clock seconds]
        ${:db} transaction {
            if {[dict exists ${:settings} unified] && [dict get ${:settings} unified] && $fid ne {}} {
                set retired "${key}:retired:$fid"; set oldIdentity "${identity}:retired:$fid"
                ${:db} execute {UPDATE nsmcp_records.files SET k=$retired,identity=$oldIdentity WHERE fid=$fid}
            } else {
                ${:db} execute {DELETE FROM nsmcp_records.rows WHERE fid=$fid; DELETE FROM nsmcp_records.ranges WHERE fid=$fid; DELETE FROM nsmcp_records.files WHERE k=$key}
            }
            ${:db} execute {
                INSERT INTO nsmcp_records.files(k,identity,prefix,plen,high,stamp,touched) VALUES($key,$identity,$prefix,$plen,$high,$stamp,$now)}
        }
    }
} finally {close $f}
set fid [${:db} scalar {SELECT fid FROM nsmcp_records.files WHERE k=$key}]
set now [clock seconds]
set touchBefore [expr {$now-max(1,min(3600,int([dict get ${:settings} retention]/4)))}]
${:db} execute {UPDATE nsmcp_records.files SET touched=$now WHERE fid=$fid AND touched<$touchBefore}
${:db} execute {UPDATE nsmcp_records.files SET active=0 WHERE identity=$identity AND fid<>$fid AND active=1;
    UPDATE nsmcp_records.files SET active=1 WHERE fid=$fid}
return $fid
XQL Not present:
Generic, PostgreSQL, Oracle
[ hide source ] | [ make this the default ]
Show another procedure: