# Path: doodle/common/errors.py
# class PropertyError(BaseError):
#     pass
# 
# Path: doodle/core/property.py
# class BooleanProperty(Property):
#     def validate(self, value):
#         if value is not None:
#             return bool(value)
# 
# class IntegerProperty(Property):
#     def validate(self, value):
#         if value is not None:
#             try:
#                 return int(value)
#             except ValueError:
#                 raise ValueError('Property %s must be an int or long, not a %s'
#                                  % (self.name, value.__class__.__name__))
# 
# class PropertiedClass(type):
#     def __init__(cls, name, bases, dct):
#         super(PropertiedClass, cls).__init__(name, bases, dct)
# 
#         if 'KEY' not in cls.__dict__:
#             cls.KEY = cls.__name__
# 
#         if hasattr(cls, '_properties'):
#             cls._properties = cls._properties.copy()
#         else:
#             cls._properties = {}  # stores Property instances
# 
#         for prop_name, prop in dct.iteritems():
#             if isinstance(prop, Property):
#                 cls._properties[prop_name] = prop
#                 prop.name = prop_name
# 
# Path: doodle/core/redis_client.py



import logging
import json
from redis.client import Pipeline
from doodle.common.errors import PropertyError
from doodle.core.property import BooleanProperty, IntegerProperty, PropertiedClass
from doodle.core.redis_client import redis_main_client
            return [entity for entity in entities if entity]
        else:
            return [cls.from_json(json_content)
                    for json_content in results]

    @classmethod
    def _get_data_by_ids(cls, ids):
        key = cls.KEY
        pipe = cls.redis_client.pipeline(transaction=False)
        for entity_id in ids:
            # todo: check id > 0
            pipe.lindex(key, int(entity_id) - 1)
        return pipe.execute()

    def save(self, redis_client=None, inserting=False, relative=True, transactional=True):
        super(IDModel, self).save(redis_client, inserting, relative, transactional)

    def _check_inserting(self):
        if self.id is not None:
            raise PropertyError('cannot insert a %s object with id' % self.__class__.__name__)

    def _populate_required_attributes(self, pipeline):
        if self.id is None:
            self.id = pipeline.llen(self.KEY) + 1

    def _save_self(self, pipeline, inserting=False):
        if inserting:
            pipeline.rpush(self.KEY, self.to_json())
        else:
            if self.id is None:

# Path: doodle/common/errors.py
# class PropertyError(BaseError):
#     pass
# 
# Path: doodle/core/property.py
# class BooleanProperty(Property):
#     def validate(self, value):
#         if value is not None:
#             return bool(value)
# 
# class IntegerProperty(Property):
#     def validate(self, value):
#         if value is not None:
#             try:
#                 return int(value)
#             except ValueError:
#                 raise ValueError('Property %s must be an int or long, not a %s'
#                                  % (self.name, value.__class__.__name__))
# 
# class PropertiedClass(type):
#     def __init__(cls, name, bases, dct):
#         super(PropertiedClass, cls).__init__(name, bases, dct)
# 
#         if 'KEY' not in cls.__dict__:
#             cls.KEY = cls.__name__
# 
#         if hasattr(cls, '_properties'):
#             cls._properties = cls._properties.copy()
#         else:
#             cls._properties = {}  # stores Property instances
# 
#         for prop_name, prop in dct.iteritems():
#             if isinstance(prop, Property):
#                 cls._properties[prop_name] = prop
#                 prop.name = prop_name
# 
# Path: doodle/core/redis_client.py



# Path: doodle/core/models/base_model.py
import logging
import json
from redis.client import Pipeline
from doodle.common.errors import PropertyError
from doodle.core.property import BooleanProperty, IntegerProperty, PropertiedClass
from doodle.core.redis_client import redis_main_client

            return [entity for entity in entities if entity]
        else:
            return [cls.from_json(json_content)
                    for json_content in results]

    @classmethod
    def _get_data_by_ids(cls, ids):
        key = cls.KEY
        pipe = cls.redis_client.pipeline(transaction=False)
        for entity_id in ids:
            # todo: check id > 0
            pipe.lindex(key, int(entity_id) - 1)
        return pipe.execute()

    def save(self, redis_client=None, inserting=False, relative=True, transactional=True):
        super(IDModel, self).save(redis_client, inserting, relative, transactional)

    def _check_inserting(self):
        if self.id is not None:
            raise PropertyError('cannot insert a %s object with id' % self.__class__.__name__)

    def _populate_required_attributes(self, pipeline):
        if self.id is None:
            self.id = pipeline.llen(self.KEY) + 1

    def _save_self(self, pipeline, inserting=False):
        if inserting:
            pipeline.rpush(self.KEY, self.to_json())
        else:
            if self.id is None:

                raise PropertyError('cannot save a %s object without id' % self.__class__.__name__)