1 USING: accessors assocs bson.constants combinators.short-circuit
2 constructors continuations fry kernel mirrors mongodb.tuple.collection
3 mongodb.tuple.state namespaces sequences words bson.writer combinators
4 hashtables linked-assocs ;
6 IN: mongodb.tuple.persistent
10 GENERIC: tuple>assoc ( tuple -- assoc )
12 GENERIC: tuple>selector ( tuple -- selector )
18 : mdbinfo>tuple-class ( tuple-info -- class )
19 [ first ] keep second lookup ; inline
21 : tuple-instance ( tuple-info -- instance )
22 mdbinfo>tuple-class new ; inline
24 : prepare-assoc>tuple ( assoc -- tuple keylist mirror assoc )
25 [ tuple-info tuple-instance dup
26 <mirror> [ keys ] keep ] keep swap ; inline
28 : make-tuple ( assoc -- tuple )
30 '[ dup _ at assoc>tuple swap _ set-at ] each
31 [ mark-persistent ] keep ; inline recursive
33 : at+ ( value key assoc -- value )
35 [ at nip ] [ [ dup ] 2dip set-at ] if ; inline
37 : data-tuple? ( tuple -- ? )
39 [ assoc? not ] [ drop f ] if ; inline
41 : add-storable ( assoc ns -- )
42 [ H{ } clone ] dip object-map get at+
43 [ dup [ MDB_OID_FIELD ] dip at ] dip set-at ; inline
45 : write-field? ( tuple key value -- ? )
46 pick mdb-persistent? [
47 { [ [ 2drop ] dip not ]
48 [ drop transient-slot? ] } 3|| not ] [ 3drop t ] if ; inline
50 TUPLE: cond-value value quot ;
52 CONSTRUCTOR: cond-value ( value quot -- cond-value ) ;
54 : write-mdb-persistent ( value quot: ( tuple -- assoc ) -- value' )
55 over [ (( tuple -- assoc )) call-effect ] dip
56 [ tuple-collection name>> ] keep
58 [ tuple-collection name>> ] [ _id>> ] bi <objref> ; inline
60 : write-field ( value quot: ( tuple -- assoc ) -- value' )
62 { [ dup value>> mdb-special-value? ] [ value>> ] }
63 { [ dup value>> mdb-persistent? ]
64 [ [ value>> ] [ quot>> ] bi write-mdb-persistent ] }
65 { [ dup value>> data-tuple? ]
66 [ [ value>> ] [ quot>> ] bi (( tuple -- assoc )) call-effect ] }
67 { [ dup value>> [ hashtable? ] [ linked-assoc? ] bi or ]
68 [ [ value>> ] [ quot>> ] bi '[ _ write-field ] assoc-map ] }
70 } cond ; inline recursive
72 : write-tuple-fields ( mirror tuple assoc quot: ( tuple -- assoc ) -- )
74 '[ _ 2over write-field?
75 [ _ write-field swap _ set-at ]
79 : prepare-assoc ( tuple -- assoc mirror tuple assoc )
80 H{ } clone swap [ <mirror> ] keep pick ; inline
82 : ensure-mdb-info ( tuple -- tuple )
83 dup _id>> [ <objid> >>_id ] unless
84 [ mark-persistent ] keep ; inline
86 : with-object-map ( quot: ( -- ) -- store-assoc )
87 [ H{ } clone dup object-map ] dip with-variable ; inline
89 : (tuple>assoc) ( tuple -- assoc )
90 [ prepare-assoc [ tuple>assoc ] write-tuple-fields ] keep
91 over set-tuple-info ; inline
95 GENERIC: tuple>storable ( tuple -- storable )
97 M: mdb-persistent tuple>storable ( mdb-persistent -- object-map )
98 '[ _ [ tuple>assoc ] write-mdb-persistent drop ] with-object-map ; inline
100 M: mdb-persistent tuple>assoc ( tuple -- assoc )
101 ensure-mdb-info (tuple>assoc) ;
103 M: tuple tuple>assoc ( tuple -- assoc )
106 M: tuple tuple>selector ( tuple -- assoc )
107 prepare-assoc [ tuple>selector ] write-tuple-fields ;
109 : assoc>tuple ( assoc -- tuple )
113 [ ] if ] [ drop ] recover
114 ] [ ] if ; inline recursive