Ejemplo n.º 1
0
    def __init__(self,
                 query_type='SELECT *',
                 conditions={},
                 model=None,
                 db=None):
        from autorm.model import Model
        self.type = query_type
        self.conditions = conditions
        self.order = ''
        self.limit = ()
        self.cache = None
        if not issubclass(model, Model):
            raise Exception(
                'Query objects must be created with a model class.')
        self.model = model
        if model:
            select_fields = []
            for f in model.Meta.fields:
                if f.sql_type == 'GEOMETRY':
                    select_fields.append("AsText(%s)" % escape(f.name))
                else:
                    select_fields.append(escape(f.name))
            self.type = "SELECT %s" % ",".join(select_fields)

        if db:
            self.db = db
        elif model:
            self.db = model.db
Ejemplo n.º 2
0
 def _update(self):
     'Uses SQL UPDATE to update record'
     query = 'UPDATE %s SET ' % self.Meta.table_safe
     query += ', '.join(['%s = %s' % (escape(f.name), self.db.conn.placeholder) for f in self._changed])
     query += ' WHERE %s = %s ' % (escape(self.Meta.pk), self.db.conn.placeholder)
     
     values = [f.to_db(getattr(self, f.name)) for f in self._changed]
     values.append(self._get_pk())
     
     cursor = Query.raw_sql(query, values, self.db)
Ejemplo n.º 3
0
 def sql_conditional(self, value, operator, placeholder):
     if operator in ('notin', 'in'):
         if type(value) not in (list, tuple):
             value = (value, )
         return "%s %s (%s)" % (escape(self.name), OPERATORS[operator],
                                ",".join([placeholder] * len(value))), map(
                                    self.to_db, value)
     else:
         return "%s %s %s" % (escape(self.name), OPERATORS[operator],
                              placeholder), self.to_db(value)
Ejemplo n.º 4
0
 def sql_conditional(self, value, operator, placeholder):
     if operator in ("notin", "in"):
         if type(value) not in (list, tuple):
             value = (value,)
         return (
             "%s %s (%s)" % (escape(self.name), OPERATORS[operator], ",".join([placeholder] * len(value))),
             map(self.to_db, value),
         )
     else:
         return "%s %s %s" % (escape(self.name), OPERATORS[operator], placeholder), self.to_db(value)
Ejemplo n.º 5
0
    def _update(self):
        'Uses SQL UPDATE to update record'
        query = 'UPDATE %s SET ' % self.Meta.table_safe
        query += ', '.join([
            '%s = %s' % (escape(f.name), self.db.conn.placeholder)
            for f in self._changed
        ])
        query += ' WHERE %s = %s ' % (escape(
            self.Meta.pk), self.db.conn.placeholder)

        values = [f.to_db(getattr(self, f.name)) for f in self._changed]
        values.append(self._get_pk())

        cursor = Query.raw_sql(query, values, self.db)
Ejemplo n.º 6
0
    def extract_condition_clause_and_values(self):
        if not len(self.conditions):
            return "", []

            fail

        conds = []
        values = []

        if not self.model:
            for k, v in self.conditions.items():
                operator = "eq"
                if "__" in k:
                    name, operator = k.split("__")
                else:
                    name = k
                if operator in ('notin', 'in'):
                    if type(v) not in (list, tuple):
                        v = (v, )
                    conds.append("%s %s (%s)" %
                                 (escape(k), OPERATORS[operator], ",".join(
                                     [self.db.conn.placeholder] * len(v))))
                    values.extend(map(str, v))
                else:
                    conds.append("%s %s %s" % (escape(k), OPERATORS[operator],
                                               self.db.conn.placeholder))
                    values.append(v)
        else:
            for k, v in self.conditions.items():
                operator = "eq"
                if "__" in k:
                    name, operator = k.split("__")
                else:
                    name = k

                if name not in self.model.Meta.field_map:
                    raise Exception("Invalid field name: %s" % name)

                cond, val = self.model.Meta.field_map[name].sql_conditional(
                    v, operator, self.db.conn.placeholder)
                conds.append(cond)
                if type(val) in (list, tuple):
                    values.extend(val)
                else:
                    values.append(val)

        return 'WHERE %s' % ' AND '.join(conds), values
Ejemplo n.º 7
0
    def extract_condition_clause_and_values(self):
        if not len(self.conditions):
            return "", []
        
            fail
            
        conds = []
        values = []

        if not self.model:
            for k,v in self.conditions.items():
                operator = "eq"
                if "__" in k:
                    name, operator = k.split("__")
                else:
                    name = k
                if operator in ('notin','in'):
                    if type(v) not in (list, tuple):
                        v = (v,)
                    conds.append("%s %s (%s)" % (escape(k), OPERATORS[operator],",".join([self.db.conn.placeholder]*len(v)))) 
                    values.extend(map(str,v))
                else:
                    conds.append("%s %s %s" % (escape(k), OPERATORS[operator], self.db.conn.placeholder))
                    values.append(v)
        else:
            for k,v in self.conditions.items():
                operator = "eq"
                if "__" in k:
                    name, operator = k.split("__")
                else:
                    name = k
                
                if name not in self.model.Meta.field_map:
                    raise Exeption("Invalid field name: %s" % name)    
                
                cond, val = self.model.Meta.field_map[name].sql_conditional(v, operator, self.db.conn.placeholder)
                conds.append(cond)
                if type(val) in (list, tuple):
                    values.extend(val)
                else:
                    values.append(val)
                        
        return 'WHERE %s' % ' AND '.join(conds), values
Ejemplo n.º 8
0
    def sql_conditional(self, value, operator, placeholder):
        srid = None
        if HAS_DJGEOS:
            srid = value.srid
        if not srid:
            srid = self.srid

        return self.GEOM_OPERATORS[operator] % (
            escape(self.name), "GeomFromText(%s, %d)" %
            (placeholder, self.srid)), self.to_db(value)
Ejemplo n.º 9
0
    def sql_conditional(self, value, operator, placeholder):
        srid = None
        if HAS_DJGEOS:
            srid = value.srid
        if not srid:
            srid = self.srid

        return (
            self.GEOM_OPERATORS[operator] % (escape(self.name), "GeomFromText(%s, %d)" % (placeholder, self.srid)),
            self.to_db(value),
        )
Ejemplo n.º 10
0
 def __init__(self, query_type='SELECT *', conditions={}, model=None, db=None):
     from autorm.model import Model
     self.type = query_type
     self.conditions = conditions
     self.order = ''
     self.limit = ()
     self.cache = None
     if not issubclass(model, Model):
         raise Exception('Query objects must be created with a model class.')
     self.model = model
     if model:
         select_fields = []
         for f in model.Meta.fields:
             if f.sql_type == 'GEOMETRY':
                 select_fields.append("AsText(%s)" % escape(f.name))
             else: select_fields.append(escape(f.name))
         self.type = "SELECT %s" % ",".join(select_fields)
             
     if db:
         self.db = db
     elif model:
         self.db = model.db
Ejemplo n.º 11
0
    def _new_save(self):
        'Uses SQL INSERT to create new record'
        # if pk field is set, we want to insert it too
        # if pk field is None, we want to auto-create it from lastrowid
        include_pk = True if self._get_pk() is not None else False
        if not hasattr(self.__class__, "_insert_stmt_cache_%s" % include_pk):
            fields = [
                escape(f.name) for f in self._fields
                if f.name != self.Meta.pk or include_pk
            ]

            placeholders = []
            for f in self._fields:
                if f.name == self.Meta.pk and not include_pk:
                    continue
                if f.sql_type == 'GEOMETRY':
                    placeholders.append("GeomFromText(%s, %d)" %
                                        (self.db.conn.placeholder, f.srid))
                else:
                    placeholders.append(self.db.conn.placeholder)

            query = 'INSERT INTO %s (%s) VALUES (%s)' % (
                self.Meta.table_safe, ', '.join(fields),
                ', '.join(placeholders))
            setattr(self.__class__, "_insert_stmt_cache_%s" % include_pk,
                    query)
        else:
            query = getattr(self.__class__,
                            "_insert_stmt_cache_%s" % include_pk)

        values = [
            f.to_db(getattr(self, f.name, None)) for f in self._fields
            if f.name != self.Meta.pk or include_pk
        ]

        cursor = Query.raw_sql(query, values, self.db)

        if self._get_pk() is None:
            self._set_pk(cursor.lastrowid)

        return True
Ejemplo n.º 12
0
    def _new_save(self):
        'Uses SQL INSERT to create new record'
        # if pk field is set, we want to insert it too
        # if pk field is None, we want to auto-create it from lastrowid
        include_pk = True if self._get_pk() is not None else False
        if not hasattr(self.__class__, "_insert_stmt_cache_%s" % include_pk):
            fields=[
                escape(f.name) for f in self._fields 
                    if f.name != self.Meta.pk or include_pk
            ]
            
            placeholders = []
            for f in self._fields:
                if f.name == self.Meta.pk and not include_pk:
                    continue
                if f.sql_type == 'GEOMETRY':
                    placeholders.append("GeomFromText(%s, %d)" % (self.db.conn.placeholder, f.srid))
                else:
                    placeholders.append(self.db.conn.placeholder)
            
            query = 'INSERT INTO %s (%s) VALUES (%s)' % (
                   self.Meta.table_safe,
                   ', '.join(fields),
                   ', '.join(placeholders)
            )
            setattr(self.__class__, "_insert_stmt_cache_%s" % include_pk, query)
        else:
            query = getattr(self.__class__, "_insert_stmt_cache_%s" % include_pk)
            
        values = [f.to_db(getattr(self, f.name, None)) for f in self._fields
                      if f.name != self.Meta.pk or include_pk]    

        cursor = Query.raw_sql(query, values, self.db)
        
        if self._get_pk() is None:
            self._set_pk(cursor.lastrowid)

        return True
Ejemplo n.º 13
0
 def order_by(self, field, direction='ASC'):
     self.order = 'ORDER BY %s %s' % (escape(field), direction)
     return self
Ejemplo n.º 14
0
    def __new__(cls, name, bases, attrs):
        if name == 'Model':
            return super(ModelBase, cls).__new__(cls, name, bases, attrs)

        new_class = type.__new__(cls, name, bases, attrs)

        if not getattr(new_class, 'Meta', None):
            new_class.Meta = Empty

        if not getattr(new_class.Meta, 'table', None):
            new_class.Meta.table = name.lower()
        new_class.Meta.table_safe = escape(new_class.Meta.table)

        if not getattr(new_class.Meta, 'objects', None):
            setattr(new_class, 'objects', BaseManager())
        else:
            setattr(new_class, 'objects', new_class.Meta.objects)

        new_class.objects.rclass = new_class

        # See cursor.description
        # http://www.python.org/dev/peps/pep-0249/
        if not hasattr(new_class, "db"):
            new_class.db = autorm_db
        #db = new_class.db

        defaults = {}
        if not getattr(new_class.Meta, 'fields', None):
            q = Query.raw_sql('SELECT * FROM %s LIMIT 1' %
                              new_class.Meta.table_safe,
                              db=new_class.db)
            new_class._fields = [Field(f[0]) for f in q.description]

            for field in getattr(new_class.Meta, 'field_overrides', []):
                if field.name not in new_class._fields:
                    raise Exception("No db column named %s in %s" %
                                    (field.name, new_class.table))
                new_class._fields[new_class._fields.index(field.name)] = field
            new_class.Meta.fields = new_class._fields
        else:
            new_class._fields = getattr(new_class.Meta, 'fields')

        field_validations = getattr(new_class.Meta, 'validations', {})
        field_map = {}
        for f in new_class._fields:
            field_map[f.name] = f
            validation = f.validators()
            if not validation: continue
            if f.name in field_validations:
                if type(field_validations[f.name]) == tuple:
                    field_validations[f.name] = list(field_validations[f.name])
                elif type(field_validations[f.name]) != list:
                    field_validations[f.name] = [field_validations[f.name]]
                else:
                    field_validations[f.name].extend(validation)
            else:
                field_validations[f.name] = validation

        # cache a map of the fields
        new_class.Meta.field_map = field_map
        # Create function to loop over iterable validations
        if len(field_validations):
            new_class.Meta.validations = field_validations
        for k, v in field_validations.iteritems():
            if isinstance(v, (list, tuple)):
                new_class.Meta.validations[k] = ValidatorChain(*v)

        # TODO: fix, look at the fields
        # Assume id is the default
        if not getattr(new_class.Meta, 'pk', None):
            new_class.Meta.pk = 'id'

        cache.add(new_class)
        return new_class
Ejemplo n.º 15
0
 def order_by_FIELD_in(self, field, field_list, direction='ASC'):
     self.order = 'ORDER BY FIELD(%s, %s) %s' % (escape(field), ", ".join(
         map(str, field_list)), direction)
     return self
Ejemplo n.º 16
0
    def __new__(cls, name, bases, attrs):
        if name == 'Model':
            return super(ModelBase, cls).__new__(cls, name, bases, attrs)
            
        new_class = type.__new__(cls, name, bases, attrs)
        
        if not getattr(new_class, 'Meta', None):
            new_class.Meta = Empty
        
        if not getattr(new_class.Meta, 'table', None):
            new_class.Meta.table = name.lower()
        new_class.Meta.table_safe = escape(new_class.Meta.table)
                
        if not getattr(new_class.Meta, 'objects', None):
            setattr(new_class, 'objects', BaseManager())
        else:
            setattr(new_class, 'objects', new_class.Meta.objects)

        new_class.objects.rclass = new_class
        
        
        # See cursor.description
        # http://www.python.org/dev/peps/pep-0249/
        if not hasattr(new_class, "db"):
            new_class.db = autorm_db
        #db = new_class.db
        
        defaults = {}
        if not getattr(new_class.Meta, 'fields', None):
            q = Query.raw_sql('SELECT * FROM %s LIMIT 1' % new_class.Meta.table_safe, db=new_class.db)
            new_class._fields = [Field(f[0]) for f in q.description]
            
            for field in getattr(new_class.Meta, 'field_overrides', []):
                if field.name not in new_class._fields:
                    raise Exception("No db column named %s in %s" % (field.name, new_class.table))
                new_class._fields[new_class._fields.index(field.name)] = field
            new_class.Meta.fields = new_class._fields
        else:
            new_class._fields = getattr(new_class.Meta, 'fields')

        field_validations = getattr(new_class.Meta, 'validations', {})
        field_map = {}
        for f in new_class._fields:
            field_map[f.name] = f
            validation = f.validators()
            if not validation: continue
            if f.name in field_validations:
                if type(field_validations[f.name]) == tuple:
                    field_validations[f.name] = list(field_validations[f.name])
                elif type(field_validations[f.name]) != list:            
                    field_validations[f.name] = [field_validations[f.name]]
                else:
                    field_validations[f.name].extend(validation)
            else:
                field_validations[f.name] = validation
        
        # cache a map of the fields
        new_class.Meta.field_map = field_map
        # Create function to loop over iterable validations
        if len(field_validations):
            new_class.Meta.validations = field_validations
        for k, v in field_validations.iteritems():
            if isinstance(v, (list, tuple)):
                new_class.Meta.validations[k] = ValidatorChain(*v)
        
        # TODO: fix, look at the fields
        # Assume id is the default 
        if not getattr(new_class.Meta, 'pk', None):
            new_class.Meta.pk = 'id'
        
        cache.add(new_class)
        return new_class
Ejemplo n.º 17
0
Archivo: run.py Proyecto: umidev/autorm
    def testmodel(self):
        # Create tables

        ### MYSQL ###
        #
        # DROP TABLE IF EXISTS author;
        # CREATE TABLE author (
        #     id INT(11) NOT NULL auto_increment,
        #     first_name VARCHAR(40) NOT NULL,
        #     last_name VARCHAR(40) NOT NULL,
        #     bio TEXT,
        #     PRIMARY KEY (id)
        # );
        # DROP TABLE IF EXISTS books;
        # CREATE TABLE books (
        #     id INT(11) NOT NULL auto_increment,
        #     title VARCHAR(255),
        #     author_id INT(11),
        #     FOREIGN KEY (author_id) REFERENCES author(id),
        #     PRIMARY KEY (id)
        # );

        ### SQLITE ###
        #
        sqlite_create = """
         DROP TABLE IF EXISTS author;
         DROP TABLE IF EXISTS books;
         CREATE TABLE author (
           id INTEGER PRIMARY KEY AUTOINCREMENT,
           first_name VARCHAR(40) NOT NULL,
           last_name VARCHAR(40) NOT NULL,
           bio TEXT,
         );
         CREATE TABLE books (
           id INTEGER PRIMARY KEY AUTOINCREMENT,
           title VARCHAR(255),
           author_id INT(11),
           json_data TEXT, 
           FOREIGN KEY (author_id) REFERENCES author(id)
         );
        """
        # autorm_db.conn.connect('sqlite3', ':memory:')
        # Query.raw_sql(sqlite_create)

        for table in ("author", "books"):
            Query.raw_sql("DELETE FROM %s" % escape(table))

        # Test Creation
        assert Author.objects.query().count() == 0

        james = Author(first_name="James", last_name="Joyce")
        james.save()

        assert Author.objects.query().count() == 1

        kurt = Author(first_name="Kurt", last_name="Vonnegut")
        kurt.save()

        tom = Author(first_name="Tom", last_name="Robbins")
        tom.save()
        # print "Tom ID", tom.id
        Book(title="Ulysses", author_id=james.id).save()
        Book(title="Slaughter-House Five", author_id=kurt.id).save()
        Book(title="Jitterbug Perfume", author_id=tom.id).save()
        slww = Book(title="Still Life with Woodpecker", author_id=tom.id, json_data=["some", "data"])
        slww.save()

        # print "JSON Data = '%s'" % Book.objects.get(slww.id).json_data
        self.assertEqual(Book.objects.get(slww.id).json_data[0], "some")
        # Test ForeignKey
        self.assertEqual(slww.author.first_name, "Tom")

        # Test OneToMany
        self.assertEqual(len(list(tom.books)), 2)

        kid = kurt.id
        del (james, kurt, tom, slww)

        # Test retrieval
        b = Book.objects.query(title="Ulysses")[0]

        a = Author.objects.get(b.author_id)
        self.assertEqual(a.id, b.author_id)

        a = Author.objects.query(id=b.id)[:]
        self.assert_(isinstance(a, list))

        # Test update
        new_last_name = "Vonnegut, Jr."
        a = Author.objects.query(id=kid)[0]
        a.last_name = new_last_name
        a.save()

        a = Author.objects.get(kid)
        self.assertEqual(a.last_name, new_last_name)

        # Test count
        self.assertEqual(Author.objects.query().count(), 3)

        self.assertEqual(len(Book.objects.query()[1:4]), 3)

        # Test delete
        a.delete()
        self.assertEqual(Author.objects.query().count(), 2)

        # Test validation
        a = Author(first_name="", last_name="Ted")
        try:
            a.save()
            raise Exception("Validation not caught")
        except Model.ValidationError:
            pass

        # Test defaults
        a.first_name = "Bill and"
        a.save()
        self.assertEqual(a.bio, "No bio available")

        try:
            Author(first_name="I am a", last_name="BadGuy!").save()
            raise Exception("Validation not caught")
        except Model.ValidationError:
            pass
Ejemplo n.º 18
0
 def order_by(self, field, direction='ASC'):
     self.order = 'ORDER BY %s %s' % (escape(field), direction)
     return self
Ejemplo n.º 19
0
    def testmodel(self):
        # Create tables

        ### MYSQL ###
        #
        # DROP TABLE IF EXISTS author;
        # CREATE TABLE author (
        #     id INT(11) NOT NULL auto_increment,
        #     first_name VARCHAR(40) NOT NULL,
        #     last_name VARCHAR(40) NOT NULL,
        #     bio TEXT,
        #     PRIMARY KEY (id)
        # );
        # DROP TABLE IF EXISTS books;
        # CREATE TABLE books (
        #     id INT(11) NOT NULL auto_increment,
        #     title VARCHAR(255),
        #     author_id INT(11),
        #     FOREIGN KEY (author_id) REFERENCES author(id),
        #     PRIMARY KEY (id)
        # );

        ### SQLITE ###
        #
        sqlite_create = """
         DROP TABLE IF EXISTS author;
         DROP TABLE IF EXISTS books;
         CREATE TABLE author (
           id INTEGER PRIMARY KEY AUTOINCREMENT,
           first_name VARCHAR(40) NOT NULL,
           last_name VARCHAR(40) NOT NULL,
           bio TEXT,
         );
         CREATE TABLE books (
           id INTEGER PRIMARY KEY AUTOINCREMENT,
           title VARCHAR(255),
           author_id INT(11),
           json_data TEXT, 
           FOREIGN KEY (author_id) REFERENCES author(id)
         );
        """
        #autorm_db.conn.connect('sqlite3', ':memory:')
        #Query.raw_sql(sqlite_create)

        for table in ('author', 'books'):
            Query.raw_sql('DELETE FROM %s' % escape(table))

        # Test Creation
        assert Author.objects.query().count() == 0

        james = Author(first_name='James', last_name='Joyce')
        james.save()

        assert Author.objects.query().count() == 1

        kurt = Author(first_name='Kurt', last_name='Vonnegut')
        kurt.save()

        tom = Author(first_name='Tom', last_name='Robbins')
        tom.save()
        #print "Tom ID", tom.id
        Book(title='Ulysses', author_id=james.id).save()
        Book(title='Slaughter-House Five', author_id=kurt.id).save()
        Book(title='Jitterbug Perfume', author_id=tom.id).save()
        slww = Book(title='Still Life with Woodpecker',
                    author_id=tom.id,
                    json_data=['some', 'data'])
        slww.save()

        #print "JSON Data = '%s'" % Book.objects.get(slww.id).json_data
        self.assertEqual(Book.objects.get(slww.id).json_data[0], 'some')
        # Test ForeignKey
        self.assertEqual(slww.author.first_name, 'Tom')

        # Test OneToMany
        self.assertEqual(len(list(tom.books)), 2)

        kid = kurt.id
        del (james, kurt, tom, slww)

        # Test retrieval
        b = Book.objects.query(title='Ulysses')[0]

        a = Author.objects.get(b.author_id)
        self.assertEqual(a.id, b.author_id)

        a = Author.objects.query(id=b.id)[:]
        self.assert_(isinstance(a, list))

        # Test update
        new_last_name = 'Vonnegut, Jr.'
        a = Author.objects.query(id=kid)[0]
        a.last_name = new_last_name
        a.save()

        a = Author.objects.get(kid)
        self.assertEqual(a.last_name, new_last_name)

        # Test count
        self.assertEqual(Author.objects.query().count(), 3)

        self.assertEqual(len(Book.objects.query()[1:4]), 3)

        # Test delete
        a.delete()
        self.assertEqual(Author.objects.query().count(), 2)

        # Test validation
        a = Author(first_name='', last_name='Ted')
        try:
            a.save()
            raise Exception('Validation not caught')
        except Model.ValidationError:
            pass

        # Test defaults
        a.first_name = 'Bill and'
        a.save()
        self.assertEqual(a.bio, 'No bio available')

        try:
            Author(first_name='I am a', last_name='BadGuy!').save()
            raise Exception('Validation not caught')
        except Model.ValidationError:
            pass