import os

odl_string = '''
module Test {

class Student (extent students)
{
	attribute string name;

};
};
'''
#'

DBNAME=os.environ.get("ODS_TEST_DB","ods:test")

import sys, test_util
from Ft.Ods import Database
from Ft.Ods.StorageManager.Adapters import Constants

from Ft.Ods import Exception

def Test(tester):
    try:
        _Test(tester)
    finally:
        if os.path.exists('Test'):
            from distutils import dir_util
            dir_util.remove_tree('Test')


def _Test(tester):

    tester.startGroup("Bindings %s Driver" % tester.test_data['driver'])

    test_util.DbInit(DBNAME,odl_string)

    tester.startTest('Testing Generated syntax')
    try:
        from Test import Student
        reload(Student)
    except:
        tester.error('Error in syntax', 1)


    tester.testDone()

    db = Database.Database()
    db.open(DBNAME)

    try:
        tester.startTest("Lookup unbound object")
        tx = db.new()
        tx.begin()

        tester.testResults(None,db.lookup("Plato"),done=0,msg="Object returned when it shouldn't have been")

        tester.testDone()

        tester.startTest("Bind a new object")
        s = Student.new(db)
        s.name = 'Mike Olson'
        db.bind(s, 'Plato')
        tester.testResults(s,db.lookup("Plato"),done=0,msg="Object not returned when it should have been")

        tester.compare(s,db.lookup('Plato'))
        keys = db.keys()
        tester.compare(3,len(keys))
        tester.compare(1,'Plato' in keys)
        tester.compare(1,'ftods_types' in keys)
        tester.compare(1,'students' in keys)

        keys = db.keys(s)
        tester.compare(1,len(keys))
        tester.compare(1,'Plato' in keys)


        tx.commit()
        tester.testDone()

        tester.startTest("Lookup in a new transaction")

        id = s._4ods_getId()


        tx = db.new()
        tx.begin()

        s = db._4ods_getPersistentObjectById(Constants.Types.POBJECT,id)

        tester.testResults(s,db.lookup("Plato"),done=0,msg="Object not returned when it should have been")

        tester.testDone()

        tester.startTest("Unbind Object")

        db.unbind("Plato")

        tester.testResults(None,db.lookup("Plato"),done=0,msg="Object returned when it shouldn't have been")

        tx.commit()

        tester.testDone()

        tester.startTest("Lookup Unbound in new transaction")

        tx = db.new()
        tx.begin()

        tester.testResults(None,db.lookup("Plato"),done=0,msg="Object returned when it shouldn't have been")

        tx.commit()

        tester.testDone()

        ###########
        #Test some error and auto magic clean up stuff
        ###########

        tester.startTest("Test that there is no bind on a abort")
        tx = db.new()
        tx.begin()

        s = Student.new(db)
        s.name = "Plato"

        db.bind(s,"Plato")

        tx.abort()

        tx = db.new()
        tx.begin()

        tester.testResults(None,db.lookup("Plato"),done=0,msg="Object returned when it shouldn't have been")

        tx.abort()

        tester.testDone()


        tester.startTest("Testing binding 2 things to the same name")

        tx = db.new()
        tx.begin()

        s = Student.new(db)
        s.name = "Plato"

        db.bind(s,"Plato")

        tx.commit()

        tx = db.new()
        tx.begin()

        s = Student.new(db)
        s.name = "Plato2"


        try:
            db.bind(s,"Plato")
        except Exception.ObjectNameNotUnique, e:
            pass
        except:
            tester.error('Wrong Exception Raised', 1)
        else:
            tester.error('Binding Exception not raised', 0)

        tx.abort()
        tester.testDone()

        tester.startTest("Test Deleting the object")

        tx = db.new()
        tx.begin()

        s = db.lookup("Plato")

        s.delete()

        tx.commit()

        tx = db.new()
        tx.begin()

        tester.testResults(None,db.lookup("Plato"),done=0,msg="Object returned when it shouldn't have been")
        tx.abort()


        tester.startTest("Test with a bad bad name")
        tx = db.new()
        tx.begin()

        s = Student.new(db)
        s.name = "Plato2"

        try:
            db.bind(s,"$$.$$")
        except ValueError, e:
            pass
        except:
            tester.error('Wrong Exception Raised', 1)
        else:
            tester.error('Binding Exception not raised', 0)

        tx.abort()
    finally:
        db.close()
    tester.testDone()

    tester.groupDone()

