Example #1
0
 def __define_virtuals(self):
     field_names = [field.name for field in self.fields]
     for name in dir(self):
         if not name.startswith("_"):
             obj = self.__getattribute__(name)
             if isinstance(obj, virtualfield):
                 if obj.field_name in field_names:
                     raise RuntimeError(
                         'virtualfield or fieldmethod cannot have same ' +
                         'name as an existent field!')
                 if isinstance(obj, fieldmethod):
                     #f = Field.Method(obj.field_name, lambda row, obj=obj,
                     #                 self=self: obj.f(self, row))
                     f = Field.Method(obj.field_name,
                                      _virtualwrap(self, obj))
                 else:
                     #f = Field.Virtual(obj.field_name, lambda row, obj=obj,
                     #                  self=self: obj.f(self, row))
                     f = Field.Virtual(obj.field_name,
                                       _virtualwrap(self, obj))
                 self.fields.append(f)
Example #2
0
    def __new__(
        cls,
        db,
        action,  # 'define_table' or 'Table'
        prefix=None,
        name=None,
        auto_pk=None,
        common_hook=None,
    ):
        tname = name or cls.__name__
        fields = list()
        hooks = dict()
        table_methods = dict(
        )  # https://github.com/web2py/pydal/blob/232e841765ee97ac6f7af45be794d46432085c4d/pydal/objects.py#L340
        kwargs = dict()
        need_pk = False
        for name, attr in cls.__dict__.items():
            if name.startswith('__'):
                continue

            # hooks
            if name in HOOKS:
                hooks[name] = attr
            # Field.Virtual
            elif isinstance(attr, property):
                fields.append(DalField.Virtual(name, attr.fget))
            # table method
            elif isinstance(attr, classmethod):
                table_methods[name] = attr.__func__
            # just Field
            elif isinstance(attr, Field):
                attr.name = name
                if not need_pk and auto_pk and name == 'id' and attr.args and attr.args[
                        0] != 'id':
                    need_pk = True
                fields.append(DalField(name, *attr.args, **attr.kwargs))
            # Field.Method
            elif callable(attr):
                fields.append(DalField.Method(name, attr))
            else:
                kwargs[name] = attr
        for sign in cls.__bases__:
            if sign is not Table:
                fields.append(get_signature(db, sign))
        args = [tname] + fields
        if action == 'Table':
            args.insert(0, db)
        action = getattr(db, action)

        # auto_pk
        if need_pk and kwargs.get('primarykey') is None:
            kwargs['primarykey'] = ['id']
        # rname prefix
        if prefix:
            kwargs['rname'] = f"{prefix}{tname}"

        # define table
        tbl = action(*args, **kwargs) or db[tname]

        # set hooks
        for hook_name, hook in hooks.items():
            tbl[f"_{hook_name}"].append(hook)
        if common_hook:
            for hook_name in HOOKS:
                tbl[f"_{hook_name}"].append(
                    lambda *args, hook_name=hook_name, **kw: common_hook(
                        tbl, hook_name, *args, **kw))
        # set table methods
        for meth_name, meth in table_methods.items():
            tbl.add_method.register(meth_name)(meth)
        return tbl