2 Mix-ins that provide the actual commands for the indexer for various indexing
 
   9 # pylint: disable=C0111
 
  11 class AbstractPlacexRunner:
 
  12     """ Returns SQL commands for indexing of the placex table.
 
  14     SELECT_SQL = 'SELECT place_id FROM placex'
 
  16     def __init__(self, rank, analyzer):
 
  18         self.analyzer = analyzer
 
  22     @functools.lru_cache(maxsize=1)
 
  23     def _index_sql(num_places):
 
  24         return """ UPDATE placex
 
  25                    SET indexed_status = 0, address = v.addr, token_info = v.ti
 
  26                    FROM (VALUES {}) as v(id, addr, ti)
 
  28                """.format(','.join(["(%s, %s::hstore, %s::jsonb)"]  * num_places))
 
  32     def get_place_details(worker, ids):
 
  33         worker.perform("""SELECT place_id, (placex_prepare_update(placex)).*
 
  34                           FROM placex WHERE place_id IN %s""",
 
  35                        (tuple((p[0] for p in ids)), ))
 
  38     def index_places(self, worker, places):
 
  41             values.extend((place[x] for x in ('place_id', 'address')))
 
  42             values.append(psycopg2.extras.Json(self.analyzer.process_place(place)))
 
  44         worker.perform(self._index_sql(len(places)), values)
 
  47 class RankRunner(AbstractPlacexRunner):
 
  48     """ Returns SQL commands for indexing one rank within the placex table.
 
  52         return "rank {}".format(self.rank)
 
  54     def sql_count_objects(self):
 
  55         return """SELECT count(*) FROM placex
 
  56                   WHERE rank_address = {} and indexed_status > 0
 
  59     def sql_get_objects(self):
 
  60         return """{} WHERE indexed_status > 0 and rank_address = {}
 
  61                      ORDER BY geometry_sector
 
  62                """.format(self.SELECT_SQL, self.rank)
 
  65 class BoundaryRunner(AbstractPlacexRunner):
 
  66     """ Returns SQL commands for indexing the administrative boundaries
 
  71         return "boundaries rank {}".format(self.rank)
 
  73     def sql_count_objects(self):
 
  74         return """SELECT count(*) FROM placex
 
  75                   WHERE indexed_status > 0
 
  77                     AND class = 'boundary' and type = 'administrative'
 
  80     def sql_get_objects(self):
 
  81         return """{} WHERE indexed_status > 0 and rank_search = {}
 
  82                            and class = 'boundary' and type = 'administrative'
 
  83                      ORDER BY partition, admin_level
 
  84                """.format(self.SELECT_SQL, self.rank)
 
  87 class InterpolationRunner:
 
  88     """ Returns SQL commands for indexing the address interpolation table
 
  89         location_property_osmline.
 
  92     def __init__(self, analyzer):
 
  93         self.analyzer = analyzer
 
  98         return "interpolation lines (location_property_osmline)"
 
 101     def sql_count_objects():
 
 102         return """SELECT count(*) FROM location_property_osmline
 
 103                   WHERE indexed_status > 0"""
 
 106     def sql_get_objects():
 
 107         return """SELECT place_id
 
 108                   FROM location_property_osmline
 
 109                   WHERE indexed_status > 0
 
 110                   ORDER BY geometry_sector"""
 
 114     def get_place_details(worker, ids):
 
 115         worker.perform("""SELECT place_id, get_interpolation_address(address, osm_id) as address
 
 116                           FROM location_property_osmline WHERE place_id IN %s""",
 
 117                        (tuple((p[0] for p in ids)), ))
 
 121     @functools.lru_cache(maxsize=1)
 
 122     def _index_sql(num_places):
 
 123         return """ UPDATE location_property_osmline
 
 124                    SET indexed_status = 0, address = v.addr, token_info = v.ti
 
 125                    FROM (VALUES {}) as v(id, addr, ti)
 
 126                    WHERE place_id = v.id
 
 127                """.format(','.join(["(%s, %s::hstore, %s::jsonb)"]  * num_places))
 
 130     def index_places(self, worker, places):
 
 133             values.extend((place[x] for x in ('place_id', 'address')))
 
 134             values.append(psycopg2.extras.Json(self.analyzer.process_place(place)))
 
 136         worker.perform(self._index_sql(len(places)), values)
 
 140 class PostcodeRunner:
 
 141     """ Provides the SQL commands for indexing the location_postcode table.
 
 146         return "postcodes (location_postcode)"
 
 149     def sql_count_objects():
 
 150         return 'SELECT count(*) FROM location_postcode WHERE indexed_status > 0'
 
 153     def sql_get_objects():
 
 154         return """SELECT place_id FROM location_postcode
 
 155                   WHERE indexed_status > 0
 
 156                   ORDER BY country_code, postcode"""
 
 159     def index_places(worker, ids):
 
 160         worker.perform(""" UPDATE location_postcode SET indexed_status = 0
 
 161                            WHERE place_id IN ({})
 
 162                        """.format(','.join((str(i[0]) for i in ids))))