Re: [RDBO] Read-only objects

2007-04-04 Thread Jonathan Vanasco
call me lazy--

I just use a bad db handle for all things rose, then have a custom  
method that pulls a read-only or read/write handle from a db factory  
as needed.  ie, they'll always fail on save, insert, update because  
they don't have the db permissions



-
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
___
Rose-db-object mailing list
Rose-db-object@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/rose-db-object


Re: [RDBO] Read-only objects

2007-04-04 Thread John Siracusa
On 4/4/07 12:37 PM, Adrian Howard wrote:
> Since there are at least three folk who have wanted this sort of
> functionality - would it be worth adding something like
> is_initialising() to Rose::DB::Object::Util? Just to prevent
> gratuitous wheel reinvention :-)

No, since that'd require extra overhead for all RDBO-derived objects.
Better to make Rose::DB::Object::ReadOnly or something similar which would
override init() as shown and add an exception on_set for every column when
not init()ializing.  Anyone should feel free to code, document, and write
tests for such a thing and then submit it to me :)

-John



-
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
___
Rose-db-object mailing list
Rose-db-object@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/rose-db-object


Re: [RDBO] Read-only objects

2007-04-04 Thread Adrian Howard

On 4 Apr 2007, at 17:21, John Siracusa wrote:
[snip]
> The only way to distinguish the two is by calling context.  That  
> said, there
> are (slightly) better ways to detect the context than using caller().
> Here's what I suggest:
>
> # Override init in you common base class
> # (See the Rose::Object docs for details)
> sub init
> {
>   my($self) = shift;
>   local $self->{'__allow_set'} = 1; # or whatever attr name you  
> pick
>   $self->SUPER::init(@_);
> }
[snip]
> Granted, this is still a bit of a hack, but at least it only relies on
> public APIs, rather than internal implementation details.
[snip]

I've done something similar myself.

Since there are at least three folk who have wanted this sort of  
functionality - would it be worth adding something like  
is_initialising() to Rose::DB::Object::Util? Just to prevent  
gratuitous wheel reinvention :-)

Adrian

-
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
___
Rose-db-object mailing list
Rose-db-object@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/rose-db-object


Re: [RDBO] Read-only objects

2007-04-04 Thread John Siracusa
On 4/4/07 12:05 PM, Ovid wrote:
> Note the 'return' condition.  I found that if I didn't have that in,
> the following would throw an exception:
> 
>   my $os = Donhost::OS->new( os => 'ubuntu' );
> 
> The hack guarantees that only things like the following throwing
> exceptions:
> 
>   $os->os('windows');
>   $os->description('sucks');
> 
> The hack relies on the order of call stack frames being different when
> I'm constructing an object or just setting an accessor directly.  How
> can I do this without relying on the internals like this?

The problem is that this:

$o = Foo->new(a => 123)

is really this:

$o = Foo->new;
$o->a(123);

The only way to distinguish the two is by calling context.  That said, there
are (slightly) better ways to detect the context than using caller().
Here's what I suggest:

# Override init in you common base class
# (See the Rose::Object docs for details)
sub init
{
  my($self) = shift;
  local $self->{'__allow_set'} = 1; # or whatever attr name you pick
  $self->SUPER::init(@_);
}

Then, in your trigger, replace this:

my ($called_from) = caller(1);
return if $called_from eq 'Rose::Object';

with this:

return if shift->{'__allow_set'};

Granted, this is still a bit of a hack, but at least it only relies on
public APIs, rather than internal implementation details.

-John






-
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
___
Rose-db-object mailing list
Rose-db-object@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/rose-db-object


Re: [RDBO] Read-only objects

2007-04-04 Thread Randal L. Schwartz
> "Ovid" == Ovid  <[EMAIL PROTECTED]> writes:

Ovid> The hack relies on the order of call stack frames being different when
Ovid> I'm constructing an object or just setting an accessor directly.  How
Ovid> can I do this without relying on the internals like this?

It seems like everyone using RDBO reinvents the same things.  Hooray
for this mailing list!

Here's what I did for my readonly class, based on discussions with jcs
six months ago:

sub insert {
  die "cannot insert" unless our $READWRITE;
  goto &{$_[0]->can("SUPER::insert")};
}

sub update {
  die "cannot update" unless our $READWRITE;
  goto &{$_[0]->can("SUPER::update")};
}

sub delete {
  die "cannot delete" unless our $READWRITE;
  goto &{$_[0]->can("SUPER::delete")};
}

I use "local our $READWRITE = 1" during some test harnesses when I set
up a fake version of the database.

Apparently, everything else is built on these routines, so unless you call
something even *lower* in your own code, this is enough to trap everything
that RDBO is doing "out of the box".

-- 
Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
 http://www.stonehenge.com/merlyn/>
Perl/Unix/security consulting, Technical writing, Comedy, etc. etc.
See PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training!

-
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
___
Rose-db-object mailing list
Rose-db-object@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/rose-db-object


Re: [RDBO] Read-only objects

2007-04-04 Thread Ovid
--- Ovid <[EMAIL PROTECTED]> wrote:

> My 'read-only' objects now have their very own metadata class. 

As a side note, it might be nice if a 'readonly' metadata class were
natively available in Rose::DB::Object, with an optional way of
allowing it to be read/write.  I know I can create said objects with a
Rose::DB subclass with only SELECT permissions, but that means the
errors won't get thrown until I try to write to the database.  Having
them thrown as soon as I try to set an attribute would make debugging
much easier.

Cheers,
Ovid

--

Buy the book -- http://www.oreilly.com/catalog/perlhks/
Perl and CGI -- http://users.easystreet.com/ovid/cgi_course/

-
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
___
Rose-db-object mailing list
Rose-db-object@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/rose-db-object


[RDBO] Read-only objects

2007-04-04 Thread Ovid
My 'read-only' objects now have their very own metadata class.  Trying
to update from the 'save', 'insert', 'update', etc. now fails.  I also
have the accessors throwing Exception::Class objects if someone tries
to set an attribute value.  However, it's a nasty hack because the
other code examples I saw here were failing:

  sub add_columns {
my ( $self, @columns ) = @_;
$self->SUPER::add_columns(@columns);
my $class = $self->class;
foreach my $column ( $self->columns ) {
  $column->add_trigger(
event => 'on_set',
code  => sub {
  my ($called_from) = caller(1);
  my $attribute = $class->_attribute_name($column);
  return if $called_from eq 'Rose::Object';
  throw_read_only "Attribute '$attribute' is read-only";
},
  );
}
  }

(I don't rely on the return value of
$self->SUPER::add_columns(@columns) because we're only using the CPAN
version)

Note the 'return' condition.  I found that if I didn't have that in,
the following would throw an exception:

  my $os = Donhost::OS->new( os => 'ubuntu' );

The hack guarantees that only things like the following throwing
exceptions:

  $os->os('windows');
  $os->description('sucks');

The hack relies on the order of call stack frames being different when
I'm constructing an object or just setting an accessor directly.  How
can I do this without relying on the internals like this?

Cheers,
Ovid

--

Buy the book -- http://www.oreilly.com/catalog/perlhks/
Perl and CGI -- http://users.easystreet.com/ovid/cgi_course/

-
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
___
Rose-db-object mailing list
Rose-db-object@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/rose-db-object