예제 #1
0
  def create_index_request(self, app_id, http_request_data):
    """ High level function for creating composite indexes.

    Args:
       app_id: Name of the application.
       http_request_data: Stores the protocol buffer request from the 
               AppServer.
    Returns: 
       Returns an encoded response.
    """
    global datastore_access
    request = entity_pb.CompositeIndex(http_request_data)
    response = api_base_pb.Integer64Proto()

    if READ_ONLY:
      logger.warning('Unable to create in read-only mode: {}'.format(request))
      raise gen.Return(
        ('', datastore_pb.Error.CAPABILITY_DISABLED,
         'Datastore is in read-only mode.'))

    try:
      index_id = yield datastore_access.create_composite_index(app_id, request)
      response.set_value(index_id)
    except dbconstants.AppScaleDBConnectionError as error:
      logger.exception('DB connection error during index creation')
      raise gen.Return(('', datastore_pb.Error.INTERNAL_ERROR, str(error)))
    raise gen.Return((response.Encode(), 0, ''))
예제 #2
0
def CreateIndex(index):
    """Creates a new composite index in the datastore for this app.

  Args:
    index: entity_pb.CompositeIndex

  Returns:
    int, the id allocated to the index
  """
    resp = api_base_pb.Integer64Proto()
    resp = _Call('CreateIndex', index, resp)
    return resp.value()
예제 #3
0
    def _SetupIndexes(self, _open=open):
        """Ensure that the set of existing composite indexes matches index.yaml.
    
    Create any new indexes, and delete indexes which are no longer required.
   
    Args:
      _open: Function used to open a file.
    """
        if not self.__root_path:
            logging.warning("No index.yaml was loaded.")
            return
        index_yaml_file = os.path.join(self.__root_path, 'index.yaml')
        if (self.__cached_yaml[0] == index_yaml_file
                and os.path.exists(index_yaml_file) and
                os.path.getmtime(index_yaml_file) == self.__cached_yaml[1]):
            requested_indexes = self.__cached_yaml[2]
        else:
            try:
                index_yaml_mtime = os.path.getmtime(index_yaml_file)
                fh = _open(index_yaml_file, 'r')
            except (OSError, IOError):
                logging.info("Error reading file")
                index_yaml_data = None
            else:
                try:
                    index_yaml_data = fh.read()
                finally:
                    fh.close()
            requested_indexes = []
            if index_yaml_data is not None:
                index_defs = datastore_index.ParseIndexDefinitions(
                    index_yaml_data)
                if index_defs is not None and index_defs.indexes is not None:
                    requested_indexes = datastore_index.IndexDefinitionsToProtos(
                        self.__app_id, index_defs.indexes)
                    self.__cached_yaml = (index_yaml_file, index_yaml_mtime,
                                          requested_indexes)

        existing_indexes = datastore_pb.CompositeIndices()
        app_str = api_base_pb.StringProto()
        app_str.set_value(self.__app_id)
        self._Dynamic_GetIndices(app_str, existing_indexes)

        requested = dict(
            (x.definition().Encode(), x) for x in requested_indexes)
        existing = dict((x.definition().Encode(), x)
                        for x in existing_indexes.index_list())

        # Delete any indexes that are no longer requested.
        deleted = 0
        for key, index in existing.iteritems():
            if key not in requested:
                self._Dynamic_DeleteIndex(index, api_base_pb.VoidProto())
                deleted += 1

        # Add existing indexes in the index cache.
        for key, index in existing.iteritems():
            new_index = entity_pb.CompositeIndex()
            new_index.CopyFrom(index)
            ent_kind = new_index.definition().entity_type()
            if ent_kind in self.__index_cache:
                new_indexes = self.__index_cache[ent_kind]
                new_indexes.append(new_index)
                self.__index_cache[ent_kind] = new_indexes
            else:
                self.__index_cache[ent_kind] = [new_index]

        # Compared the existing indexes to the requested ones and create any
        # new indexes requested.
        created = 0
        for key, index in requested.iteritems():
            if key not in existing:
                new_index = entity_pb.CompositeIndex()
                new_index.CopyFrom(index)
                new_index.set_id(
                    self._Dynamic_CreateIndex(
                        new_index, api_base_pb.Integer64Proto()).value())
                new_index.set_state(entity_pb.CompositeIndex.READ_WRITE)
                self._Dynamic_UpdateIndex(new_index, api_base_pb.VoidProto())
                created += 1

                ent_kind = new_index.definition().entity_type()
                if ent_kind in self.__index_cache:
                    new_indexes = self.__index_cache[ent_kind]

                    new_indexes.append(new_index)
                    self.__index_cache[ent_kind] = new_indexes
                else:
                    self.__index_cache[ent_kind] = [new_index]

        if created or deleted:
            logging.info('Created %d and deleted %d index(es); total %d',
                         created, deleted, len(requested))