[dancer-users] Looking for a developer...

Richard Jones ra.jones at dpw.clara.co.uk
Thu Sep 11 10:52:05 BST 2014


Thanks for the examples Mike. I see you are calling and manipulating 
your RBDO classes directly in your routes. That answers my integration 
question. I tend to keep all that stuff in separate model classes so 
that I could change ORM to say DBIX::Class without any change to the D2 
classes. But it does increase complexity. Just a thought regarding the 
expansion helpers - you don't utilise the as_tree() function anywhere? I 
realise your helpers do more than just simple object-to-hash conversion.

my $rv = dbo2h($student);
my $rv = $student->as_tree;
my $rv = $student->as_tree(deflate => 0); # to keep eg DateTime objects

On 10/09/2014 21:00, Mike Schroeder wrote:
> Hi Richard - not sure mine is the most elegant approach vis a vi 
> plugins - but it is working, and it is fast :)  For production I'm 
> running multiple instances of Dancer with shared memcached for session 
> management, all behind balance.  This is all on a 12-core OS X 
> Mavericks box and barely makes a blip on utilization.
>
> 1) I generated all the Rose::DB::Object classes from the MySQL schema 
> for the RDBO classes and Manager classes.
>
> 2) I wrote a few helper functions to convert DBO objects in hash or 
> array of hash suitable for Dancer templating (I'll copy those in 
> below).  I still use HTML::Template over TT just so that I can have 
> non-coder HTML designers work with the templates, so these data 
> structures work for that template engine.  The result is a route that 
> looks like this:
>
> #----------------------------------------------------------------------
> get '/modal/points/:student_id' => sub {
> #----------------------------------------------------------------------
>    my $student = NDB::Student->new( id => params->{student_id} )->load;
>    my $rv = dbo2h($student);
>    template "staff/modal/points", $rv, {layout => "simple"};
> };
>
> Here are a few other sample routes:
>
> #----------------------------------------------------------------------
> post '/studio' => sub {
> #----------------------------------------------------------------------
>    my @fields = ( qw( studio_name campus_id location session_rate
> calendar_id ) );
>  dbo_add_update("NDB::Studio", { params }, \@fields );
>    redirect "/admin/campus";
> };
>
> #----------------------------------------------------------------------
> post '/studio/delete' => sub {
> #----------------------------------------------------------------------
>    my $p = NDB::Studio->new( id => params->{id} );
>    if ( params->{id} == params->{confirm_id} ) {
>       $p->delete;
>    }
>    redirect "/admin/campus";
> };
>
> I also have some other helpers that follow RDBO relationships and 
> inflate the data structures for templating:
>
> #----------------------------------------------------------------------
> get '/campus' => sub {
> #----------------------------------------------------------------------
>    my $campuses = NDB::Campus::Manager->get_campus();
>    my $rv = dbom2aoh( $campuses, { studios   => 'studio_list', staff 
> => 'staff_list', } );
>    template "admin/campus", { campus_list => $rv, add_navbar() }, { 
> layout => 'staff'};
> };
>
>
> 3) The helper functions help glue Dancer and RDBO together:
>
>
> =head2 dbo2h()
>
> dbo2h - convert a DBO object into a hash of key/value pairs.
>
>    my $hashref = dbo2h( $dboobject, $date_format_string, $expandhash, 
> $prepend );
>
> =cut
>
> sub dbo2h {
>    my $row = shift;
>    my $date_format = shift || '%Y-%m-%d %T';
>    my $expand = shift;
>    my $prepend = shift;
>    my $parent_prepend = shift;
>    my %hash = $row->column_value_pairs;
>    foreach my $key ( keys %$expand ) {
>       my $reln = $expand->{$key};
>       if ( $prepend ) {
>          $hash{$reln . '_' . $key} = ( $row->$reln ? $row->$reln->$key 
> : '' );
>       } else {
>          $hash{$key} =  ( $row->$reln ? $row->$reln->$key : '');
>       }
>    }
>    foreach my $key ( keys %hash ) {
>       if ( ref $hash{$key} eq 'DateTime' ) {
>          $hash{$key} = $hash{$key}->strftime($date_format);
>       }
>       elsif ( ref $hash{$key} eq 'Time::Clock' ) {
>          $hash{$key} = $hash{$key}->as_string;
>       }
>       $hash{$key} =~ s/\s+$//g;
>       if ( $parent_prepend ) {
>  $hash{$parent_prepend.'_'.$key} = delete $hash{$key};
>       }
>    }
>    return \%hash;
> }
>
> =head2 dbo2aoh()
>
> dbo2aoh - convert a DBO set of objects into an array of hash of 
> key/value pairs.
>
>    my $arrayref = dbo2aoh( $dboarray, $date_format_string, 
> $expandhash, $prepend );
>
> =cut
>
> sub dbo2aoh {
>    my $rows = shift;
>    my $date_format = shift;
>    my $expandhash = shift;
>    my $prepend = shift;
>    my $parent_prepend = shift;
>    my @results;
>    foreach my $row ( @$rows ) {
>       push(@results, dbo2h( $row, $date_format, $expandhash, $prepend, 
> $parent_prepend ) );
>    }
>    return \@results;
> }
>
>
> =head2 dbo_add_update()
>
> dbo_add_update - convert Dancer params into DBO add/update
>
>    my @fields = ( qw( field1 field2 field3 ) );
>    @errors = dbo_update( 'NDB::Lecture', { params }, \@fields, );
>
> =cut
>
> sub dbo_add_update {
>    my ( $class, $p, $fields ) = @_;
>    my ( $obj, @errors );
>
>    if ( $p->{id} ) {
>       $obj = $class->new( id => $p->{id} );
>       push(@errors, "No such record") unless $obj->load_speculative;
>
>       unless ( @errors ) {
>          foreach my $field ( @$fields ) {
> $obj->$field( $p->{$field} ) if exists $p->{$field};
>          }
>  $obj->save;
>       }
>    } else {
>       my %columns;
>       foreach my $field ( @$fields ) {
> $columns{$field} = $p->{$field} if exists $p->{$field};
>       }
>       $obj = $class->new( %columns );
>       $obj->save;
>    }
>    return $obj;
> }
>
> =head2 dbom2aoh()
>
> dbom2row - convert dbo to AOH and add DBOM relationships as child AOH
>
>    $rv = dbo_update( $dbo, { relationship => 'hash_key' }, 
> $date_format_string, $expandhash, $prepend );
>
> =cut
>
> sub dbom2aoh {
>    my ( $parent, $map, $dateformat, $expand, $prepend ) = @_;
>    my @rv;
>    foreach my $dbo ( @$parent ) {
>       my $row = dbo2h( $dbo, $dateformat, $expand, $prepend );
>       foreach my $reln ( keys %$map ) {
>          my $children = $dbo->$reln;
>          $row->{ $map->{$reln} } = dbo2aoh( $children, $dateformat );
>       }
>       push @rv, $row;
>    }
>    return \@rv;
> }
>
> Like I said in my initial post - I'm sure there are refactor 
> opportunities in my code - so please be kind :)  I tried to go for 
> readability over conciseness so that I could hand it off at some point.
>
> Hope that helps.
>
> Best,
>
> Mike.
>
>
>
> On Wed, Sep 10, 2014 at 12:19 PM, Richard Jones 
> <ra.jones at dpw.clara.co.uk <mailto:ra.jones at dpw.clara.co.uk>> wrote:
>
>     Hello Mike,
>
>     I was very interested to read about your experience. I'm not
>     touting for the job as I have a full-time job already. But just to
>     say I'm a recent convert to Dancer2 from developing long-term with
>     CGI::Application/RBDO/MySQL. I'm most interested in how you
>     integrated Rose with Dancer. I haven't tried it yet as all my
>     recent apps are small enough to use DBIx::Simple, but I'm planning
>     a bigger one that will need an ORM. Do you use the MVC
>     architecture? Do you use an adapter class for Rose or just rely on
>     the Dancer DB plugin? Is your project open source or are you not
>     able to expose the code base publicly?
>
>     Good luck recruiting.
>
>
>     On 10/09/2014 19:39, Mike Schroeder wrote:
>>     Hi all - I've been using Dancer for years and have watched this
>>     list for years - thank you to everyone for a great framework.
>>
>>     In my new role at a new company (an audio engineering and
>>     production school), I searched for an off the shelf system to do
>>     what I wanted, and finally gave up and wrote my own.  Dancer,
>>     Rose::DB::Object, Bootstrap and MySQL - amazing what you can do
>>     in 3-4 months of spare time :)
>>
>>     The project is up and in production, running well, and now we are
>>     wanting to add more features, etc.  I am too busy doing my real
>>     job (CEO) to have the time to do the development work on the system.
>>
>>     I'm looking for someone who can can SSH into our servers from
>>     anywhere, work within my existing architecture to extend and add
>>     features, refactor some of my prototype code (it's not horrible,
>>     but I know it could be better), and help move the project forward.
>>
>>     The ideal candidate would have experience with Dancer,
>>     Rose::DB::Object, Bootstrap and MySQL.  There is also a POE-based
>>     daemon using Rose::DB::Object running alongside for long-running
>>     asynchronous job handling, so POE experience would be helpful as
>>     well.
>>
>>     This is not a full-time job - more project based work to add new
>>     features, etc.  I expect to keep building this out over the next
>>     year, so I'm looking for a good long term partner to work with.
>>     I'm ok with different timezones, as long as we can find some
>>     common time for Skype etc. (I'm in Vancouver, so Pacific Timezone).
>>
>>     If you are interested, you can send an email to mike at
>>     nimbusrecording dot com.  Let me know your experience and
>>     expectations for payment.
>>
>>     Thanks all - I really appreciate the Dancer community and what it
>>     allows us all to create.
>>
>>     Best,
>>
>>     Mike.
>>
>>
>>
>>     _______________________________________________
>>     dancer-users mailing list
>>     dancer-users at dancer.pm  <mailto:dancer-users at dancer.pm>
>>     http://lists.preshweb.co.uk/mailman/listinfo/dancer-users
>
>     -- 
>     Richard Jones
>
>
>     _______________________________________________
>     dancer-users mailing list
>     dancer-users at dancer.pm <mailto:dancer-users at dancer.pm>
>     http://lists.preshweb.co.uk/mailman/listinfo/dancer-users
>
>
>
>
> _______________________________________________
> dancer-users mailing list
> dancer-users at dancer.pm
> http://lists.preshweb.co.uk/mailman/listinfo/dancer-users

-- 
Richard Jones

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.preshweb.co.uk/pipermail/dancer-users/attachments/20140911/485cbd9a/attachment-0001.html>


More information about the dancer-users mailing list