View · Index

::xo::db Object Relational Database Interface

The database abstraction layer of xotcl-core interfaces between the OpenACS object model used in the relational Database and XOTcl objects. The database abstraction layer works for PostgreSQL and Oracle in exact the same way.

The functionality of the database abstraction layer provides separate classes for operation on generic ACS objects and on objects stored in the OpenACS content repository. The generic lookup queries and instantiate methods are provided through the following classes

Generic operations on ACS Object IDs:

  • ::xo::db::Class get_object_type -id
  • ::xo::db::Class get_instance_from_db -id
  • ::xo::db::Class exists_in_db -id
  • ::xo::db::Class delete -id

Generic operations on ACS Object Types:

  • ::xo::db::Class get_table_name -object_type
  • ::xo::db::Class object_type_exists_in_db -object_type
  • ::xo::db::Class get_class_from_db -object_type
  • ::xo::db::Class drop_type -object_type -drop_table -cascade_p
  • ::xo::db::Class delete_all_acs_objects -object_type

Generic operations on items of the content repository:

  • ::xo::db::CrClass get_object_type -item_id -revision_id
  • ::xo::db::CrClass get_instance_from_db -item_id -revision_id
  • ::xo::db::CrClass lookup -item_id -revision_id
  • ::xo::db::CrClass delete -item_id

Methods on classes for ACS Object Types

  • <classname> new_persistent_object -package_id -creation_user -creation_ip ...
  • <classname> object_types -subtypes_first
  • <classname> create_object_type
  • <classname> drop_object_type -cascade
  • <classname> instance_select_query ...
  • <classname> get_instances_from_db ...

Methods on content repository classes

  • <classname> new_persistent_object -package_id -creation_user -creation_ip ...
  • <classname> create_object_type
  • <classname> drop_object_type
  • <classname> get_instance_from_db -item_id -revision_id
  • <classname> instance_select_query ...
  • <classname> get_instances_from_db ...
  • <classname> folder_type_unregister_all -include_subtypes -folderid register|unregister
  • <classname> folder_type_unregister_all -include_subtypes

Methods on instances of ordinary classes

  • <object> save -package_id -modifying_user
  • <object> save_new -package_id -creation_user -creation_ip
  • <object> delete

Methods on instances of content repository classes

  • <object> save -modifying_user -live_p
  • <object> save_new -package_id -creation_user -creation_ip -live_p
  • <object> set_live_revision -revision_id -publish_status
  • <object> delete

The following links provide a detailed description of these classes in the version as they are installed on openacs.org: ::xo::db::Class and ::xo::db::CrClass

The xotcl-core Database Abstraction Layer by Examples 

The remainder of this page provides a short tutorial into the basic functionality of the interface. A more detailed description can be found in the xotcl-core tutorial

############################################################
#
# 1) Create new ACS Objects, destroy it in memory, 
#    load it from the database, delete it in the database.
#
.. Create a plain new ACS object just for demo purposes.
.. The ACS object is created with a new object id.

>> set o [::xo::db::Object new_persistent_object]
=  ::7845

.. Show the contents of object ::7845 by serializing it:

>> ::7845 serialize
=  ::xo::db::Object create ::7845 -noinit \
    -set object_title {Object 7845} \
    -set object_id 7845 


.. In the next steps, we (a) get the object_id of the newly
.. created ACS object, (b) destroy the XOTcl object (the ACS
.. object is still in the database, (c) we recreate the
.. XOTcl object from the database, and (d) delete it in the 
.. database.

.. Step (a)
>> set o_id [::7845 object_id]
=  7845

#
# Delete object from memory: <object> destroy 
# Check, if an XOTcl object exists: ::xotcl::Object isobject <obj>
#
>> ::xotcl::Object isobject ::7845
=  1

.. Step (b)
>> ::7845 destroy

>> ::xotcl::Object isobject ::7845
=  0

#
# Load an object from the database: ::xo::db::Class get_instance_from_db -id <id>
#
.. Step (c)
>> set o [::xo::db::Class get_instance_from_db -id 7845]
=  ::7845

>> ::xotcl::Object isobject ::7845
=  1

.. Now, we have recreated the same object as before:

>> ::7845 serialize
=  ::xo::db::Object create ::7845 -noinit \
    -set object_title {Object 7845} \
    -set object_id 7845 


#
# Check, if an ACS object exists in the database: ::xo::db::Class exists_in_db -id <id>
# Delete object from memory and database: <object> delete 
#
>> ::xo::db::Class exists_in_db -id 7845
=  1

.. Step (d)
>> ::7845 delete

.. Now, we have deleted the ACS Object and the XOTcl object:

>> ::xo::db::Class exists_in_db -id 7845
=  0

>> ::xotcl::Object isobject ::7845
=  0


############################################################
#
# 2) Create new ACS Object Types, ACS Attributes and 
#    SQL Tables from XOTcl Classes with slot definitions.
#
.. We want to create a new ACS Object type and 
.. an XOTcl class named ::demo::Person.

.. Does the ACS Object type ::demo::Person exist in the database?
>> ::xo::db::Class object_type_exists_in_db -object_type ::demo::Person
=  0

.. The ACS Object Type should not exist (statement should return 0)

.. We create a new XOTcl Class '::demo::Person'.
.. By defining this class, the database layer takes care
.. of creating the ACS Object Type and the necessary table via SQL.

.. The persistent attributes (stored in the database) are defined
.. as slots of type ::xo::db::Attribute.

>> 
::xo::db::Class create ::demo::Person  \
   -superclass ::xo::db::Object  \
   -slots {
      ::xo::db::Attribute create name -column_name pname
      ::xo::db::Attribute create age -default 0 -datatype integer
      ::xo::db::Attribute create projects -default {} -multivalued true
    }

=  ::demo::Person

.. If the ACS Object Type and the ACS Attributes would be
.. already defined in the database, the class definition above 
.. would be a no-op operation.

.. Now, the ACS Object Type exists in the database

>> ::xo::db::Class object_type_exists_in_db -object_type ::demo::Person
=  1

.. The XOTcl class definition created automatically the 
.. following table for storing instances:

CREATE TABLE demo_person (
    age  integer DEFAULT '0' ,
    pname  text ,
    projects  text DEFAULT '' ,
    person_id  integer REFERENCES acs_objects(object_id) ON DELETE CASCADE
    CONSTRAINT demo_person_person_id_pk PRIMARY KEY 
)

.. SQL attribute slot names:
>> ::demo::Person array names db_slot
=  name age projects person_id

.. The XOTcl class definition created as well a 'save' and
.. an 'insert' method:

.. Created 'save' method:

::demo::Person instproc save {}  {
      db_transaction {
    next
    my instvar object_id name age projects
    db_dml dbqd..update_demo_person {update demo_person
      set pname = :name,age = :age,projects = :projects
          where person_id = :object_id
    }
      }
    }

.. Created 'insert' method:

::demo::Person instproc insert {}  {
      set __table_name [[self class] table_name]
      set __id [[self class] id_column]
      my set $__id [my set object_id]
      my log "ID insert in $__table_name, id = $__id = [my set $__id]"
      next
      foreach {__slot_name __slot} [[self class] array get db_slot] {
    my instvar $__slot_name
    if {[info exists $__slot_name]} { 
      lappend __vars $__slot_name
      lappend __atts [$__slot column_name]
    }
      }
      db_dml dbqd..insert_$__table_name "insert into $__table_name
        ([join $__atts ,]) values (:[join $__vars ,:])"
    }

.. The 'insert' method is typically called via
.. '<classname> new', which takes care about db_transaction (see below)

#
# Create a new instance of ::demo::Person with name 'Gustaf'
#
# The method 'new_persistent_object' of a database class (instance of ::xo::db::Class)
# creates an ACS Object with a fresh id in the database and 
# creates as well an XOTcl object in memory

>> set p [::demo::Person new_persistent_object -name Gustaf -age 105]
=  ::7846

::7846 created

.. check, if object ::7846 exists in memory
>> ::xotcl::Object isobject ::7846
=  1

.. check, if object ::7846 exists in the database
>> ::xo::db::Class exists_in_db -id 7846
=  1

.. Every persistent XOTcl object has an object_id.
>> ::7846 exists object_id
=  1

.. Show the contents of object ::7846 (using serialize)

>> ::7846 serialize
=  ::demo::Person create ::7846 -noinit \
    -set object_title {Person 7846} \
    -set name Gustaf \
    -set age 105 \
    -set projects {} \
    -set person_id 7846 \
    -set object_id 7846 


.. modify some attributes of the XOTcl object
>> ::7846 incr age
=  106

.. show modified contents of ::7846

::demo::Person create ::7846 -noinit \
    -set object_title {Person 7846} \
    -set name Gustaf \
    -set age 106 \
    -set projects {} \
    -set person_id 7846 \
    -set object_id 7846 

.. save the modified object data in the database
>> ::7846 save

>> set person_id [$p person_id]
=  7846

.. deleting xotcl object ::7846 in memory
>> $p destroy

.. check, if object ::7846 exists in memory
>> ::xotcl::Object isobject ::7846
=  0

.. check, if object ::7846 exists in the database
>> ::xo::db::Class exists_in_db -id 7846
=  1

.. fetch person again from database:

>> set p [::xo::db::Class get_instance_from_db -id 7846]
=  ::7846

.. check, if object ::7846 exists in memory
>> ::xotcl::Object isobject ::7846
=  1

::demo::Person create ::7846 -noinit \
    -set object_title {Person 7846} \
    -set name Gustaf \
    -set age 106 \
    -set projects {} \
    -set object_id 7846 \
    -set person_id 7846 


.. The object ::7846 was fetched from the database using the
.. automatically created query:

SELECT demo_person.pname AS name,demo_person.age,
   demo_person.projects,demo_person.person_id,
   acs_objects.title AS object_title,acs_objects.object_id
FROM demo_person,acs_objects
WHERE person_id = 7846 and object_id = person_id

.. In order to delete an object from the database, 
.. the method 'delete' can be used. 'delete' deletes the 
.. ACS object in the database as well the XOTcl object in memory.

>> set p_id [::7846 object_id]
=  7846

>> ::xo::db::Class exists_in_db -id 7846
=  1

>> ::7846 delete

>> ::xo::db::Class exists_in_db -id 7846
=  0

.. Instead of using 'new_persistent_object' to create
.. new acs_objects, one can use the method 'new' in 
.. combination with 'save_new'. While the method 'new' creates
.. an XOTcl object in memory, the method 'save_new' can be used
.. to create a new ACS object (with a new object_id) an to 
.. save this object persistently in the database.

>> set p [::demo::Person new -name Gustaf -age 105]
=  ::xotcl::__#A

>> ::xotcl::__#A exists object_id
=  0

>> ::xotcl::__#A save_new
=  7847

>> ::xotcl::__#A exists object_id
=  1


.. Now, we create a subclass of ::demo::Person called ::demo::Employee
.. which has a few more attributes. Again, we define an XOTcl class
.. ::demo::Employee which creates the ACS Object Type, the ACS
.. attributes and the table, if necessary.

>> 
::xo::db::Class create ::demo::Employee  \
   -superclass ::demo::Person  \
   -table_name demo_employee \
   -id_column employee_id  \
   -slots {
      ::xo::db::Attribute create salary -datatype integer
      ::xo::db::Attribute create dept_nr -datatype integer -default "0"
    }

=  ::demo::Employee


.. The XOTcl class definition created automatically the 
.. following table for storing instances:

CREATE TABLE demo_employee (
    dept_nr  integer DEFAULT '0' ,
    salary  integer ,
    employee_id  integer REFERENCES demo_person(person_id) ON DELETE CASCADE
    CONSTRAINT demo_employee_employee_id_pk PRIMARY KEY 
)

.. Create a first new employee:
>> set p1 [::demo::Employee new_persistent_object -name Neophytos -age 25]
=  ::7848

.. show contents of ::7848

::demo::Employee create ::7848 -noinit \
    -set employee_id 7848 \
    -set object_title {Employee 7848} \
    -set dept_nr 0 \
    -set name Neophytos \
    -set age 25 \
    -set projects {} \
    -set person_id 7848 \
    -set object_id 7848 

.. Create a second new employee:
>> set p2 [::demo::Employee new_persistent_object -name Lore -age 35 -salary 100000]
=  ::7849

.. show contents of ::7849

::demo::Employee create ::7849 -noinit \
    -set employee_id 7849 \
    -set object_title {Employee 7849} \
    -set salary 100000 \
    -set dept_nr 0 \
    -set name Lore \
    -set age 35 \
    -set projects {} \
    -set person_id 7849 \
    -set object_id 7849 

.. Create a third new employee:
>> set p3 [::demo::Employee new_persistent_object -name Nora -age 7 -salary 100]
=  ::7850

.. show contents of ::7850

::demo::Employee create ::7850 -noinit \
    -set employee_id 7850 \
    -set object_title {Employee 7850} \
    -set salary 100 \
    -set dept_nr 0 \
    -set name Nora \
    -set age 7 \
    -set projects {} \
    -set person_id 7850 \
    -set object_id 7850 

#
# Delete object from memory: <object> destroy 
#
>> ::xotcl::Object isobject ::7848
=  1

>> set p1_id [$p1 object_id]
=  7848

>> ::xo::db::Class exists_in_db -id 7848
=  1

>> $p1 destroy

>> ::xotcl::Object isobject ::7848
=  0

>> ::xo::db::Class exists_in_db -id 7848
=  1

#
# Delete object from memory and database: <object> delete 
#
>> ::xotcl::Object isobject ::7849
=  1

>> set p2_id [$p2 object_id]
=  7849

>> ::xo::db::Class exists_in_db -id 7849
=  1

>> $p2 delete

>> ::xotcl::Object isobject ::7849
=  0

>> ::xo::db::Class exists_in_db -id 7849
=  0

.. Fetch employee with id 7848 again from the database:

>> set p [::xo::db::Class get_instance_from_db -id 7848]
=  ::7848

.. show contents of ::7848

::demo::Employee create ::7848 -noinit \
    -set object_title {Employee 7848} \
    -set salary {} \
    -set employee_id 7848 \
    -set dept_nr 0 \
    -set name Neophytos \
    -set age 25 \
    -set projects {} \
    -set object_id 7848 \
    -set person_id 7848 

.. The object ::7848 was fetched from the database using the
.. automatically created query:

SELECT demo_employee.employee_id,demo_employee.salary,
   demo_employee.dept_nr, 
   demo_person.pname AS name,demo_person.age,
   demo_person.projects,demo_person.person_id,
   acs_objects.title AS object_title,acs_objects.object_id
FROM demo_employee,demo_person,acs_objects
WHERE employee_id = 7848 and person_id = employee_id 
   and object_id = employee_id

>> ::7848 destroy



.. Query the instances from the database

.. Instances are queried by default based on the following,
.. automatically generated SQL Query:

>> ::demo::Employee instance_select_query
=  SELECT demo_employee.employee_id,demo_employee.salary,
     demo_employee.dept_nr,
     demo_person.pname AS name,demo_person.age,
     demo_person.projects, demo_person.person_id,
     acs_objects.title AS object_title,acs_objects.object_id 
   FROM demo_employee,demo_person,acs_objects  
   WHERE person_id = employee_id and object_id = employee_id   

.. Query the object using this query into a set of objects.
>> set s [::demo::Employee get_instances_from_db]
=  ::xotcl::__#H

.. The result is an OrderedComposite. Children can be accessed
.. via the 'children' method:

>> llength [$s children]
=  2

.. serialize all children
::xotcl::Object create ::xotcl::__#I -noinit \
    -set __parent ::xotcl::__#H \
    -set object_title {Employee 7848} \
    -set dept_nr 0 \
    -set salary {} \
    -set employee_id 7848 \
    -set age 25 \
    -set name Neophytos \
    -set projects {} \
    -set object_id 7848 \
    -set person_id 7848 

::xotcl::Object create ::xotcl::__#J -noinit \
    -set __parent ::xotcl::__#H \
    -set object_title {Employee 7850} \
    -set dept_nr 0 \
    -set salary 100 \
    -set employee_id 7850 \
    -set age 7 \
    -set name Nora \
    -set projects {} \
    -set object_id 7850 \
    -set person_id 7850 

.. The instance_select_query can be configured in many ways.
.. Here we use the '-count true' option to return just the number
.. of solutions:

>> ::demo::Employee instance_select_query -count true
=  SELECT count(*) 
   FROM demo_employee,demo_person,acs_objects  
   WHERE person_id = employee_id and object_id = employee_id   

>> db_string cnt [::demo::Employee instance_select_query -count true]
=  2

.. The same queries for ::demo::Person instead of ::demo::Employee.
.. Note, that we get the person data of employees as well, since
.. employees are as well persons (i.e. a specialization of person):

>> ::demo::Person instance_select_query
=  SELECT demo_person.pname AS name,demo_person.age,
     demo_person.projects,demo_person.person_id,
     acs_objects.title AS object_title,acs_objects.object_id 
   FROM demo_person,acs_objects  
   WHERE object_id = person_id   

>> set s [::demo::Person get_instances_from_db]
=  ::xotcl::__#M

>> llength [$s children]
=  3

::xotcl::Object create ::xotcl::__#N -noinit \
    -set __parent ::xotcl::__#M \
    -set object_title {Person 7847} \
    -set age 105 \
    -set name Gustaf \
    -set projects {} \
    -set object_id 7847 \
    -set person_id 7847 

::xotcl::Object create ::xotcl::__#O -noinit \
    -set __parent ::xotcl::__#M \
    -set object_title {Employee 7848} \
    -set age 25 \
    -set name Neophytos \
    -set projects {} \
    -set object_id 7848 \
    -set person_id 7848 

::xotcl::Object create ::xotcl::__#P -noinit \
    -set __parent ::xotcl::__#M \
    -set object_title {Employee 7850} \
    -set age 7 \
    -set name Nora \
    -set projects {} \
    -set object_id 7850 \
    -set person_id 7850 

TODO: explain more options for instance_select_query and get_instances_from_db

############################################################
#
# 3) Create XOTcl classes from existing ACS Object Types
#    and ACS Attributes based on the definitions in the
#    database

>> set c [::xo::db::Class get_class_from_db -object_type party]
=  ::xo::db::party

.. XOTcl class ::xo::db::party created (superclass ::xo::db::Object)
.. SQL attributes:
>> ::xo::db::party array names db_slot
=  email party_id url

>> set c [::xo::db::Class get_class_from_db -object_type person]
=  ::xo::db::person

.. XOTcl class ::xo::db::person created (superclass ::xo::db::party)
.. SQL attributes:
>> ::xo::db::person array names db_slot
=  last_name first_names person_id

>> set c [::xo::db::Class get_class_from_db -object_type user]
=  ::xo::db::user

.. XOTcl class ::xo::db::user created (superclass ::xo::db::person)
.. SQL attributes:
>> ::xo::db::user array names db_slot
=  user_id

>> set c [::xo::db::Class get_class_from_db -object_type group]
=  ::xo::db::group

.. XOTcl class ::xo::db::group created (superclass ::xo::db::party)
.. SQL attributes:
>> ::xo::db::group array names db_slot
=  group_name group_id

.. Create XOTcl object for user_id = 0

.. please log in
>> set u [::xo::db::Class get_instance_from_db -id $myuser]
=  ::0

.. ::0 created, class ::xo::db::user
.. class hierarchy for ::0 ::xo::db::user ::xo::db::person ::xo::db::party ::xo::db::Object ::xotcl::Object
.. show contents of ::0

::xo::db::user create ::0 -noinit \
    -set object_title Unregistered Visitor \
    -set party_id 0 \
    -set email {} \
    -set last_name Visitor \
    -set object_id 0 \
    -set url {} \
    -set person_id 0 \
    -set first_names Unregistered \
    -set user_id 0 

.. The object ::0 was fetched from the database using the
.. automatically created query:

SELECT users.user_id,persons.last_name,persons.first_names,
  persons.person_id,parties.email,
  parties.party_id,parties.url,
  acs_objects.title AS object_title,acs_objects.object_id
FROM users,persons,parties,acs_objects
WHERE user_id = 0 and person_id = user_id and 
  party_id = user_id and object_id = user_id

.. Now we modify the user. To be on the safe side, we
.. a) save firstly the original URL of the current user, then
.. b) we set it to a new value and save the user information
..    to the database
.. c) delete the user object in memory
.. d) load it again from the database to see the modified data
.. e) reset it to the original value and save it again to restore
..    the original state

.. Step a:
>> set url [::0 url]

.. Step b:
>> ::0 url https://openacs.org/
=  https://openacs.org/

>> ::0 save

.. Step c:
>> ::0 destroy

.. Step d:
>> set u [::xo::db::Class get_instance_from_db -id $myuser]
=  ::0

.. show contents of ::0

::xo::db::user create ::0 -noinit \
    -set object_title Unregistered Visitor \
    -set party_id 0 \
    -set email {} \
    -set last_name Visitor \
    -set object_id 0 \
    -set url https://openacs.org" \
    -set person_id 0 \
    -set first_names Unregistered \
    -set user_id 0 

.. Step e:
>> ::0 url $url

>> ::0 save

>> ::0 destroy

>> set u [::xo::db::Class get_instance_from_db -id $myuser]
=  ::0

.. show contents of ::0

::xo::db::user create ::0 -noinit \
    -set object_title Unregistered Visitor \
    -set party_id 0 \
    -set email {} \
    -set last_name Visitor \
    -set object_id 0 \
    -set url {} \
    -set person_id 0 \
    -set first_names Unregistered \
    -set user_id 0 



############################################################
#
# 4) Use the generic Content Repository interface (using 
#    just cr_items and cr_revisions)
#

.. check, if cr_item with name 'testing' exists
>> set item_id [::xo::db::CrClass lookup -name testing]
=  7841

.. yes, it exists; delete it without instantiating
>> ::xo::db::CrItem delete -item_id 7841

.. create item
>> set i [::xo::db::CrItem new  -name "testing"  -title "Title of Hello World"  -text "Hello World"  ]
=  ::xotcl::__#a

>> $i save_new
=  7852

.. show contents of item

::xo::db::CrItem create ::xotcl::__#a -noinit \
    -set creation_date {2007-09-03 23:28:26.727511+02} \
    -set creation_user 0 \
    -set object_id 7852 \
    -set description {} \
    -set text {Hello World} \
    -set nls_language en_US \
    -set mime_type text/plain \
    -set name testing \
    -set publish_status ready \
    -set title {Title of Hello World} \
    -set revision_id 7851 \
    -set item_id 7852 \
    -set last_modified {2007-09-03 23:28:26.727511+02} \
    -set parent_id -100 

.. update content

>> ::xotcl::__#a append text {... more text.. more text.. more text.}
=  Hello World... more text.. more text.. more text.

>> ::xotcl::__#a append title { - v2}
=  Title of Hello World - v2

.. show modified contents of item

::xo::db::CrItem create ::xotcl::__#a -noinit \
    -set creation_date {2007-09-03 23:28:26.727511+02} \
    -set creation_user 0 \
    -set object_id 7852 \
    -set description {} \
    -set text {Hello World... more text.. more text.. more text.} \
    -set nls_language en_US \
    -set mime_type text/plain \
    -set name testing \
    -set publish_status ready \
    -set title {Title of Hello World - v2} \
    -set revision_id 7851 \
    -set item_id 7852 \
    -set last_modified {2007-09-03 23:28:26.727511+02} \
    -set parent_id -100 

>> ::xotcl::__#a save
=  7852

.. method 'save' creates a new revision; see changed revision_id below

::xo::db::CrItem create ::xotcl::__#a -noinit \
    -set creation_date {2007-09-03 23:28:26.727511+02} \
    -set creation_user 0 \
    -set object_id 7852 \
    -set description {} \
    -set text {Hello World... more text.. more text.. more text.} \
    -set nls_language en_US \
    -set mime_type text/plain \
    -set name testing \
    -set publish_status ready \
    -set title {Title of Hello World - v2} \
    -set revision_id 7853 \
    -set item_id 7852 \
    -set last_modified {2007-09-03 23:28:26.727511+02} \
    -set parent_id -100 

>> set item_id 7852
=  7852

>> ::xotcl::__#a destroy

>> set i [::xo::db::CrClass get_instance_from_db -item_id 7852]
=  ::7852

::xo::db::CrItem create ::7852 -noinit \
    -set object_type content_revision \
    -set creation_date {2007-09-03 23:28:26.727511+02} \
    -set object_id 7853 \
    -set creation_user 0 \
    -set description {} \
    -set text {Hello World... more text.. more text.. more text.} \
    -set nls_language en_US \
    -set package_id 492 \
    -set name testing \
    -set mime_type text/plain \
    -set publish_status ready \
    -set title {Title of Hello World - v2} \
    -set item_id 7852 \
    -set revision_id 7853 \
    -set last_modified {2007-09-03 23:28:26.750059+02} \
    -set parent_id -100 

############################################################
#
# 5) Create new application classes by sub-typing the 
#    Content Repository, adding additional attributes
#

.. We create a subclass of ::xo::db::CrItem called ::demo::Page
.. which has a few more attributes. Actually, this class is very
.. similar to ::xowiki::Page. Again, we define an XOTcl class
.. ::demo::Page which creates the ACS Object Type, the ACS
.. attributes and the table, if necessary.

>> 
  # content class very similar to ::xowiki::Page
  ::xo::db::CrClass create Page \
    -superclass ::xo::db::CrItem  \
    -pretty_name "demo Page"  \
    -mime_type text/html  \
    -slots {
        if {[::xo::db::has_ltree]} {
          ::xo::db::CrAttribute create page_order \
            -sqltype ltree -validator page_order \
            -default ""
        }
        ::xo::db::CrAttribute create creator \
            -column_name creator_string
      }

=  ::demo::Page

.. The sql_attribute_names for content items contain
.. the attributes of all supertypes:

>> ::demo::Page array names db_slot
=  creator page_order page_id object_id description text object_title nls_language mime_type name title item_id revision_id

>> ::demo::Page info slots
=  ::demo::Page::slot::creator ::demo::Page::slot::page_order ::demo::Page::slot::mime_type ::demo::Page::slot::page_id

>> ::xo::slotobjects ::demo::Page
=  ::demo::Page::slot::creator ::demo::Page::slot::page_order ::demo::Page::slot::mime_type ::demo::Page::slot::page_id ::xo::db::CrItem::slot::package_id ::xo::db::CrItem::slot::nls_language ::xo::db::CrItem::slot::description ::xo::db::CrItem::slot::name ::xo::db::CrItem::slot::text ::xo::db::CrItem::slot::publish_status ::xo::db::CrItem::slot::parent_id ::xo::db::CrItem::slot::title ::xo::db::CrItem::slot::revision_id ::xo::db::CrItem::slot::item_id ::xo::db::Object::slot::object_title ::xo::db::Object::slot::object_id

.. create page
>> set i [Page new  \
     -name "page0"  \
     -title "Joke of the Month" \
     -creator "GN" \
     -text "Three cannibals meet in a NYC subway station..."  ]
=  ::xotcl::__#j

>> $i save_new
=  7855

.. show contents of page object ::xotcl::__#j (including creator and page_order,
.. when ltree is available)

::demo::Page create ::xotcl::__#j -noinit \
    -set page_order {} \
    -set creator GN \
    -set page_id {} \
    -set creation_date {2007-09-03 23:28:29.149591+02} \
    -set object_id 7855 \
    -set creation_user 0 \
    -set description {} \
    -set text {Three cannibals meet in a NYC subway station...} \
    -set nls_language en_US \
    -set mime_type text/html \
    -set name page0 \
    -set publish_status ready \
    -set title {Joke of the Month} \
    -set revision_id 7854 \
    -set item_id 7855 \
    -set last_modified {2007-09-03 23:28:29.149591+02} \
    -set parent_id -100 

>> set item_id [::xotcl::__#j item_id]
=  7855

>> ::xotcl::__#j destroy

>> ::demo::Page get_instance_from_db -item_id 7855
=  ::7855

::demo::Page create ::7855 -noinit \
    -set page_order {} \
    -set object_type ::demo::Page \
    -set page_id 7854 \
    -set creation_date {2007-09-03 23:28:29.149591+02} \
    -set object_id 7854 \
    -set creation_user 0 \
    -set description {} \
    -set text {Three cannibals meet in a NYC subway station...} \
    -set nls_language en_US \
    -set package_id 492 \
    -set name page0 \
    -set mime_type text/html \
    -set title {Joke of the Month} \
    -set publish_status ready \
    -set revision_id 7854 \
    -set item_id 7855 \
    -set last_modified {2007-09-03 23:28:29.149591+02} \
    -set parent_id -100 \
    -set creator_string GN
previous March 2024
Sun Mon Tue Wed Thu Fri Sat
25 26 27 28 29 1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31 1 2 3 4 5 6

Popular tags

17 , 5.10 , 5.10.0 , 5.9.0 , 5.9.1 , ad_form , ADP , ajax , aolserver , asynchronous , bgdelivery , bootstrap , bugtracker , CentOS , COMET , compatibility , CSP , CSRF , cvs , debian , docker , docker-compose , emacs , engineering-standards , exec , fedora , FreeBSD , guidelines , host-node-map , hstore
No registered users in community xowiki
in last 30 minutes
Contributors

OpenACS.org