"""Benchmark for web2py DAL
"""

import datetime
import os
import sys
import time

from gluon.sql import DAL, Field

class ZooMark(object):

    def setup(self, uri, iterations, **opts):
        global db, ITERATIONS
        
        db = DAL(uri, pool_size=10)
        
        ITERATIONS = iterations
        
    def teardown(self):
        db.rollback()
        
        for table in db.tables:
            db[table].truncate("CASCADE")
            
        db.commit()

        
    def step_1_create_tables(self):
        Zoo = db.define_table('Zoo',
            Field('Name', length=255),
            Field('Founded', 'date'),
            Field('Opens', 'time'),
            Field('LastEscape', 'datetime'),
            Field('Admission', 'double'),
        )
        
        Animal = db.define_table('Animal',
            Field('ZooID', Zoo),
            Field('Name', length=100),
            Field('Species', length=100),
            Field('Legs', 'integer', default=4),
            Field('LastEscape', 'datetime'),
            Field('Lifespan', 'double'),
            Field('MotherID', 'reference Animal'),
            Field('PreferredFoodID', 'integer'),
            Field('AlternateFoodID', 'integer'),
        )
        
        db.commit()
        
    def step_1a_populate(self):
        Zoo = db.Zoo
        Animal = db.Animal
        
        wap = Zoo.insert(Name = u'Wild Animal Park',
                Founded = datetime.date(2000, 1, 1),
                Opens = datetime.time(8, 15, 59),
                LastEscape = datetime.datetime(2004, 7, 29, 5, 6, 7),
                Admission=4.95,
                )
                
        sdz = Zoo.insert(Name = u'San Diego Zoo',
            Founded = datetime.date(1835, 9, 13),
            Opens = datetime.time(9, 0, 0),
            Admission = 0,        
        )
        
        Zoo.insert(
            Name = u'Montr\xe9al Biod\xf4me',
            Founded = datetime.date(1992, 6, 19),
            Opens = datetime.time(9, 0, 0),
            Admission = 11.75,
        )
        
        seaworld = Zoo.insert(
            Name = u'Sea_World', Admission = 60
        )
        
        lp = Zoo.insert(Name = u'Luna Park',
                Founded = datetime.date(2072, 7, 17),
                Opens = datetime.time(0,0,0),
                Admission = 134.95,
        )
        
        leopardid = Animal.insert(Species = u'Leopard', Lifespan = 73.5)
        db(Animal.id == leopardid).update(ZooID = wap, LastEscape=datetime.datetime(2004, 12, 21, 8, 15, 0, 999907))
        
        lion = Animal.insert(Species=u'Lion', ZooID = wap)
        Animal.insert(Species=u'Slug', Legs=1, Lifespan = .75)
        
        tiger = Animal.insert(Species=u'Tiger', ZooID=sdz)
        
        Animal.insert(Species=u'Bear', Legs=4)
        Animal.insert(Species=u'Ostrich', Legs=2, Lifespan=103.2)
        Animal.insert(Species=u'Centipede', Legs=100)
        
        emp = Animal.insert(Species=u'Emperor Penguin', Legs=2, ZooID=seaworld)
        adelie = Animal.insert(Species=u'Adelie Penguin', Legs=2, ZooID=seaworld)
        
        Animal.insert(Species=u'Millipede', Legs=1000000, ZooID=sdz)
        
        bai_yun = Animal.insert(Species=u'Ape', Name=u'Bai Yun', Legs=2)
        Animal.insert(Species=u'Ape', Name=u'Hua Mei', Legs=2, MotherID=bai_yun)
        
        db.commit()
        
        
    def step_2_insert(self):
        Animal = db.Animal
        
        for x in xrange(ITERATIONS):
            tick = Animal.insert(Species=u'Tick', Name=u'Tick %d' % x, Legs=8)
            
        db.commit()
        
    def step_3_Properties(self):
        Zoo = db.Zoo
        Animal = db.Animal
        
        for x in xrange(ITERATIONS):
            WAP = list(db(Zoo.Name == u'Wild Animal Park').select())
            SDZ = list(db(Zoo.Founded == datetime.date(1835, 9, 13)).select())
            
            Biodome = list(db(Zoo.Name == u'Montr\xe9al Biod\xf4me').select())
            seaworld = list(db(Zoo.Admission == float(60)).select())
            
            leopard = list(db(Animal.Species == u'Leopard').select())
            ostrich = list(db(Animal.Species == u'Ostrich').select())
            millipede = list(db(Animal.Legs==1000000).select())
            ticks = list(db(Animal.Species == u'Tick').select())
            
    def step_4_Expressions(self):
    
        Zoo = db.Zoo
        Animal = db.Animal
        
        for x in xrange(ITERATIONS):
            assert len(db(Zoo.id > 0).select()) == 5
            assert len(db(Animal.id > 0).select()) == ITERATIONS + 12
            assert len(db(Animal.Legs == 4).select()) == 4
            assert len(db(Animal.Legs == 2).select()) == 5
            assert len(db(Animal.Legs >= 2)(Animal.Legs < 20).select()) == ITERATIONS + 9
            assert len(db(Animal.Legs > 10).select()) == 2
            assert len(db(Animal.Lifespan > 70).select()) == 2
            assert len(db(Animal.Species.like('L%')).select()) == 2
            assert len(db(Animal.Species.like('%pede')).select()) == 2
            assert len(db(Animal.LastEscape != None).select()) == 1
            assert len(db(Animal.LastEscape == None).select()) == ITERATIONS + 11
            assert len(db(Animal.Species.like(u'%pede%')).select()) == 2
            assert len(db(Animal.Species.belongs((u'Lion', u'Tiger', u'Bear'))).select()) == 3
            
            
            assert len(db(Animal.Species.lower().like(u'slug')).select()) == 1
            assert len(db(Animal.Species.upper().like(u'%PEDE%')).select()) == 2
            name = u'Lion'
            assert len(db(Animal.Species.like(u'%i%')).select()) == ITERATIONS + 7
            assert len(db(Zoo.Founded != None)(Zoo.Founded < datetime.datetime.now()).select()) == 3
            assert len(db(Animal.LastEscape == datetime.datetime.now()).select()) == 0
            assert len(db(Animal.LastEscape.year() == 2004).select()) == 1
            assert len(db(Animal.LastEscape.month() == 12).select()) == 1
            assert len(db(Animal.LastEscape.day() == 21).select()) == 1
            
    def step_5_Aggregates(self):
        Animal = db.Animal
        Zoo = db.Zoo
        
        for x in xrange(ITERATIONS):
            
            view = db(Animal.id > 0).select(Animal.Legs)
            legs = [x.Legs for x in view]
            legs.sort()
            
            expected = {'Leopard': 73.5,
                        'Slug': .75,
                        'Tiger': None,
                        'Lion': None,
                        'Bear': None,
                        'Ostrich': 103.2,
                        'Centipede': None,
                        'Emperor Penguin': None,
                        'Adelie Penguin': None,
                        'Millipede': None,
                        'Ape': None,
                        'Tick': None,
                        }
                        
            for row in db(Animal.id > 0).select(Animal.Species, Animal.Lifespan):
                assert row.Lifespan == expected[row.Species]
                
            expected = [u'Montr\xe9al Biod\xf4me', u'Wild Animal Park']
            
            e = db(Zoo.Founded != None)(Zoo.Founded <= datetime.date.today())(Zoo.Founded >= datetime.date(1990, 1, 1)).select(Zoo.Name)
            
            legs = [x.Legs for x in db(Animal.id > 0).select(Animal.Legs, distinct=True)]
            legs.sort()
            
    def step_6_Editing(self):
        
        Zoo = db.Zoo
        
        
        for x in xrange(ITERATIONS):
            SDZ = db(Zoo.Name == u'San Diego Zoo').select().first()
            db(Zoo.id == SDZ).update(
                Name = u'The San Diego Zoo',
                Founded = datetime.date(1900, 1, 1),
                Opens = datetime.time(7, 30, 0),
                Admission = "35.00"
            )
            db.commit()
            SDZ = db(Zoo.Name == u'The San Diego Zoo').select().first()
            assert SDZ.Founded == datetime.date(1900, 1, 1)
            
            SDZ.update_record(
                dict(
                    Name = u'San Diego Zoo',
                    Founded = datetime.date(1835, 9, 13),
                    Opens = datetime.time(9, 0, 0),
                    Admission = "0"
                )
            )
            
            db.commit()
            
            SDZ = db(Zoo.Name == u'San Diego Zoo').select().first()
            assert SDZ.Founded == datetime.date(1835, 9, 13)
            
    def step_7_Multiview(self):
        Zoo = db.Zoo
        Animal = db.Animal
        
        for x in xrange(ITERATIONS):
            za = db(Zoo.id == Animal.ZooID)(Zoo.Name == u'San Diego Zoo').select(Zoo.id, Animal.ALL)
            
            SDZ = db(Zoo.Name == u'San Diego Zoo').select()
            
            e = db(Zoo.id == Animal.ZooID)(Zoo.Name == u'San Diego Zoo')(
                    Animal.Species == u'Leopard').select(Zoo.id, Animal.id)
                    
            e = db(Zoo.id == Animal.ZooID).select(Zoo.Name, Animal.Species)
            e = db(Zoo.id > 0).select(Zoo.Name, Animal.Species, left=Zoo.on(Zoo.id == Animal.ZooID))
            e = db(Animal.id > 0).select(Zoo.Name, Animal.Species, left=Animal.on(Zoo.id == Animal.ZooID))
    
    
    
    
    
    
    
    
    
    
    
    

