[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