116 lines
3.4 KiB
Factor
116 lines
3.4 KiB
Factor
USING: accessors assocs bson.constants combinators.short-circuit
|
|
constructors continuations fry kernel mirrors mongodb.tuple.collection
|
|
mongodb.tuple.state namespaces sequences words bson.writer combinators
|
|
hashtables linked-assocs ;
|
|
|
|
IN: mongodb.tuple.persistent
|
|
|
|
SYMBOLS: object-map ;
|
|
|
|
GENERIC: tuple>assoc ( tuple -- assoc )
|
|
|
|
GENERIC: tuple>selector ( tuple -- selector )
|
|
|
|
DEFER: assoc>tuple
|
|
|
|
<PRIVATE
|
|
|
|
: mdbinfo>tuple-class ( tuple-info -- class )
|
|
[ first ] keep second lookup ; inline
|
|
|
|
: tuple-instance ( tuple-info -- instance )
|
|
mdbinfo>tuple-class new ; inline
|
|
|
|
: prepare-assoc>tuple ( assoc -- tuple keylist mirror assoc )
|
|
[ tuple-info tuple-instance dup
|
|
<mirror> [ keys ] keep ] keep swap ; inline
|
|
|
|
: make-tuple ( assoc -- tuple )
|
|
prepare-assoc>tuple
|
|
'[ dup _ at assoc>tuple swap _ set-at ] each
|
|
[ mark-persistent ] keep ; inline recursive
|
|
|
|
: at+ ( value key assoc -- value )
|
|
2dup key?
|
|
[ at nip ] [ [ dup ] 2dip set-at ] if ; inline
|
|
|
|
: data-tuple? ( tuple -- ? )
|
|
dup tuple?
|
|
[ assoc? not ] [ drop f ] if ; inline
|
|
|
|
: add-storable ( assoc ns -- )
|
|
[ H{ } clone ] dip object-map get at+
|
|
[ dup [ MDB_OID_FIELD ] dip at ] dip set-at ; inline
|
|
|
|
: write-field? ( tuple key value -- ? )
|
|
pick mdb-persistent? [
|
|
{ [ [ 2drop ] dip not ]
|
|
[ drop transient-slot? ] } 3|| not ] [ 3drop t ] if ; inline
|
|
|
|
TUPLE: cond-value value quot ;
|
|
|
|
CONSTRUCTOR: cond-value ( value quot -- cond-value ) ;
|
|
|
|
: write-mdb-persistent ( value quot: ( tuple -- assoc ) -- value' )
|
|
over [ (( tuple -- assoc )) call-effect ] dip
|
|
[ tuple-collection name>> ] keep
|
|
[ add-storable ] dip
|
|
[ tuple-collection name>> ] [ _id>> ] bi <objref> ; inline
|
|
|
|
: write-field ( value quot: ( tuple -- assoc ) -- value' )
|
|
<cond-value> {
|
|
{ [ dup value>> mdb-special-value? ] [ value>> ] }
|
|
{ [ dup value>> mdb-persistent? ]
|
|
[ [ value>> ] [ quot>> ] bi write-mdb-persistent ] }
|
|
{ [ dup value>> data-tuple? ]
|
|
[ [ value>> ] [ quot>> ] bi (( tuple -- assoc )) call-effect ] }
|
|
{ [ dup value>> [ hashtable? ] [ linked-assoc? ] bi or ]
|
|
[ [ value>> ] [ quot>> ] bi '[ _ write-field ] assoc-map ] }
|
|
[ value>> ]
|
|
} cond ; inline recursive
|
|
|
|
: write-tuple-fields ( mirror tuple assoc quot: ( tuple -- assoc ) -- )
|
|
swap ! m t q q a
|
|
'[ _ 2over write-field?
|
|
[ _ write-field swap _ set-at ]
|
|
[ 2drop ] if
|
|
] assoc-each ;
|
|
|
|
: prepare-assoc ( tuple -- assoc mirror tuple assoc )
|
|
H{ } clone swap [ <mirror> ] keep pick ; inline
|
|
|
|
: ensure-mdb-info ( tuple -- tuple )
|
|
dup _id>> [ <objid> >>_id ] unless
|
|
[ mark-persistent ] keep ; inline
|
|
|
|
: with-object-map ( quot: ( -- ) -- store-assoc )
|
|
[ H{ } clone dup object-map ] dip with-variable ; inline
|
|
|
|
: (tuple>assoc) ( tuple -- assoc )
|
|
[ prepare-assoc [ tuple>assoc ] write-tuple-fields ] keep
|
|
over set-tuple-info ; inline
|
|
|
|
PRIVATE>
|
|
|
|
GENERIC: tuple>storable ( tuple -- storable )
|
|
|
|
M: mdb-persistent tuple>storable ( mdb-persistent -- object-map )
|
|
'[ _ [ tuple>assoc ] write-mdb-persistent drop ] with-object-map ; inline
|
|
|
|
M: mdb-persistent tuple>assoc ( tuple -- assoc )
|
|
ensure-mdb-info (tuple>assoc) ;
|
|
|
|
M: tuple tuple>assoc ( tuple -- assoc )
|
|
(tuple>assoc) ;
|
|
|
|
M: tuple tuple>selector ( tuple -- assoc )
|
|
prepare-assoc [ tuple>selector ] write-tuple-fields ;
|
|
|
|
: assoc>tuple ( assoc -- tuple )
|
|
dup assoc?
|
|
[ [ dup tuple-info?
|
|
[ make-tuple ]
|
|
[ ] if ] [ drop ] recover
|
|
] [ ] if ; inline recursive
|
|
|