Content-Type: multipart/alternative; boundary="------------070205050605030101060001" --------------070205050605030101060001 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit Hello, Here is a patch that add simple inheritance to SQLObject 0.8.1. If you try it, please send me some comments (to the list or my email). Thanks. With this patch, the following code: class Person(SQLObject): _inheritable = 1 firstName = StringCol() lastName = StringCol() class Employee(Person): position = StringCol() will generate the following tables: CREATE TABLE person ( id INT PRIMARY KEY, child_id INT, child_name TEXT, first_name TEXT, last_name TEXT ); CREATE TABLE employee ( id INT PRIMARY KEY, parent_id INT, position TEXT ) A new class attribute '_inheritable' is added. When this new attribute is set to 1, the class is marked 'inheritable' and two colomns will automatically be added: childID (INT) and childName (TEXT). When a class inherits from a class that is marked inheritable, a new colomn (ForeignKey) will automatically be added: parent. The column parent is a foreign key that point to the parent class. It works as all SQLObject's foreign keys. There will also be a parentID attribute to retreive the ID of the parent class. The columns childID and childName will respectivly contain the id and the name of the child class (for exemple, 1 and 'Employee'. This will permit to call a new function: getSubClass() that will return a child class if possible. For exemple, the following code: p = Person(firstName='John', lastName='Doe') e = Employee(firstName='Jane', lastName='Doe', position='Chief') p2 = Person(1) Will create the following data in the database: *Person* id child_id child_name first_name last_name 0 Null Null John Doe 1 0 Employee Jane Doe *Employee* id parent_id position 0 1 Chief You will still be able to ask for the attribute normally: e.firstName will return Jane and setting it will write the new value in the person table. If you use p2, as p2 is a person object, you will only be able to retreive the firstName and lastName attribute. However, you can call the getSubClass function on it: e2 = p2.getSubClass() This function will return None if there is no subclass (as for the first person with id 0) and will return an Employee class for the second case (where id is 1). Once you got an Employee class, you can ask for the position attribute. e2.position will return 'Chief'. Also, deleting a person or an employee that are linked will destroy both entries as one would expect. The SQLObject q magic also work. Using this select are valid: Employee.select(Employee.q.firstName == 'Jane' & Employee.q.position == 'Chief') will return Jane Doe Employee.select(Person.q.firstName == 'Jane' & Employee.q.position == 'Chief') will return Jane Doe Employee.select(Employee.q.lastName == 'Doe') will only return Jane Doe (as Joe isn't an employee) Person.select(Person.q.lastName == 'Doe') will return both entries The SQL where clause will contain additional clauses when used with 'inherited' classes. These clauses are the link between the id and the parent id. This will look like the following request: SELECT employee.id, employee.parent_id, employee.first_name, employee.last_name, from employee FROM person, employee WHERE person.first_name = 'Jane' AND employee.position = 'Chief' AND person.id = employee.parent_id Some limitation or notice about this patch: - Only simple inheritance will work. It is not possible to inherits from multiple SQLObject classes. - It is possible to inherits from an inherited class and this will works well. In the above exemple, you can have a Chief class that inherits from Employee and all parents attributes will be available through the Chief class. - You may not redefine a parent column in a inherited class (this will raise an exception). - If you don't want the 'childID' and 'childName' columns in your last class (one that will never be inherited), you must set '_inheritable' to 0 in this class. - I made this patch because I needed to be able to have automatic inheritance with linked table. - This patch works for me, it may not works for you. I tried to do my best but it is possible that I broke some things... So, there is no warranty that this patch will work. - This patch is released under the LGPL (GNU Lesser General Public License) as the original SQLObject code. - Thanks to Ian Bicking for SQLObject, this is a wonderful python module. - If you have suggestion, bugs, or patch to this patch, you can contact me at Thanks, Daniel Savard XSOLI Inc. --------------070205050605030101060001 Content-Type: text/html; charset=us-ascii Content-Transfer-Encoding: 7bit Hello,

    Here is a patch that add simple inheritance to SQLObject 0.8.1.
    If you try it, please send me some comments (to the list or my email).  Thanks.

    With this patch, the following code:
class Person(SQLObject):
    _inheritable = 1
    firstName = StringCol()
    lastName = StringCol()

class Employee(Person):
    position = StringCol()
    will generate the following tables:
CREATE TABLE person (
    id INT PRIMARY KEY,
    child_id INT,
    child_name TEXT,
    first_name TEXT,
    last_name TEXT
);

CREATE TABLE employee (
    id INT PRIMARY KEY,
    parent_id INT,
    position TEXT
)
 
    A new class attribute '_inheritable' is added.  When this new attribute is set to 1, the class is marked 'inheritable' and two colomns will automatically be added: childID (INT) and childName (TEXT).  When a class inherits from a class that is marked inheritable, a new colomn (ForeignKey) will automatically be added: parent.

    The column parent is a foreign key that point to the parent class.  It works as all SQLObject's foreign keys.  There will also be a parentID attribute to retreive the ID of the parent class.

    The columns childID and childName will respectivly contain the id and the name of the child class (for exemple, 1 and 'Employee'.  This will permit to call a new function: getSubClass() that will return a child class if possible.

    For exemple, the following code:
p = Person(firstName='John', lastName='Doe')
e = Employee(firstName='Jane', lastName='Doe', position='Chief')
p2 = Person(1)

    Will create the following data in the database:
Person
id
child_id
child_name
first_name
last_name
0
Null
Null
John
Doe
1
0
Employee
Jane
Doe

Employee
id
parent_id
position
0
1
Chief

    You will still be able to ask for the attribute normally:
e.firstName will return Jane and setting it will write the new value in the person table.

    If you use p2, as p2 is a person object, you will only be able to retreive the firstName and lastName attribute.  However, you can call the getSubClass function on it:
e2 = p2.getSubClass()

    This function will return None if there is no subclass (as for the first person with id 0) and will return an Employee class for the second case (where id is 1).  Once you got an Employee class, you can ask for the position attribute.
e2.position will return 'Chief'.

    Also, deleting a person or an employee that are linked will destroy both entries as one would expect.

    The SQLObject q magic also work.  Using this select are valid:
Employee.select(Employee.q.firstName == 'Jane' & Employee.q.position == 'Chief') will return Jane Doe
Employee.select(Person.q.firstName == 'Jane' & Employee.q.position == 'Chief') will return Jane Doe
Employee.select(Employee.q.lastName == 'Doe') will only return Jane Doe (as Joe isn't an employee)
Person.select(Person.q.lastName == 'Doe') will return both entries

    The SQL where clause will contain additional clauses when used with 'inherited' classes.  These clauses are the link between the id and the parent id.  This will look like the following request:
    SELECT employee.id, employee.parent_id, employee.first_name, employee.last_name, from employee FROM person, employee WHERE person.first_name = 'Jane' AND employee.position = 'Chief' AND person.id = employee.parent_id

    Some limitation or notice about this patch:
- Only simple inheritance will work.  It is not possible to inherits from multiple SQLObject classes.
- It is possible to inherits from an inherited class and this will works well.  In the above exemple, you can have a Chief class that inherits from Employee and all parents attributes will be available through the Chief class.
- You may not redefine a parent column in a inherited class (this will raise an exception).
- If you don't want the 'childID' and 'childName' columns in your last class (one that will never be inherited), you must set '_inheritable' to 0 in this class.
- I made this patch because I needed to be able to have automatic inheritance with linked table.
- This patch works for me, it may not works for you.  I tried to do my best but it is possible that I broke some things... So, there is no warranty that this patch will work.
- This patch is released under the LGPL (GNU Lesser General Public License) as the original SQLObject code.
- Thanks to Ian Bicking for SQLObject, this is a wonderful python module.
- If you have suggestion, bugs, or patch to this patch, you can contact me at <sqlobject xsoli.com>

Thanks,
Daniel Savard
XSOLI Inc.
--------------070205050605030101060001--