<s> import json <EOL> import copy <EOL> import random <EOL> from functools import reduce <EOL> import plyvel <EOL> from . _version import schema_version <EOL> class DB : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , database_path , ** kwargs ) : <EOL> self . db = plyvel . DB ( database_path , ** kwargs ) <EOL> self . collections_set = self . db . prefixed_db ( b'<STR_LIT>' ) <EOL> self . collection_items_set = self . db . prefixed_db ( b'<STR_LIT>' ) <EOL> self . collections_cache = { } <EOL> try : <EOL> self . schema_version = decode ( self . db . get ( b'<STR_LIT>' ) ) <EOL> except : <EOL> self . schema_version = schema_version <EOL> self . db . put ( b'<STR_LIT>' , encode ( schema_version ) ) <EOL> def collection ( self , collection_name , reset_collection = False , <EOL> create_if_missing = True , error_if_exists = False ) : <EOL> """<STR_LIT>""" <EOL> if collection_name not in self . collections_cache : <EOL> data = self . collections_set . get ( collection_name . encode ( ) ) <EOL> if data == None : <EOL> if create_if_missing == False : <EOL> raise ValueError ( "<STR_LIT>" . format ( collection_name ) ) <EOL> self . collections_set . put ( collection_name . encode ( ) , b'<STR_LIT:true>' ) <EOL> self . collections_cache [ collection_name ] = Collection ( self , self . collection_items_set , collection_name ) <EOL> elif error_if_exists : <EOL> raise ValueError ( "<STR_LIT>" . format ( collection_name ) ) <EOL> if reset_collection : <EOL> self . collections_cache [ collection_name ] . delete_all ( ) <EOL> return self . collections_cache [ collection_name ] <EOL> def collections ( self ) : <EOL> """<STR_LIT>""" <EOL> return [ name . decode ( ) for name in self . collections_set . iterator ( include_value = False ) ] <EOL> def copy_collection ( self , old_collection , new_collection , start = None , end = None , ** kwargs ) : <EOL> """<STR_LIT>""" <EOL> old = self . collection ( old_collection , create_if_missing = False ) <EOL> new = self . collection ( new_collection , reset_collection = True , ** kwargs ) <EOL> new . append_all ( old . iterator ( start , end ) ) <EOL> return new <EOL> def delete ( self , collection_name ) : <EOL> """<STR_LIT>""" <EOL> self . collection ( collection_name ) . delete_all ( ) <EOL> self . collections_set . delete ( collection_name . encode ( ) ) <EOL> del self . collections_cache [ collection_name ] <EOL> def close ( self ) : <EOL> """<STR_LIT>""" <EOL> self . db . close ( ) <EOL> def open ( self ) : <EOL> """<STR_LIT>""" <EOL> self . db . open ( ) <EOL> class Collection : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , database , items_set , name ) : <EOL> if '<STR_LIT>' in name : <EOL> raise ValueError ( "<STR_LIT>" ) <EOL> self . name = name <EOL> self . db = items_set . prefixed_db ( name . encode ( ) + b'<STR_LIT>' ) <EOL> self . parent_db = database <EOL> self . refresh ( ) <EOL> def append ( self , record ) : <EOL> """<STR_LIT>""" <EOL> self . last_index += <NUM_LIT:1> <EOL> key = str ( self . last_index ) . encode ( ) <EOL> self . db . put ( key , encode ( record ) ) <EOL> self . keys . append ( key ) <EOL> def refresh ( self ) : <EOL> """<STR_LIT>""" <EOL> self . keys = [ ] <EOL> for key in self . db . iterator ( include_value = False ) : <EOL> self . keys . append ( key ) <EOL> if len ( self . keys ) > <NUM_LIT:0> : <EOL> self . last_index = int ( self . keys [ - <NUM_LIT:1> ] ) <EOL> else : <EOL> self . last_index = <NUM_LIT:0> <EOL> def delete ( self , index ) : <EOL> """<STR_LIT>""" <EOL> self . db . delete ( self . keys [ index ] ) <EOL> self . keys . pop ( index ) <EOL> def delete_all ( self ) : <EOL> """<STR_LIT>""" <EOL> for key in self . keys : <EOL> self . db . delete ( key ) <EOL> self . keys = [ ] <EOL> self . last_index = <NUM_LIT:0> <EOL> def append_all ( self , iterable ) : <EOL> """<STR_LIT>""" <EOL> for instance in iterable : <EOL> self . append ( instance ) <EOL> def map ( self , function , new_collection , ** kwargs ) : <EOL> """<STR_LIT>""" <EOL> collection = None <EOL> if new_collection in [ None , self . name ] : <EOL> collection = self <EOL> for key in self . keys : <EOL> new_value = function ( decode ( self . db . get ( key ) ) ) <EOL> self . db . put ( key , encode ( new_value ) ) <EOL> else : <EOL> collection = self . parent_db . collection ( new_collection , reset_collection = True , ** kwargs ) <EOL> for instance in self : <EOL> collection . append ( function ( instance ) ) <EOL> return collection <EOL> def filter ( self , function , new_collection , ** kwargs ) : <EOL> """<STR_LIT>""" <EOL> collection = None <EOL> if new_collection in [ None , self . name ] : <EOL> collection = self <EOL> new_keys = [ ] <EOL> for key in self . keys : <EOL> if function ( decode ( self . db . get ( key ) ) ) : <EOL> new_keys . append ( key ) <EOL> else : <EOL> self . db . delete ( key ) <EOL> self . keys = new_keys <EOL> else : <EOL> collection = self . parent_db . collection ( new_collection , reset_collection = True , ** kwargs ) <EOL> for instance in self : <EOL> if function ( instance ) : <EOL> collection . append ( instance ) <EOL> return collection <EOL> def reduce ( self , function , new_collection , initializer = None , ** kwargs ) : <EOL> """<STR_LIT>""" <EOL> reduced = None <EOL> if initializer != None : <EOL> reduced = reduce ( function , self . iterator ( ) , initializer ) <EOL> else : <EOL> reduced = reduce ( function , self . iterator ( ) ) <EOL> collection = None <EOL> if new_collection in [ None , self . name ] : <EOL> collection = self <EOL> else : <EOL> collection = self . parent_db . collection ( new_collection , reset_collection = True , ** kwargs ) <EOL> collection . append ( reduced ) <EOL> return collection <EOL> def random_subset ( self , number , new_collection , ** kwargs ) : <EOL> """<STR_LIT>""" <EOL> collection = None <EOL> if new_collection in [ None , self . name ] : <EOL> collection = self <EOL> random . shuffle ( self . keys ) <EOL> for key in self . keys [ number : ] : <EOL> self . db . delete ( key ) <EOL> self . keys = self . keys [ : number ] <EOL> list . sort ( self . keys ) <EOL> else : <EOL> new_keys = copy . copy ( self . keys ) <EOL> random . shuffle ( new_keys ) <EOL> new_keys = new_keys [ : number ] <EOL> list . sort ( new_keys ) <EOL> collection = self . parent_db . collection ( new_collection , ** kwargs ) <EOL> collection . delete_all ( ) <EOL> for key in new_keys : <EOL> collection . append ( decode ( self . db . get ( key ) ) ) <EOL> return collection <EOL> def iterator ( self , start = None , end = None ) : <EOL> """<STR_LIT>""" <EOL> return Iterator ( self , start , end ) <EOL> def __iter__ ( self ) : <EOL> return self . iterator ( ) <EOL> def __getitem__ ( self , key ) : <EOL> if isinstance ( key , slice ) : <EOL> return [ decode ( self . db . get ( key ) ) for key in self . keys [ key ] ] <EOL> else : <EOL> return decode ( self . db . get ( self . keys [ key ] ) ) <EOL> def __setitem__ ( self , key , value ) : <EOL> self . db . put ( self . keys [ key ] , encode ( value ) ) <EOL> def __repr__ ( self ) : <EOL> return "<STR_LIT>" % ( self . __class__ , self . name ) <EOL> def __len__ ( self ) : <EOL> return len ( self . keys ) <EOL> class Iterator : <EOL> def __init__ ( self , collection , start = None , end = None ) : <EOL> self . key_iterator = iter ( collection . keys [ start : end ] ) <EOL> self . collection = collection <EOL> def __iter__ ( self ) : <EOL> return self <EOL> def next ( self ) : <EOL> return decode ( self . collection . db . get ( self . key_iterator . next ( ) ) ) <EOL> def __next__ ( self ) : <EOL> return decode ( self . collection . db . get ( self . key_iterator . __next__ ( ) ) ) <EOL> def encode ( obj ) : <EOL> return json . dumps ( obj ) . encode ( ) <EOL> def decode ( string ) : <EOL> return json . loads ( string . decode ( ) ) </s>
