Forum OpenACS Development: Code changes in MyFirstPackage

Collapse
Posted by Nils Lohse on
Hi all,

i just wondered that i had to change the code to get the MyFirstPackage (see Development Tutorial) run.

mfp::note::add should called just with a title, but requires an item_id (in note-procs.tcl)

I changed the item_id to be optional.

# modified 2006/07/26 by nfl:
#          -item_id:required to optional
#          to match tutorial documentation
ad_proc -public mfp::note::add {
    -title:required
    -item_id
} {
    This proc adds a note.
} {
    if { [info exists item_id] eq 0 } {
        set item_id [db_nextval acs_object_id_seq]
    }

... following code unchanged.

Any comments from the gurus? 😉

Nils

Collapse
Posted by Jun Yamog on
Hi Nils,

My tcl is a bit rusty, but I think you can just use

if { ![info exists item_id] } {

I don't fully understand your question. What you currently doing?

Collapse
Posted by Nils Lohse on
Hi Jun,

i had just followed the tutorial... 😉

See https://openacs.org/doc/openacs-5-2/tutorial.html

And wondered that the given code needs to be fixed!?!

If i'm right, the tutorial should be updated...
If i'm wrong, please correct me...

Greetings,
Nils

Collapse
Posted by Torben Brosten on
bug number 1640[1] is dealing with this issue.

Maybe someone who knows the "best practices" method that includes protecting against double click errors etc. could post the solution here or to the bug, so we can add it to the tutorial, and make the example available along with the other best practices that are being put together in xowiki[2]

1. https://openacs.org/bugtracker/openacs/bug?bug_number=1640
2. https://openacs.org/xowiki/pages/en/Web_Forms

Collapse
Posted by Nils Lohse on
Hi Torben,

okay, i'm not the first one encountering this topic... 😉
(Bug #1640)

Thank you for the url.

Nils

Collapse
Posted by Jim Lynch on
Heya Nils...

This will take a few messages to get everything explained...

First off... in your proc, you're grabbing the next object_id from the sequence... which is the same thing that happens when you pass "" for object_id to acs_object__new...

So you could do:

ad_proc -public mfp::note::add {
    -title:required
    -item_id
} {
    This proc adds a note.
} {
    if { ! [info exists item_id] } {
        set item_id ""
    }

    :
    :
}
and get a similar result (note also replacing "c eq 0" with "! c"; eq is a string compare, == is numeric)

More to come (about why even have the item_id come into the func if it's to be a new object) later :)

Collapse
Posted by Nils Lohse on
Heya Jim,

okay, i see, there exist better methods to deal with an empty item_id (see also Jun's Posting)...

... but the main point is, that the original tutorial source code says:

ad_proc -public mfp::note::add {
    -title:required
    -item_id:required
} {
    This proc adds a note.
} {  ...

I removed the :required-clause behind -item_id to match the tutorial description and get the code running.

That's why i'm wondering/asking... tutorial code shouldn't be needed to be fixed... 😉

Nils

Collapse
Posted by Jim Lynch on
(quote)tutorial code shouldn't be needed to be fixed...(/quote)

Yes, there is that...

BUT

you got the app working?

Collapse
Posted by Nils Lohse on
Hi Jim,

yes, i got the app working. So it's no problem for me, just irritating/confusing... 😉

But maybe other people won't be able to fix the code.

And i think, most people won't expect such "tasks" in a tutorial... 😉

Anyway, my intention just was to ask if i was right. (I belong to the people that don't expect... and so on <smile>)

Nils

Collapse
Posted by Jim Lynch on
Sometimes I think, "why not leave this bug in" so that the tutorial includes a small challenge...

Other times, I think it would be better if it were fixed.

If you read the bug report you'll see my {here's the point of passing in the item_id as received from the item_id key field of the form} comment, and you'll also see that I didn't put the type of posting right so you have to scroll to the right a lot to read it...

Anyway, the double-click thing is not unique to openacs, but not everyone gets that right. As an exercise, alter your app so that it passes the key from the form into the note__new call.

I'm dealing with Myfirstpackage example, and after I have changed the code in the note-procs.tcl:

ad_proc -public mfp::note::add {
-title:required
-item_id
} {
This proc adds a note.
@return item_id of the new note.
} {
if { ! [info exists item_id] } {
set item_id[db_nextval acs_object_id_seq]
}
}
{
db_transaction {
set item_id [db_exec_plsql note_insert {
select content_item__new(:title,-100,null,null,null,null,null,null,\
'content_item','mfp_note',:title,null,null,null,null)
}]
set revision_id [db_nextval acs_object_id_seq]

I have another error:

[21/ago/2007:20:17:25][2997.3064855472][-conn:plataforma::3] Error: Error sourcing /home/jesusdavid/web/plataforma/packages/myfirstpackage/tcl/note-procs.tcl:
invalid command name "
db_transaction {
set item_id [db_exec_plsql note_insert {
select content_item__new(:title,-100,null,null,null,null,null,null,'content_item','mfp_note',:title,null,null,null,null)
}]

set revision_id [db_nextval acs_object_id_seq]

db_dml revision_add {
insert into mfp_notesi (item_id, revision_id, title)
values (:item_id, :revision_id, :title)
}

db_exec_plsql make_live {
select content_item__set_live_revision(:revision_id)
}
}
return $item_id
"
while executing
"{
db_transaction {
set item_id [db_exec_plsql note_insert {
select content_item__new(:title,-100,null,null,null,null,null,null,'content_item..."
(file "/home/jesusdavid/web/plataforma/packages/myfirstpackage/tcl/note-procs.tcl" line 44)
invoked from within
"source $__file "

Somebody can help me?

Thanks,

Silvia

Collapse
Posted by Jim Lynch on
Why is there a "{" just before db_transaction?
Thanks Jim, I could find my last error. Now I have another:

Database operation "dml" failed (exception NSDB, "Query was not a DML or DDL command.")

SQL: insert into mfp_notesi(item_id, revision_id, title) values('3352', '3354', 'Silvia')
while executing
"ns_pg_bind dml nsdb0 { insert into mfp_notesi(item_id, revision_id, title) values(:item_id, :revision_id, :title) }"
("uplevel" body line 1)
invoked from within
"uplevel $ulevel [list ns_pg_bind $type $db $sql]"
("postgresql" arm line 2)
invoked from within
"switch $driverkey {
oracle {
return [uplevel $ulevel [list ns_ora $type $db $sql] $args]
}
..."
invoked from within
"db_exec dml $db $full_statement_name $sql"

MY CODE IS:

{
if { ! [info exists item_id] } {
set item_id[db_nextval acs_object_id_seq]
}

db_transaction {
db_exec_plsql note_insert {select content_item__new(:title,-100,:item_id,null,null,null,null,null,'content_item','mfp_note',:title,null,null,null,null)}

set revision_id [db_nextval acs_object_id_seq]

db_dml revision_add { insert into mfp_notesi(item_id, revision_id, title) values(:item_id, :revision_id, :title) }

db_exec_plsql make_live {
select content_item__set_live_revision(:revision_id)
}
}
return $item_id
}

Thanks before hand,

Silvia

Collapse
Posted by Jim Lynch on
mfp_notesi is this weird view that if you insert into it, it does all the rest of the stuff needed (make an acs_object, etc) to get the new item in there.

Unfortunately...

doing that insert makes the -result- appear to be a "select" statement because of what the view is an "alias" for.

If you enable the debugging output of the nspostgres driver in the pool definition, it should show you what symbol is being returned by the pq exec call; you should fnd it's claiming there is a rows result.

So if you change the db_dml to soemthing else, like db_exec_plsql maybe, or maybe db_0or1row or db_string, the insert (which stops looking like an insert at the point of return) will return good exit status again.

Collapse
Posted by Brian Fenton on
You can insert into a view? Is this a Postgres "feature"?
You could try inserting into the underlying base tables directly.

Brian

Collapse
Posted by Jim Lynch on
The act of inserting into this particular view fires a trigger. This is a feature of the openacs content repository: when you create a content type, it makes a view with a trigger like this.
Jim, thanks, I get to run the example.