Re: [cgiapp] Re: [OT] CGI::Session is good, but we can do better (a new project is born?)

2005-06-18 Thread Ron Savage
On Fri, 17 Jun 2005 09:43:38 -0500, Mark Stosberg wrote:

Hi Mark

 Conversely, I recently spent several /hours/ because of poor naming
 internal to CGI::Session. It uses ATIME, CTIME, and ETIME. The all
 lock very similar, and even the values look consistent because they
 are expressed in seconds. However, ETIME is a relative number of
 seconds, while the others are absolute values since the Epoch. I
 tried to improve this in PureSQL with columns named
 last_access_time, creation_time and duration, which what
 ETIME really is.

Yes. That's exactly the same problem I had every time I looked into CGI::Session
when writing CGI::Session::ExpireSessions. But it's a mindset, just like when
people write books - each book is (luckily) different.
--
Cheers
Ron Savage, [EMAIL PROTECTED] on 18/06/2005
http://savage.net.au/index.html
Let the record show: Microsoft is not an Australian company



-
Web Archive:  http://www.mail-archive.com/cgiapp@lists.erlbaum.net/
  http://marc.theaimsgroup.com/?l=cgiappr=1w=2
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Re: [cgiapp] Re: [OT] CGI::Session is good, but we can do better (a new project is born?)

2005-06-18 Thread Ron Savage
On Fri, 17 Jun 2005 22:05:33 -0400, Cees Hek wrote:

Hi Cees

 I think we are just using the same tool for different purposes, and
 hence are looking for different features.  It really comes down to
 semantics I think...

I'm up your end of the scale. As I see it - for 'session' info:

o Some info is for 1 round trip. I save it and when I get a reply from the user
I combine the user's (new) data with the saved data

o Some info is for up to when the user somehow indicates they are 'done'

o Some info is left over because the user did not explicitly say 'done'. This is
what gets zapped by CGI::Session::ExpireSessions and its ilk

Each app is slightly different so each data usage pattern is slightly different.
Definitely no big deal.
--
Cheers
Ron Savage, [EMAIL PROTECTED] on 18/06/2005
http://savage.net.au/index.html
Let the record show: Microsoft is not an Australian company



-
Web Archive:  http://www.mail-archive.com/cgiapp@lists.erlbaum.net/
  http://marc.theaimsgroup.com/?l=cgiappr=1w=2
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Re: [cgiapp] Re: [OT] CGI::Session is good, but we can do better (a new project is born?)

2005-06-18 Thread Ron Savage
On Sat, 18 Jun 2005 00:15:23 -0400, Michael Graham wrote:

Hi Michael

 I'd like to be able to easily create temporary sessions for
 specific purposes.  For instance, it would be nice to create a
 session for a multi-page form, and use this to store the state
 between pages instead of using hidden fields or the user's own
 session.

Exactly. I deal with departmental staff lists, and people's names are displayed
in a specific order when staff do a search on a department's name. This order is
called Order of Merit (OOM). It's just to make Enquiries phone numbers appear
before those of live! staff, with postgrads last :-).

Now, in the editing screen, if the user submits a form of 310 staff details,
with N fields per person (sigh) I keep the OOMs in the session table, and
compare them against the incoming data. That way, if the OOM has not changed I
do not hit the database, and visa versa, only update the personnel record when
the OOM has changed.

Hmmm ... thinks ... I'd better check the code to ensure the session is updated,
not just the db (mega-sigh).

--
Cheers
Ron Savage, [EMAIL PROTECTED] on 18/06/2005
http://savage.net.au/index.html
Let the record show: Microsoft is not an Australian company



-
Web Archive:  http://www.mail-archive.com/cgiapp@lists.erlbaum.net/
  http://marc.theaimsgroup.com/?l=cgiappr=1w=2
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Re: [cgiapp] Re: [OT] CGI::Session is good, but we can do better (a new project is born?)

2005-06-18 Thread Ron Savage
On Fri, 17 Jun 2005 09:43:38 -0500, Mark Stosberg wrote:

Hi Mark

 http://savage.net.au/Ron/html/naming-database-objects.html
 which, of course, I do not expect anyone else to follow...

 At the moment, I'm eastbound on I-70 without net access, but I'll
 be curious to read that later. I also believe in the value of DB
 naming conventions, and Summersault uses one we've published on our
 corporate intranet.

I don't state it explicitly in the article, but one major reason I evolved this
design was to compensate for MySQL's lack of support for foreign keys.

I had code which would determine foreign keys based on column name alone. An
example is sub is_foreign_key() in
http://savage.net.au/Ron/html/graphing-database-schema.html

Now, even tho MySQL support them, I keep the column-naming system.
--
Cheers
Ron Savage, [EMAIL PROTECTED] on 18/06/2005
http://savage.net.au/index.html
Let the record show: Microsoft is not an Australian company



-
Web Archive:  http://www.mail-archive.com/cgiapp@lists.erlbaum.net/
  http://marc.theaimsgroup.com/?l=cgiappr=1w=2
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Re: [cgiapp] Re: [OT] CGI::Session is good, but we can do better (a new project is born?)

2005-06-18 Thread Ron Savage
On Fri, 17 Jun 2005 09:43:38 -0500, Mark Stosberg wrote:

Hi Mark

This just turned up on CPAN today:

Object::Generic::Session

--
Cheers
Ron Savage, [EMAIL PROTECTED] on 18/06/2005
http://savage.net.au/index.html
Let the record show: Microsoft is not an Australian company



-
Web Archive:  http://www.mail-archive.com/cgiapp@lists.erlbaum.net/
  http://marc.theaimsgroup.com/?l=cgiappr=1w=2
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



[cgiapp] Re: RFC: DBI::Session proposed docs (name clarification)

2005-06-18 Thread Mark Stosberg
On 2005-06-18, Mark Stosberg [EMAIL PROTECTED] wrote:

 DBI::Session - Database-driven session management

Cees kindly brought to my attention that the 'DBI::' namespace is
reserved, which I had forgotten. 'DBIx::Session' would be the preferred
alternative. 

Mark


-
Web Archive:  http://www.mail-archive.com/cgiapp@lists.erlbaum.net/
  http://marc.theaimsgroup.com/?l=cgiappr=1w=2
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Re: [cgiapp] OT: Beer in New York

2005-06-18 Thread Michael Peters
Gabor Szabo wrote:
 Last month we talked about the possibility to have a pre-YAPC meeting in
 New York when I am there.
 So this is coming now. I'll be in New York between 18-22/June.
 I'd be glad if a couple of us could get together for a beer or some
 similar substance.
 Local people, please set the place and the time on any of those dates.

I'm not local, but I'll be in NY the evening of the 21st. If that works
for everyone else, then i'm game. I know that Jesse's wife just released
child 2.0 so we'll see if he can break away for an evening.

-- 
Michael Peters
Developer
Plus Three, LP


-
Web Archive:  http://www.mail-archive.com/cgiapp@lists.erlbaum.net/
  http://marc.theaimsgroup.com/?l=cgiappr=1w=2
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Re: [cgiapp] RFC: DBI::Session proposed docs

2005-06-18 Thread Sam Tregar
On Sat, 18 Jun 2005, Mark Stosberg wrote:

 As a design goal, no database driver layer should be needed. 

How will you handle locking?  This seems to be the hardest thing to do
in a database agnostic fashion.

-sam

-
Web Archive:  http://www.mail-archive.com/cgiapp@lists.erlbaum.net/
  http://marc.theaimsgroup.com/?l=cgiappr=1w=2
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Re: [cgiapp] Re: [OT] CGI::Session is good, but we can do better (a new project is born?)

2005-06-18 Thread Michael Graham

 Now, in the editing screen, if the user submits a form of 310 staff details,
 with N fields per person (sigh)

You really aren't kidding about this stuff, are you? :)

 I keep the OOMs in the session table, and
 compare them against the incoming data. That way, if the OOM has not changed I
 do not hit the database, and visa versa, only update the personnel record when
 the OOM has changed.

Yeah that's the kind of thing I mean.  (Assuming I understand you
correctly - that you are storing application state in the user's session.)

If the user closes the form and comes back to it three days later then
the application state from three days ago is reused, right?  Bleah.

The other option is to use hidden fields, but that's pretty messy too.

I guess what I'm looking for is a session with more than one primary
key:

   my $form_session = Session-new(
   page = 'staff_list',
   form = 'details',
   user = $user_session-{'uid'},
   );

Like regular sessions, this would either return the existing session or
create a new one, based on whether or not it can find a (non-expired)
session with that page, form and user combination.

Still doesn't solve the problem of one user, one form, two browser
windows though.  Hmmm


Michael


---
Michael Graham [EMAIL PROTECTED]

YAPC::NA 2005 Toronto - http://www.yapc.org/America/ - [EMAIL PROTECTED]
---


-
Web Archive:  http://www.mail-archive.com/cgiapp@lists.erlbaum.net/
  http://marc.theaimsgroup.com/?l=cgiappr=1w=2
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



[cgiapp] Re: Class::Trigger [was Hooks, HTML::Tidy plugin]

2005-06-18 Thread Rhesa Rozendaal

Mark Stosberg wrote:

On 2005-06-17, Rhesa Rozendaal [EMAIL PROTECTED] wrote:
Has anybody ever mentioned Class::Trigger? It would be nice to have 
'before_foo' and 'after_foo' triggers, for instance, and Class::Trigger 
has already proven its usefulness in Class::DBI.



I looked it in passing. If you try it with C::A, let us know how you
like it. 


I've taken some time to see if I could rewrite the hook system with 
Class::Trigger, and it works except for all the tests in t/11callbacks.t 
(due to the different order in which callbacks are executed):


Failed Test Stat Wstat Total Fail  Failed  List of Failed
---
t/11callbacks.t3   768 53  60.00%  2-4
Failed 1/12 test scripts, 91.67% okay. 3/160 subtests failed, 98.12% okay.

Before I continue, can I ask some questions about some of the design 
decisions you guys made?


- add_callback() accepts both a coderef and a string. Class::Trigger 
only accepts coderefs. Why did you decide to accept sub names as well?


- CT doesn't have the analog of new_hook(); it just creates the hook 
point when add_trigger is called for the first time. That looks sensible 
to me at first sight. What was the reason for the explicit new_hook()?


- CT says it executes hooks in the order they were registered. I _think_ 
this may be a drawback for us in the long run, as it doesn't give us 
control over the execution order at all. On the other hand, Mark decided 
to avoid the entire issue for now.


I'd like to stress that it's not my intention to change the current 
implementation. I'm just curious to see if I can get it to work with an 
already existing framework for triggers.
I've read the posts that mentioned CT in the archives. It seems the 
execution order was the big thing back then, which is why it had never 
been seriously considered.
As Mark noted quite correctly, it would add a dependency that many users 
wouldn't need. Then again, the callback code is _in_ cgiapp now, so that 
may not be such a big objection anymore.


So far this is just a weekend excursion for me. If there's any feedback, 
I might start to take it more seriously :-)


Rhesa

Complete test results:
athene:~/.cpan/build/CGI-Application-4.01$ make test
PERL_DL_NONLAZY=1 /usr/bin/perl -MExtUtils::Command::MM -e 
test_harness(0, 'blib/lib', 'blib/arch') t/*.t
t/01cgiappok 

t/02mailform..ok 

t/03prerunok 

t/04getquery..ok 

t/05arrayrefmodes.ok 

t/06enhancement31.ok 

t/07postrun...ok 

t/09zerormok 

t/10errormode.ok 

t/11callbacks.NOK 2 


# Failed test (t/11callbacks.t at line 370)
# Structures begin differing at:
#  $got-[0] = 'init/My::App::cgiapp_init'
# $expected-[0] = 'init/CGI::Application::Plugin::Bar::bar_init1'
Actual Event History:
$VAR1 = [
  'init/My::App::cgiapp_init',
  'init/CGI::Application::Plugin::Foo::foo_init1',
  'init/CGI::Application::Plugin::Foo::foo_init2',
  'init/My::Project::my_project_init',
  'init/CGI::Application::Plugin::Bar::bar_init1',
  'bar_hook/CGI::Application::Plugin::Bar::bar_custom',
  'init/CGI::Application::Plugin::Bar::bar_init2',
  'prerun/My::App::cgiapp_prerun',
  'prerun/CGI::Application::Plugin::Foo::foo_prerun',
  'prerun/CGI::Application::Plugin::Bar::bar_prerun',
  'prerun/My::App::my_app_class_prerun',
  'prerun/My::App::my_app_obj_prerun',
  'runmode/My::App::begin',
  'postrun/My::App::cgiapp_postrun',
  'postrun/CGI::Application::Plugin::Foo::foo_postrun',
  'postrun/CGI::Application::Plugin::Bar::bar_postrun',
  'teardown/My::App::teardown',
  'teardown/CGI::Application::Plugin::Foo::foo_teardown',
  'foo_hook/CGI::Application::Plugin::Foo::foo_custom',
  'teardown/CGI::Application::Plugin::Bar::bar_teardown',
  'teardown/My::App::my_app_teardown',
  'teardown/My::App::my_app_teardown'
];
t/11callbacks.NOK 3 


# Failed test (t/11callbacks.t at line 438)
# Structures begin differing at:
#  $got-[0] = 'init/My::App::cgiapp_init'
# $expected-[0] = 'init/CGI::Application::Plugin::Bar::bar_init1'
Actual Event History:
$VAR1 = [
  'init/My::App::cgiapp_init',
  'init/CGI::Application::Plugin::Foo::foo_init1',
  'init/CGI::Application::Plugin::Foo::foo_init2',
  'init/My::Project::my_project_init',
  'init/CGI::Application::Plugin::Bar::bar_init1',
  'bar_hook/CGI::Application::Plugin::Bar::bar_custom',
  'init/CGI::Application::Plugin::Bar::bar_init2',
  'prerun/My::App::cgiapp_prerun',
  'prerun/CGI::Application::Plugin::Foo::foo_prerun',
  'prerun/CGI::Application::Plugin::Bar::bar_prerun',
  

Re: [cgiapp] Re: Class::Trigger [was Hooks, HTML::Tidy plugin]

2005-06-18 Thread Thilo Planz

Hi Rhesa,


- add_callback() accepts both a coderef and a string. Class::Trigger 
only accepts coderefs. Why did you decide to accept sub names as well?


The whole system of overloadable methods in sub classes depends on that.
So an alternate implementation had better preserve it.

Cheers,

Thilo

-
Web Archive:  http://www.mail-archive.com/cgiapp@lists.erlbaum.net/
 http://marc.theaimsgroup.com/?l=cgiappr=1w=2
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



[cgiapp] Re: Class::Trigger

2005-06-18 Thread Rhesa Rozendaal

Cees Hek wrote:

On 6/18/05, Rhesa Rozendaal [EMAIL PROTECTED] wrote:

- add_callback() accepts both a coderef and a string. Class::Trigger
only accepts coderefs. Why did you decide to accept sub names as well?


I did this because runmodes accept a string or a coderef, so it would
be consistent with the rest of CGI::Application.  Also, it makes
subclassing easier.


Yes, Thilo just pointed that out as well, and I think that's important. 
Since I already made add_callback() a wrapper around add_trigger(), I 
managed to support that after a fashion.


Here's the gist of it:

 use Class::Trigger;
 sub add_callback {
my ($pkg, $hook, $method) = @_;
$pkg-add_trigger($hook, sub{ shift()-$method(@_) } );
 }
 sub call_hook {
my ($pkg, $hook, @args) = @_;
$pkg-call_trigger($hook, @args);
 }
 sub new_hook {}

 # register default triggers
 __PACKAGE__-add_callback('init', 'cgiapp_init');
 __PACKAGE__-add_callback('prerun',   'cgiapp_prerun');
 __PACKAGE__-add_callback('postrun',  'cgiapp_postrun');
 __PACKAGE__-add_callback('teardown', 'teardown');

I also commented out the original code for the callbacks, of course 
(there's a complete diff at the end of this post).


This works, to a degree. All tests pass, except the more complex cases 
in t/11callbacks.t. In my runs the order is different, and I see some 
oddities: certain callbacks are executed more than once; not all 
expected events actually occur.
Maybe I took too much of a shortcut in my add_callback() wrapper, or 
maybe the cgiapp contains more smarts. I'm not really in the mood 
anymore to figure it out right now.




- CT doesn't have the analog of new_hook(); it just creates the hook
point when add_trigger is called for the first time. That looks sensible
to me at first sight. What was the reason for the explicit new_hook()?


To me it acts more like 'use strict'.  It catches typos and silly
mistakes that can be very hard to track down.


Ah, so it warns if an undefined hook gets called? I suppose that's good, 
yes.



Dependancies don't worry me that much, as long as we are using 60-80%
of the functionality of the module.  If we are using a tiny piece of a
huge module, then I might speak up against it.


Class::Trigger itself is roughly 95 lines of code. It in turn depends on 
Class::Data::Inheritable, of which I don't know the size.



So far this is just a weekend excursion for me. If there's any feedback,
I might start to take it more seriously :-)


Thanks for looking into it.  I don't think all of this is set in stone
yet (but the cement is drying fast).  We have a basic system of
callbacks in place that I think will work for most people.  It will
take some time to cater to every possibility though.


Thanks for the reply.

I liked the ease with which I was able to refactor it. Class::Trigger is 
definitely worth considering in general. I'm not all that certain 
anymore it would win us much for cgiapp though. The current code does 
the exact same thing, and we're (well, Mark is ;) in full control.


I had fun poking around in all this. I'll attach this patch for whoever 
is interested in taking it further.


Have a great weekend!

Rhesa



--- Application.pm.orig 2005-06-19 04:20:21.0 +0200
+++ Application.pm  2005-06-19 04:53:34.0 +0200
@@ -4,8 +4,11 @@
 use Carp;
 use strict;
 use Class::ISA;
+use Class::Trigger;

-$CGI::Application::VERSION = '4.01';
+$CGI::Application::VERSION = '4.01_01';
+
+=for old code

 my %INSTALLED_CALLBACKS = (
 #  hook name  package sub
@@ -16,6 +19,23 @@
load_tmpl = { },
 );

+=cut
+
+sub add_callback {
+   my ($pkg, $hook, $method) = @_;
+   $pkg-add_trigger($hook, sub{ shift()-$method(@_) } );
+}
+sub call_hook {
+   my ($pkg, $hook, @args) = @_;
+   $pkg-call_trigger($hook, @args);
+}
+sub new_hook {}
+
+__PACKAGE__-add_callback('init', 'cgiapp_init');
+__PACKAGE__-add_callback('prerun',   'cgiapp_prerun');
+__PACKAGE__-add_callback('postrun',  'cgiapp_postrun');
+__PACKAGE__-add_callback('teardown', 'teardown');
+
 ###
   INSTANCE SCRIPT METHODS  
 ###
@@ -1953,6 +1973,8 @@

 =cut

+=for old code
+
 sub add_callback {
my ($self_or_class, $hook, $callback) = @_;

@@ -1974,6 +1996,8 @@

 }

+=cut
+
 =item new_hook(HOOK)

 $self-new_hook('pretemplate');
@@ -1989,12 +2013,16 @@

 =cut

+=for old code
+
 sub new_hook {
my ($class, $hook) = @_;
$INSTALLED_CALLBACKS{$hook} ||= {};
return 1;
 }

+=cut
+
 =item call_hook(HOOK)

 $self-call_hook('pretemplate', @args);
@@ -2021,6 +2049,8 @@

 =cut

+=for old code
+
 sub call_hook {
my $self  = shift;
my $app_class = ref $self || $self;
@@ -2060,6 +2090,8 @@
}
 }

+=cut
+
 =pod

 BCallback Ordering


-
Web Archive: