<s> from py2neo . database import Graph , Resource , ResourceTemplate <EOL> from py2neo . types import Node , Relationship , remote <EOL> from py2neo . packages . httpstream . numbers import CREATED <EOL> from py2neo . packages . httpstream . packages . urimagic import percent_encode , URI <EOL> from . batch import ManualIndexWriteBatch <EOL> class ManualIndexManager ( object ) : <EOL> def __init__ ( self , graph ) : <EOL> self . graph = graph <EOL> self . _indexes = { Node : { } , Relationship : { } } <EOL> def _index_manager ( self , content_type ) : <EOL> """<STR_LIT>""" <EOL> if content_type is Node : <EOL> uri = remote ( self . graph ) . metadata [ "<STR_LIT>" ] <EOL> elif content_type is Relationship : <EOL> uri = remote ( self . graph ) . metadata [ "<STR_LIT>" ] <EOL> else : <EOL> raise TypeError ( "<STR_LIT>" ) <EOL> return Resource ( uri ) <EOL> def get_indexes ( self , content_type ) : <EOL> """<STR_LIT>""" <EOL> index_manager = self . _index_manager ( content_type ) <EOL> index_index = index_manager . get ( ) . content <EOL> if index_index : <EOL> self . _indexes [ content_type ] = dict ( <EOL> ( key , ManualIndex ( content_type , value [ "<STR_LIT>" ] ) ) <EOL> for key , value in index_index . items ( ) <EOL> ) <EOL> else : <EOL> self . _indexes [ content_type ] = { } <EOL> return self . _indexes [ content_type ] <EOL> def get_index ( self , content_type , index_name ) : <EOL> """<STR_LIT>""" <EOL> if index_name not in self . _indexes [ content_type ] : <EOL> self . get_indexes ( content_type ) <EOL> if index_name in self . _indexes [ content_type ] : <EOL> return self . _indexes [ content_type ] [ index_name ] <EOL> else : <EOL> return None <EOL> def get_or_create_index ( self , content_type , index_name , config = None ) : <EOL> """<STR_LIT>""" <EOL> index = self . get_index ( content_type , index_name ) <EOL> if index : <EOL> return index <EOL> index_manager = self . _index_manager ( content_type ) <EOL> rs = index_manager . post ( { "<STR_LIT:name>" : index_name , "<STR_LIT>" : config or { } } ) <EOL> index = ManualIndex ( content_type , rs . content [ "<STR_LIT>" ] ) <EOL> self . _indexes [ content_type ] . update ( { index_name : index } ) <EOL> return index <EOL> def delete_index ( self , content_type , index_name ) : <EOL> """<STR_LIT>""" <EOL> if index_name not in self . _indexes [ content_type ] : <EOL> self . get_indexes ( content_type ) <EOL> if index_name in self . _indexes [ content_type ] : <EOL> index = self . _indexes [ content_type ] [ index_name ] <EOL> remote ( index ) . delete ( ) <EOL> del self . _indexes [ content_type ] [ index_name ] <EOL> else : <EOL> raise LookupError ( "<STR_LIT>" ) <EOL> def get_indexed_node ( self , index_name , key , value ) : <EOL> """<STR_LIT>""" <EOL> index = self . get_index ( Node , index_name ) <EOL> if index : <EOL> nodes = index . get ( key , value ) <EOL> if nodes : <EOL> return nodes [ <NUM_LIT:0> ] <EOL> return None <EOL> def get_or_create_indexed_node ( self , index_name , key , value , properties = None ) : <EOL> """<STR_LIT>""" <EOL> index = self . get_or_create_index ( Node , index_name ) <EOL> return index . get_or_create ( key , value , properties or { } ) <EOL> def get_indexed_relationship ( self , index_name , key , value ) : <EOL> """<STR_LIT>""" <EOL> index = self . get_index ( Relationship , index_name ) <EOL> if index : <EOL> relationships = index . get ( key , value ) <EOL> if relationships : <EOL> return relationships [ <NUM_LIT:0> ] <EOL> return None <EOL> class ManualIndex ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , content_type , uri , name = None ) : <EOL> self . _content_type = content_type <EOL> key_value_pos = uri . find ( "<STR_LIT>" ) <EOL> if key_value_pos >= <NUM_LIT:0> : <EOL> self . _searcher = ResourceTemplate ( uri ) <EOL> self . __remote__ = Resource ( uri [ : key_value_pos ] ) <EOL> else : <EOL> self . __remote__ = Resource ( uri ) <EOL> self . _searcher = ResourceTemplate ( uri . string + "<STR_LIT>" ) <EOL> uri = remote ( self ) . uri <EOL> self . _create_or_fail = Resource ( uri . resolve ( "<STR_LIT>" ) ) <EOL> self . _get_or_create = Resource ( uri . resolve ( "<STR_LIT>" ) ) <EOL> self . _query_template = ResourceTemplate ( uri . string + "<STR_LIT>" ) <EOL> self . _name = name or uri . path . segments [ - <NUM_LIT:1> ] <EOL> self . __searcher_stem_cache = { } <EOL> self . graph = Graph ( uri . resolve ( "<STR_LIT>" ) . string ) <EOL> def __repr__ ( self ) : <EOL> return "<STR_LIT>" . format ( <EOL> self . __class__ . __name__ , <EOL> self . _content_type . __name__ , <EOL> repr ( remote ( self ) . uri . string ) <EOL> ) <EOL> def _searcher_stem_for_key ( self , key ) : <EOL> if key not in self . __searcher_stem_cache : <EOL> stem = self . _searcher . uri_template . string . partition ( "<STR_LIT>" ) [ <NUM_LIT:0> ] <EOL> self . __searcher_stem_cache [ key ] = stem + percent_encode ( key ) + "<STR_LIT:/>" <EOL> return self . __searcher_stem_cache [ key ] <EOL> def add ( self , key , value , entity ) : <EOL> """<STR_LIT>""" <EOL> remote ( self ) . post ( { <EOL> "<STR_LIT:key>" : key , <EOL> "<STR_LIT:value>" : value , <EOL> "<STR_LIT>" : remote ( entity ) . uri . string , <EOL> } ) <EOL> return entity <EOL> def add_if_none ( self , key , value , entity ) : <EOL> """<STR_LIT>""" <EOL> rs = self . _get_or_create . post ( { <EOL> "<STR_LIT:key>" : key , <EOL> "<STR_LIT:value>" : value , <EOL> "<STR_LIT>" : remote ( entity ) . uri . string , <EOL> } ) <EOL> if rs . status_code == CREATED : <EOL> return entity <EOL> else : <EOL> return None <EOL> @ property <EOL> def content_type ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . _content_type <EOL> @ property <EOL> def name ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . _name <EOL> def get ( self , key , value ) : <EOL> """<STR_LIT>""" <EOL> return [ <EOL> self . graph . _hydrate ( result ) <EOL> for result in self . _searcher . expand ( key = key , value = value ) . get ( ) . content <EOL> ] <EOL> def create ( self , key , value , abstract ) : <EOL> """<STR_LIT>""" <EOL> batch = ManualIndexWriteBatch ( self . graph ) <EOL> if self . _content_type is Node : <EOL> batch . create ( abstract ) <EOL> batch . add_to_index ( Node , self , key , value , <NUM_LIT:0> ) <EOL> elif self . _content_type is Relationship : <EOL> batch . create ( abstract ) <EOL> batch . add_to_index ( Relationship , self , key , value , <NUM_LIT:0> ) <EOL> else : <EOL> raise TypeError ( self . _content_type ) <EOL> entity , index_entry = batch . run ( ) <EOL> return entity <EOL> def _create_unique ( self , key , value , abstract ) : <EOL> """<STR_LIT>""" <EOL> if self . _content_type is Node : <EOL> body = { <EOL> "<STR_LIT:key>" : key , <EOL> "<STR_LIT:value>" : value , <EOL> "<STR_LIT>" : abstract <EOL> } <EOL> elif self . _content_type is Relationship : <EOL> body = { <EOL> "<STR_LIT:key>" : key , <EOL> "<STR_LIT:value>" : value , <EOL> "<STR_LIT:start>" : abstract [ <NUM_LIT:0> ] . uri . string , <EOL> "<STR_LIT:type>" : abstract [ <NUM_LIT:1> ] , <EOL> "<STR_LIT:end>" : abstract [ <NUM_LIT:2> ] . uri . string , <EOL> "<STR_LIT>" : abstract [ <NUM_LIT:3> ] if len ( abstract ) > <NUM_LIT:3> else None <EOL> } <EOL> else : <EOL> raise TypeError ( self . _content_type ) <EOL> return self . _get_or_create . post ( body ) <EOL> def get_or_create ( self , key , value , abstract ) : <EOL> """<STR_LIT>""" <EOL> return self . graph . _hydrate ( self . _create_unique ( key , value , abstract ) . content ) <EOL> def create_if_none ( self , key , value , abstract ) : <EOL> """<STR_LIT>""" <EOL> rs = self . _create_unique ( key , value , abstract ) <EOL> if rs . status_code == CREATED : <EOL> return self . graph . _hydrate ( rs . content ) <EOL> else : <EOL> return None <EOL> def remove ( self , key = None , value = None , entity = None ) : <EOL> """<STR_LIT>""" <EOL> if key and value and entity : <EOL> t = ResourceTemplate ( remote ( self ) . uri . string + "<STR_LIT>" ) <EOL> t . expand ( key = key , value = value , entity = remote ( entity ) . _id ) . delete ( ) <EOL> elif key and value : <EOL> uris = [ <EOL> URI ( remote ( entity ) . metadata [ "<STR_LIT>" ] ) <EOL> for entity in self . get ( key , value ) <EOL> ] <EOL> batch = ManualIndexWriteBatch ( self . graph ) <EOL> for uri in uris : <EOL> batch . append_delete ( uri ) <EOL> batch . run ( ) <EOL> elif key and entity : <EOL> t = ResourceTemplate ( remote ( self ) . uri . string + "<STR_LIT>" ) <EOL> t . expand ( key = key , entity = remote ( entity ) . _id ) . delete ( ) <EOL> elif entity : <EOL> t = ResourceTemplate ( remote ( self ) . uri . string + "<STR_LIT>" ) <EOL> t . expand ( entity = remote ( entity ) . _id ) . delete ( ) <EOL> else : <EOL> raise TypeError ( "<STR_LIT>" ) <EOL> def query ( self , query ) : <EOL> """<STR_LIT>""" <EOL> resource = self . _query_template . expand ( query = query ) <EOL> for result in resource . get ( ) . content : <EOL> yield self . graph . _hydrate ( result ) <EOL> def _query_with_score ( self , query , order ) : <EOL> resource = self . _query_template . expand ( query = query , order = order ) <EOL> for result in resource . get ( ) . content : <EOL> yield self . graph . _hydrate ( result ) , result [ "<STR_LIT>" ] <EOL> def query_by_index ( self , query ) : <EOL> return self . _query_with_score ( query , "<STR_LIT:index>" ) <EOL> def query_by_relevance ( self , query ) : <EOL> return self . _query_with_score ( query , "<STR_LIT>" ) <EOL> def query_by_score ( self , query ) : <EOL> return self . _query_with_score ( query , "<STR_LIT>" ) </s>
