Forum OpenACS Development: Re: Res: Major revision of the XOTcl interface to the Content Repository and to ACS objects and ACS Object Types in general

xotcl-core has now stronger dependencies on correct (and fairly complete) setting of define_function_args(), which are used to manage the acs_function_args table in OpenACS. I have completed and fixed some define_function_args() ages ago on my instances and forgot to mention this.

Run the following script against your database to get rid the error above.

-- acs-kernel: acs-metadata-create.sql
select define_function_args('acs_object_type__create_type','object_type,pretty_name,pretty_plural,supertype,table_name;null,id_column;null,package_name;null,abstract_p;f,type_extension_table;null,name_method;null');
select define_function_args('acs_object_type__drop_type','object_type,cascade_p;f');
select define_function_args('acs_attribute__create_attribute','object_type,attribute_name,datatype,pretty_name,pretty_plural;null,table_name;null,column_name;null,default_value;null,min_n_values;1,max_n_values;1,sort_order;null,storage;type_specific,static_p;f');
select define_function_args('acs_attribute__add_description','object_type,attribute_name,description_key,description');
select define_function_args('acs_attribute__drop_description','object_type,attribute_name,description_key');
-- acs-kernel: acs-objects-create.sql
select define_function_args('acs_object__new','object_id;null,object_type;acs_object,creation_date;now(),creation_user;null,creation_ip;null,context_id;null,security_inherit_p;t,title;null,package_id;null');
select define_function_args('acs_object__delete','object_id');
-- acs-content-respository: content-type.sql ... incorrectly defined twice, fix redefinition
select define_function_args('content_type__drop_type','content_type,drop_children_p;f,drop_table_p;f,drop_objects_p;f');

These function definitions should be fixed in the acs kernel packages in CVS head as well (if nobody objects). Otherwise i would need to come up with some redundant definition in xotcl-core.

I did some more checks on fresh installs and fixed a few more things in xotcl-core and xowiki. There is as well a new version of the xotcl-request-monitor (for the version in head and oacs-5-3) and a version of the s5 package (depending on the changes in cvs head) in CVS.

I think you are safe to fix them and please provide an upgrade as well. Do you know if this problem exists in Oracle as well?
define_function_args does not exist in oracle at all, since it is implemented to mimic the oracle meta data for stored procedures. It is a postgres only problem.

I am pretty sure, some more interface descriptions are still missing or incorrect. My suggestion is to fix the above set of definitions soon in cvs head and do a second round, checking attribute names and defaults of the existing definitions against the actual stored procedures, and then compare the interface definitions with Oracle and complete where necessary.

Any idea why you cannot redefine the function_args in postgresql dependent on how many arguments the function has? We do have two content_type__drop_type functions, one with three, one with four arguments, so why can't we define the function args for both?
Sorry, the last attempt was fired before even getting started. I'd say the simple reason is the data model and constraints currently in place, e.g.:

"acs_function_args_un" UNIQUE, btree ("function", arg_name)

this does not leave anymore options.

from the perspective of xotcl-core's db layer, we would be constraint due to XOTcl currently not providing for overloading/ multi-methods, i.e. defining equally named methods on objects which are only distinct with respect to their signature (types of their arguments) and are resolved according to some specific order of precedence by the dispatcher.

So the recommended "solution" would be to only define the function_args for the largest function, as we usually (always?) only add more parameters and not have two equally named functions where one had other attributes than the other?

Oracle's plsql interface is very nice and friendly when you want to create an object layer like these. It handles multiple functions of the same name, different defaults for the arguments, and the argument order is not important. That means that usually the developer doesn't have to go back and look at the signature, Oracle will decide which proc to use. How does it do this? The function calls include the names of the attributes along with the value. In postgres it is like a Tcl call. So the only thing you need to mimic the behavior for postgres is the name of the arguments, their position in each function (the function signature), and any defaults for optional attributes, plus a way of choosing which function to call given the information.

By a strange fluke, code exists in OpenACS which does exactly this. A tiny subset of query-writer is in the cronjob package, just a few procedures, with examples for setup and use. It doesn't use the database. I wrote this code to specifically aid porting from Oracle to Postgres. Here is an example of the original oracle, and the postgres:


begin
  cronjob.set_attrs(
    cronjob_id => :cronjob_id,
    description => :description,
    approved_p => :approved_p,
    disabled_p => :disabled_p,
    minute => :minute,
    hr => :hr,
    mon => :mon,
    day => :day,
    dayofweek => :dayofweek,
    run_sql => :run_sql,
    run_tcl => :run_tcl,
    email => :email);
end;
select [qd_write_query_select cronjob__set_attrs {
  cronjob_id => :cronjob_id
  description => :description
  approved_p => :approved_p
  disabled_p => :disabled_p
  minute => :minute
  hr => :hr
  mon => :mon
  day => :day
  dayofweek => :dayofweek
  run_sql => :run_sql
  run_tcl => :run_tcl
  email => :email } ]

The current version of the code in cronjob is here:

http://rmadilo.com/files/cronjob/cronjob/tcl/

Usage is in the www/admin directory. Mostly current code is also in CVS.

It is important to point out that you can submit a subset of the arguments as long as you provide all the params which don't have defaults, for instance, when creating a new object, the object_id has a default of null, meaning that the function will create a new acs_object first, so you don't have to look at the function signatures before writing a query. This is exactly similar to Oracle. Also, each function can have different parameter defaults, different from the same attribute in other functions of the same name.

As Stefan says, this is restriction is not xotcl related (same e.g. in package_exec_plsql). A call like define_function_args(FUNCNAME, ...) tries fist to delete all entries for FUNCNAME before it defines the args new.

since define_function_args() is an oacs-function, it would be possible to extend it, but note that one has to care about oracle as well

So the recommended "solution" would be to only define the function_args for the largest function ...

yes

fixed the function args above in cvs head, including upgrade scripts.