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

Mike Schroeder mike at nimbusrecording.com
Wed Sep 10 21:00:51 BST 2014


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>
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 listdancer-users at dancer.pmhttp://lists.preshweb.co.uk/mailman/listinfo/dancer-users
>
>
> --
> Richard Jones
>
>
> _______________________________________________
> dancer-users mailing list
> dancer-users at dancer.pm
> http://lists.preshweb.co.uk/mailman/listinfo/dancer-users
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.preshweb.co.uk/pipermail/dancer-users/attachments/20140910/5e897bf3/attachment-0001.html>


More information about the dancer-users mailing list