From da6a187ab3fc3cbb97e094559dc964a9809f347b Mon Sep 17 00:00:00 2001 From: Moritz Bunkus Date: Fri, 17 Jul 2015 18:16:14 +0200 Subject: [PATCH] SL::DB::Object: clone_and_reset unter Umgehung von itime, mtime --- SL/DB/CsvImportProfile.pm | 1 - SL/DB/DeliveryOrder.pm | 2 +- SL/DB/Invoice.pm | 2 +- SL/DB/Object.pm | 44 ++++++++++++++++++++++++++++++++++++++- SL/DB/PriceRule.pm | 1 - SL/DB/PriceRuleItem.pm | 1 - SL/DB/RequirementSpec.pm | 8 +++---- 7 files changed, 49 insertions(+), 10 deletions(-) diff --git a/SL/DB/CsvImportProfile.pm b/SL/DB/CsvImportProfile.pm index 8797a7a49..c03e9f3da 100644 --- a/SL/DB/CsvImportProfile.pm +++ b/SL/DB/CsvImportProfile.pm @@ -5,7 +5,6 @@ use strict; use List::Util qw(first); require SL::DB::MetaSetup::CsvImportProfile; -use Rose::DB::Object::Helpers qw(clone_and_reset); __PACKAGE__->meta->add_relationship( settings => { diff --git a/SL/DB/DeliveryOrder.pm b/SL/DB/DeliveryOrder.pm index b7b7a82f6..66c8982ad 100644 --- a/SL/DB/DeliveryOrder.pm +++ b/SL/DB/DeliveryOrder.pm @@ -101,7 +101,7 @@ sub date { sub _clone_orderitem_cvar { my ($cvar) = @_; - my $cloned = Rose::DB::Object::Helpers::clone_and_reset($_); + my $cloned = $_->clone_and_reset; $cloned->sub_module('delivery_order_items'); return $cloned; diff --git a/SL/DB/Invoice.pm b/SL/DB/Invoice.pm index e4c24263e..84349e191 100644 --- a/SL/DB/Invoice.pm +++ b/SL/DB/Invoice.pm @@ -131,7 +131,7 @@ sub closed { sub _clone_orderitem_delivery_order_item_cvar { my ($cvar) = @_; - my $cloned = Rose::DB::Object::Helpers::clone_and_reset($_); + my $cloned = $_->clone_and_reset; $cloned->sub_module('invoice'); return $cloned; diff --git a/SL/DB/Object.pm b/SL/DB/Object.pm index 81ef97890..4ecaab2ed 100755 --- a/SL/DB/Object.pm +++ b/SL/DB/Object.pm @@ -5,7 +5,8 @@ use strict; use Carp; use English qw(-no_match_vars); use Rose::DB::Object; -use List::MoreUtils qw(any); +use Rose::DB::Object::Constants qw(); +use List::MoreUtils qw(any pairwise); use SL::DB; use SL::DB::Helper::Attr; @@ -218,6 +219,37 @@ sub invalidate_cached { return $class_or_self; } +my %_skip_fields_when_cloning = map { ($_ => 1) } qw(itime mtime); + +sub clone_and_reset { + my($self) = shift; + my $class = ref $self; + my $cloning = Rose::DB::Object::Constants::STATE_CLONING(); + local $self->{$cloning} = 1; + + my $meta = $class->meta; + my @accessors = $meta->column_accessor_method_names; + my @mutators = $meta->column_mutator_method_names; + my @column_names = + grep { $_->[0] && $_->[1] && !$_skip_fields_when_cloning{ $_->[0] } } + pairwise { [ $a, $b] } @accessors, @mutators; + + my $clone = $class->new(map { my $method = $_->[0]; ($_->[1] => $self->$method) } @column_names); + + # Blank all primary and unique key columns + my @keys = ( + $meta->primary_key_column_mutator_names, + map { my $uk = $_; map { $meta->column_mutator_method_name($_) } ($uk->columns) } ($meta->unique_keys) + ); + + $clone->$_(undef) for @keys; + + # Also copy db object, if any + $clone->db($self->{db}) if $self->{db}; + + return $clone; +} + 1; __END__ @@ -323,6 +355,16 @@ object's ID is used. Returns the object/class it was called on. +=item C + +This works similar to L: it +returns a cloned instance of C<$self>. All primary and unique key +fields have been reset. + +The difference between Rose's and this function is that this function +will also skip setting the following fields if such columns exist for +C<$self>: C, C. + =back =head1 AUTHOR diff --git a/SL/DB/PriceRule.pm b/SL/DB/PriceRule.pm index 70b5ab4da..1c43d4a96 100644 --- a/SL/DB/PriceRule.pm +++ b/SL/DB/PriceRule.pm @@ -7,7 +7,6 @@ use strict; use SL::DB::MetaSetup::PriceRule; use SL::DB::Manager::PriceRule; -use Rose::DB::Object::Helpers qw(clone_and_reset); use SL::Locale::String qw(t8); __PACKAGE__->meta->add_relationship( diff --git a/SL/DB/PriceRuleItem.pm b/SL/DB/PriceRuleItem.pm index 8aa71dab3..77d0fe571 100644 --- a/SL/DB/PriceRuleItem.pm +++ b/SL/DB/PriceRuleItem.pm @@ -7,7 +7,6 @@ use strict; use SL::DB::MetaSetup::PriceRuleItem; use SL::DB::Manager::PriceRuleItem; -use Rose::DB::Object::Helpers qw(clone_and_reset); use SL::Locale::String qw(t8); __PACKAGE__->meta->initialize; diff --git a/SL/DB/RequirementSpec.pm b/SL/DB/RequirementSpec.pm index 1cc17712f..c35540c74 100644 --- a/SL/DB/RequirementSpec.pm +++ b/SL/DB/RequirementSpec.pm @@ -156,7 +156,7 @@ sub create_copy { sub _create_copy { my ($self, %params) = @_; - my $copy = Rose::DB::Object::Helpers::clone_and_reset($self); + my $copy = $self->clone_and_reset; $copy->copy_from($self, %params); return $copy; @@ -185,14 +185,14 @@ sub _copy_from { # Clone text blocks and pictures. my $clone_and_reset_position = sub { my ($src_obj) = @_; - my $cloned = Rose::DB::Object::Helpers::clone_and_reset($src_obj); + my $cloned = $src_obj->clone_and_reset; $cloned->position(undef); return $cloned; }; my $clone_text_block = sub { my ($text_block) = @_; - my $cloned = Rose::DB::Object::Helpers::clone_and_reset($text_block); + my $cloned = $text_block->clone_and_reset; $cloned->position(undef); $cloned->pictures([ map { $clone_and_reset_position->($_) } @{ $text_block->pictures_sorted } ]); return $cloned; @@ -220,7 +220,7 @@ sub _copy_from { my $clone_item; $clone_item = sub { my ($item) = @_; - my $cloned = Rose::DB::Object::Helpers::clone_and_reset($item); + my $cloned = $item->clone_and_reset; $cloned->requirement_spec_id($self->id); $cloned->position(undef); $cloned->fb_number(undef) if $params->{paste_template}; -- 2.20.1