예제 #1
0
  def register_model(self, *fields, **kw):
    """Registers a single model for fulltext search. This basically creates
    a simple PonyWhoosh.Index for the model and calls self.register_index on it.

    Args:
        *fields: all the fields indexed from the model.
        **kw: The options for each field, sortedby, stored ...
    """

    index = PonyWhooshIndex(pw=self)

    index._kw = kw
    index._fields = fields

    def inner(model):
      """This look for the types of each field registered in the index,
      whether if it is Numeric, datetime, boolean or just text.

      Args:
          model (PonyORM.Entity): A model defined on the database with PonyORM

      Returns:
          model (PonyORM.Entity): A model modified for handle the appropriate
          search methods.
      """

      index._name = model._table_
      if not index._name:
        index._name  = model.__name__

      self._entities[index._name]     = model
      index._schema_attrs             = {}
      index._primary_key_is_composite =  model._pk_is_composite_
      index._primary_key              = [f.name for f in model._pk_attrs_]
      index._primary_key_type         = 'list'
      type_attribute                  = {}

      for field in model._attrs_:
        if field.is_relation:
          continue

        assert hasattr(field, "name") and hasattr(field, "py_type")

        fname = field.name
        if hasattr(field.name, "__name__"):
            fname = field.name.__name__

        stored = kw.get("stored", False)
        if fname in index._primary_key:
            kw["stored"] = True
        # we're not supporting this kind of data
        ftype = field.py_type.__name__
        if ftype in ['date', 'datetime', 'datetime.date']:
            kw["stored"] = stored
            continue

        fwhoosh = fwhoosh = whoosh.fields.TEXT(**kw)

        if field == model._pk_:
            index._primary_key_type = ftype
            fwhoosh = whoosh.fields.ID(stored=True, unique=True)

        if fname in index._fields:
          if not field.is_string:
            if ftype in ['int', 'float']:
              fwhoosh = whoosh.fields.NUMERIC(**kw)
            elif ftype == 'bool':
              fwhoosh = whoosh.fields.BOOLEAN(stored=True)

        type_attribute[fname]       = ftype
        index._schema_attrs[fname]  = fwhoosh
        kw["stored"]                = stored

      index._schema = whoosh.fields.Schema(**index._schema_attrs)

      self.register_index(index)

      def _middle_save_(obj, status):
        """A middle-in-middle method to intercept CRUD operations from PonyORM
        over the current object model to update the appropriate whoosh index.

        Args:
            obj (EntityInstance): An instance of a current model.
            status (str): Type of transaction on the database. A CRUD operation.

        Returns:
            obj (EntityInstance): The same object as the input.
        """
        writer = index._whoosh.writer(timeout=self.writer_timeout)

        dict_obj = obj.to_dict()

        def dumps(v):
          if isinstance(v, int):
            return unicode(v)
          if isinstance(v, float):
            return '%.9f' % v
          return unicode(v)

        attrs = {}
        for k, v in dict_obj.iteritems():
          if k in index._schema_attrs.keys():
            attrs[k] = dumps(v)

        if status == 'inserted':
          writer.add_document(**attrs)
        elif status == 'updated':
          writer.update_document(**attrs)
        elif status in set(['marked_to_delete', 'deleted', 'cancelled']):
          writer.delete_by_term(primary, attrs[primary])

        writer.commit()
        return obj._after_save_

      index._model        = model
      model._after_save_  = _middle_save_
      model._pw_index_    = index
      model.search        =  model._pw_index_.search
      return model
    return inner
예제 #2
0
  def register_model(self, *fields, **kw):
    """Registers a single model for fulltext search. This basically creates
    a simple PonyWhoosh.Index for the model and calls self.register_index on it.

    Args:
        *fields: all the fields indexed from the model.
        **kw: The options for each field, sortedby, stored ...
    """

    index         = PonyWhooshIndex(pw=self)
    index._kw     = kw
    index._fields = fields

    def inner(model):
      """This look for the types of each field registered in the index,
      whether if it is Numeric, datetime, boolean or just text.

      Args:
          model (PonyORM.Entity): A model defined on the database with PonyORM

      Returns:
          model (PonyORM.Entity): A model modified for handle the appropriate
          search methods.
      """

      index._name = model._table_
      if not index._name:
        index._name  = model.__name__

      self._entities[index._name]     = model
      index._schema_attrs             = {}
      index._primary_key_is_composite =  model._pk_is_composite_
      index._primary_key              = [f.name for f in model._pk_attrs_]
      index._primary_key_type         = 'list'
      type_attribute                  = {}

      for field in model._attrs_:
        if field.is_relation:
          continue

        assert hasattr(field, "name") and hasattr(field, "py_type")

        fname = field.name
        if hasattr(field.name, "__name__"):
            fname = field.name.__name__

        stored = kw.get("stored", False)
        if fname in index._primary_key:
            kw["stored"] = True
        # we're not supporting this kind of data
        ftype = field.py_type.__name__
        if ftype in ['date', 'datetime', 'datetime.date']:
            kw["stored"] = stored
            continue

        fwhoosh = fwhoosh = whoosh.fields.TEXT(**kw)

        if field == model._pk_:
            index._primary_key_type = ftype
            fwhoosh = whoosh.fields.ID(stored=True, unique=True)

        if fname in index._fields:
          if not field.is_string:
            if ftype in ['int', 'float']:
              fwhoosh = whoosh.fields.NUMERIC(**kw)
            elif ftype == 'bool':
              fwhoosh = whoosh.fields.BOOLEAN(stored=True)

        type_attribute[fname]       = ftype
        index._schema_attrs[fname]  = fwhoosh
        kw["stored"]                = stored

      index._schema = whoosh.fields.Schema(**index._schema_attrs)

      self.register_index(index)

      def _middle_save_(obj, status):
        """A middle-in-middle method to intercept CRUD operations from PonyORM
        over the current object model to update the appropriate whoosh index.

        Args:
            obj (EntityInstance): An instance of a current model.
            status (str): Type of transaction on the database. A CRUD operation.

        Returns:
            obj (EntityInstance): The same object as the input.
        """

        writer   = index._whoosh.writer(timeout=self.writer_timeout)
        dict_obj = obj.to_dict()

        def dumps(v):
          if isinstance(v, int):
            return unicode(v)
          if isinstance(v, float):
            return '%.9f' % v
          return unicode(v)

        attrs = {}
        for k, v in dict_obj.iteritems():
          if k in index._schema_attrs.keys():
            attrs[k] = dumps(v)

        if status == 'inserted':
          writer.add_document(**attrs)
        elif status == 'updated':
          writer.update_document(**attrs)
        elif status in set(['marked_to_delete', 'deleted', 'cancelled']):
          writer.delete_by_term(primary, attrs[primary])

        writer.commit()
        return obj._after_save_

      index._model       = model
      model._after_save_ = _middle_save_
      model._pw_index_   = index
      model.search       =  model._pw_index_.search
      return model
    return inner