Home
The Toolkit for Online Communities
15900 Community Members, 1 member online, 2459 visitors today
Log In Register

Forum OpenACS Development: porting a db_dml transaction

OpenACS Home : Forums : OpenACS Development : porting a db_dml transaction

Icon of Envelope Request notifications

+
Posted by Ola Hansson on
Which is the prefered way to port this non-SQL92 compliant "db_dml" within a transaction? (The QD didn't manage to extract the sql from this one).
...
	set sql "
update mp3_mp3s
set    deleted_p = 'f'
"

	foreach i_key [array names info_pairs] {
	    append sql ",
       $i_key = $info_pairs($i_key)"
	}
	append sql "
where  mp3_id = :mp3_id
"

	set sql2 "
update acs_objects
set    creation_user = :creation_user,
       creation_ip = :creation_ip,
       creation_date = sysdate,
       context_id = :package_id
where object_id = :mp3_id
"
...
...

db_transaction {
    db_dml undelete_mp3 $sql
    db_dml fix_creation $sql2
}
...
Thanks,
+
Posted by Don Baccus on
The second one is easy - get rid of the set sql2 statement and move the SQL query into your generic .xql file (it's not db-specific so it only needs to appear in the generic queryfile). The first (undelete_mp3) isn't much more difficult. The static part, i.e. the update prefix, can go into your queryfile. Then build the dynamic part into a Tcl variable as is being done (you might want to choose a name like "extra_vars" instead of "sql" since it's s snippet that will be built, not the entire query). Reference the Tcl variable directly in the queryfile. The query, in other words, will look something like:
update mp3_mp3s
set deleted = 'f'
$extra_vars
where mp3_id = :mp3_id
The Query Dispatcher will substitute the Tcl variable before the driver is called with the query.
+
Posted by Ola Hansson on
So, in the sql2 case above, are you saying that Oracle can handle "current_timestamp" in place of "sysdate"? (I was on my way to split *that* statement in a generic xql file and an -oracle.xql file).

Okay. Here's a piece I got stuck on although it's similar. I know how to port the psql block, but how do I treat the "extra_vars" when thy're both dynamic and db specific? db_map doesn't seem appropriate...
...
	set sql "
begin
   :1 := mp3.new(
      file_path => :client_filename,"

	foreach i_key [array names info_pairs] {
	    append sql "
      $i_key => $info_pairs($i_key),"
	}
	append sql "
      creation_user => :creation_user,
      creation_ip => :creation_ip,
      creation_date => sysdate,
      context_id => :package_id
);
end;
"
...
...
db_exec_plsql add_mp3 $sql
...
+
Posted by Dan Wickstrom on
Create a list with the key values in the correct order to match the postgresql function call - oracle won't care about ordering since you're using named variables here.
        # foo, bar, and baz match key names in info_pairs
        set ordered_keys [list foo bar baz]
        foreach i_key $ordered_keys {
                  append sql "$i_key => $info_pairs($i_key),"
                  set $i_key $info_pairs($i_key)
        }
Then in your postgresql .xql file reference the variables in the correct order for the mp3__new function.
+
Posted by Don Baccus on
Sorry, I missed the "creation_date" in the SQL2 portion, so that call needs to be put into both oracle and postgresql .xql files, sorry.