Changeset 1836
- Timestamp:
- 04/10/08 18:23:37 (8 months ago)
- Files:
-
- branches/feature-narrow-tables/lib/MT.pm.pre (modified) (9 diffs)
- branches/feature-narrow-tables/lib/MT/Asset.pm (modified) (1 diff)
- branches/feature-narrow-tables/lib/MT/Asset/Image.pm (modified) (1 diff)
- branches/feature-narrow-tables/lib/MT/Author.pm (modified) (2 diffs)
- branches/feature-narrow-tables/lib/MT/Blog.pm (modified) (2 diffs)
- branches/feature-narrow-tables/lib/MT/Component.pm (modified) (1 diff)
- branches/feature-narrow-tables/lib/MT/Core.pm (modified) (2 diffs)
- branches/feature-narrow-tables/lib/MT/Entry.pm (modified) (1 diff)
- branches/feature-narrow-tables/lib/MT/Meta.pm (modified) (10 diffs)
- branches/feature-narrow-tables/lib/MT/Meta/Proxy.pm (modified) (5 diffs)
- branches/feature-narrow-tables/lib/MT/Object.pm (modified) (18 diffs)
- branches/feature-narrow-tables/lib/MT/ObjectDriver/DDL/mysql.pm (modified) (1 diff)
- branches/feature-narrow-tables/lib/MT/Template.pm (modified) (2 diffs)
- branches/feature-narrow-tables/lib/MT/Upgrade.pm (modified) (1 diff)
- branches/feature-narrow-tables/t/64-objectmeta.t (modified) (3 diffs)
- branches/feature-narrow-tables/t/plugins/Awesome/config.yaml (modified) (1 diff)
- branches/feature-narrow-tables/t/plugins/Awesome/lib/MT/Awesome.pm (modified) (2 diffs)
- branches/feature-narrow-tables/t/plugins/Awesome/lib/MT/Awesome/Image.pm (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
branches/feature-narrow-tables/lib/MT.pm.pre
r1554 r1836 57 57 no strict 'refs'; 58 58 unless ( defined *{ $compat . '::' } ) { 59 eval " require $compat;";59 eval "# line " . __LINE__ . " " . __FILE__ . "\nrequire $compat;"; 60 60 } 61 61 } … … 266 266 return $object_types{$k} if exists $object_types{$k}; 267 267 268 if ($k =~ m/^(.+):meta$/) { 269 my $ppkg = $pkg->model($1); 270 my $mpkg = $ppkg->meta_pkg; 271 return $mpkg ? $object_types{$k} = $mpkg : undef; 272 } 273 268 274 my $model = $pkg->registry( 'object_types', $k ); 269 275 if ( ref($model) eq 'ARRAY' ) { … … 286 292 unless ( defined *{ $model . '::__properties' } ) { 287 293 use strict 'refs'; 288 eval " require $model;";294 eval "# line " . __LINE__ . " " . __FILE__ . "\nrequire $model;"; 289 295 if ( $@ && ( $k =~ m/^(.+)\./ ) ) { 290 296 … … 611 617 612 618 $cb->error(); # reset the error string 613 my $result = eval { $cb->invoke(@args) }; 619 my $result = eval { 620 # line __LINE__ __FILE__ 621 $cb->invoke(@args); 622 }; 614 623 if ( my $err = $@ ) { 615 624 $cb->error($err); … … 1250 1259 $Plugins{$plugin_sig}{full_path} = $plugin_full_path; 1251 1260 $timer->pause_partial if $timer; 1252 eval { require $plugin };1261 eval "# line " . __LINE__ . " " . __FILE__ . "\nrequire '$plugin';"; 1253 1262 $timer->mark("Loaded plugin " . $sig) if $timer; 1254 1263 if ($@) { … … 1258 1267 # the database has been initialized... 1259 1268 eval { 1269 # line __LINE__ __FILE__ 1260 1270 require MT::Log; 1261 1271 $mt->log( … … 2574 2584 if ($method) { 2575 2585 return sub { 2576 eval " require $hdlr_pkg;"2586 eval "# line " . __LINE__ . " " . __FILE__ . "\nrequire $hdlr_pkg;" 2577 2587 or Carp::confess( 2578 2588 "failed loading package $hdlr_pkg for routine $name: $@"); … … 2585 2595 else { 2586 2596 return sub { 2587 eval " require $hdlr_pkg;"2597 eval "# line " . __LINE__ . " " . __FILE__ . "\nrequire $hdlr_pkg;" 2588 2598 or Carp::confess( 2589 2599 "failed loading package $hdlr_pkg for routine $name: $@"); … … 2599 2609 } 2600 2610 else { 2601 eval " require $hdlr_pkg;"2611 eval "# line " . __LINE__ . " " . __FILE__ . "\nrequire $hdlr_pkg;" 2602 2612 or Carp::confess( 2603 2613 "failed loading package $hdlr_pkg for routine $name: $@"); branches/feature-narrow-tables/lib/MT/Asset.pm
r1763 r1836 41 41 }); 42 42 43 __PACKAGE__->install_meta({44 columns => [],45 });46 47 43 require MT::Asset::Image; 48 44 require MT::Asset::Audio; branches/feature-narrow-tables/lib/MT/Asset/Image.pm
r1174 r1836 10 10 use base qw( MT::Asset ); 11 11 12 __PACKAGE__->install_properties( { class_type => 'image', } ); 13 __PACKAGE__->install_meta( { columns => [ 'image_width', 'image_height', ], } ); 12 __PACKAGE__->install_properties( { 13 class_type => 'image', 14 column_defs => { 15 'image_width' => 'integer meta', 16 'image_height' => 'integer meta', 17 }, 18 } ); 14 19 15 20 # List of supported file extensions (to aid the stock 'can_handle' method.) branches/feature-narrow-tables/lib/MT/Author.pm
r1522 r1836 37 37 'userpic_asset_id' => 'integer', 38 38 'basename' => 'string(255)', 39 40 # meta properties 41 'widgets' => 'hash meta', 42 'favorite_blogs' => 'array meta', 39 43 }, 40 44 defaults => { … … 59 63 audit => 1, 60 64 }); 61 __PACKAGE__->install_meta({62 columns => [63 'favorite_blogs',64 'widgets',65 ],66 });67 65 68 66 sub class_label { branches/feature-narrow-tables/lib/MT/Blog.pm
r1554 r1836 77 77 'archive_tmpl_category' => 'string(255)', 78 78 'archive_tmpl_individual' => 'string(255)', 79 80 # meta properties 81 'image_default_wrap_text' => 'integer meta', 82 'image_default_align' => 'string meta', 83 'image_default_thumb' => 'integer meta', 84 'image_default_width' => 'integer meta', 85 'image_default_wunits' => 'integer meta', 86 'image_default_constrain' => 'integer meta', 87 'image_default_popup' => 'integer meta', 88 'commenter_authenticators' => 'string meta', 89 'require_typekey_emails' => 'integer meta', 90 'nofollow_urls' => 'integer meta', 91 'follow_auth_links' => 'integer meta', 92 'update_pings' => 'integer meta', 93 'captcha_provider' => 'string meta', 94 'publish_queue' => 'integer meta', 95 'nwc_smart_replace' => 'integer meta', 96 'nwc_replace_field' => 'string meta', 97 'template_set' => 'string meta', 98 'page_layout' => 'string meta', 99 'include_system' => 'integer meta', 100 'include_cache' => 'integer meta', 79 101 }, 80 102 meta => 1, … … 87 109 'custom_dynamic_templates' => 'none', 88 110 }, 89 child_classes => ['MT::Entry', 'MT::Page', 'MT::Template', 'MT::Asset', 90 'MT::Category', 'MT::Folder', 'MT::Notification', 'MT::Log', 91 'MT::ObjectTag', 'MT::Association', 'MT::Comment', 92 'MT::TBPing', 'MT::Trackback', 'MT::TemplateMap'], 111 child_classes => [ 112 'MT::Entry', 'MT::Page', 'MT::Template', 'MT::Asset', 'MT::Category', 113 'MT::Folder', 'MT::Notification', 'MT::Log', 'MT::ObjectTag', 114 'MT::Association', 'MT::Comment', 'MT::TBPing', 'MT::Trackback', 115 'MT::TemplateMap' 116 ], 93 117 datasource => 'blog', 94 118 primary_key => 'id', 95 });96 __PACKAGE__->install_meta({97 columns => [98 'image_default_wrap_text',99 'image_default_align',100 'image_default_thumb',101 'image_default_width',102 'image_default_wunits',103 'image_default_constrain',104 'image_default_popup',105 'commenter_authenticators',106 'require_typekey_emails',107 'nofollow_urls',108 'follow_auth_links',109 'update_pings',110 'captcha_provider',111 'publish_queue',112 'nwc_smart_replace',113 'nwc_replace_field',114 'template_set',115 'page_layout',116 'include_system',117 'include_cache',118 ],119 119 }); 120 120 branches/feature-narrow-tables/lib/MT/Component.pm
r1572 r1836 508 508 509 509 # check for a yaml file reference... 510 if ( !ref($v) && ( $v =~ m/^[-\w]+\.yaml$/ ) ) { 511 my $f = File::Spec->catfile( $c->path, $v ); 512 if ( -f $f ) { 513 require YAML::Tiny; 514 my $y = eval { YAML::Tiny->read($f) } 515 or die "Error reading $f: " . $YAML::Tiny::errstr; 516 517 # skip over non-hash elements 518 shift @$y while @$y && ( ref( $y->[0] ) ne 'HASH' ); 519 if (@$y) { 520 $r->{$p} = $y->[0]; 510 if ( !ref($v) ) { 511 if ( $v =~ m/^[-\w]+\.yaml$/ ) { 512 my $f = File::Spec->catfile( $c->path, $v ); 513 if ( -f $f ) { 514 require YAML::Tiny; 515 my $y = eval { YAML::Tiny->read($f) } 516 or die "Error reading $f: " 517 . $YAML::Tiny::errstr; 518 # skip over non-hash elements 519 shift @$y 520 while @$y && ( ref( $y->[0] ) ne 'HASH' ); 521 $r->{$p} = $y->[0] if @$y; 522 } 523 } elsif ($v =~ m/^\$\w+::/) { 524 my $code = MT->handler_to_coderef($v); 525 if (ref $code eq 'CODE') { 526 $r->{$p} = $code->($c); 521 527 } 522 528 } branches/feature-narrow-tables/lib/MT/Core.pm
r1790 r1836 51 51 object_types => { 52 52 'entry' => 'MT::Entry', 53 'entry_meta' => 'MT::Entry::Meta',54 53 'author' => 'MT::Author', 55 'author_meta' => 'MT::Author::Meta',56 54 'asset' => 'MT::Asset', 57 'asset_meta' => 'MT::Asset::Meta',58 55 'file' => 'MT::Asset', 59 56 'asset.image' => 'MT::Asset::Image', … … 71 68 'commenter' => 'MT::Author', 72 69 'blog' => 'MT::Blog', 73 'blog_meta' => 'MT::Blog::Meta',74 70 'template' => 'MT::Template', 75 'template_meta' => 'MT::Template::Meta',76 71 'comment' => 'MT::Comment', 77 72 'notification' => 'MT::Notification', branches/feature-narrow-tables/lib/MT/Entry.pm
r1763 r1836 105 105 }); 106 106 107 __PACKAGE__->install_meta({108 columns => [],109 });110 111 107 sub HOLD () { 1 } 112 108 sub RELEASE () { 2 } branches/feature-narrow-tables/lib/MT/Meta.pm
r1814 r1836 16 16 # Constants 17 17 18 use constant TYPE_VCHAR => 1; 19 use constant TYPE_VCHAR_INDEXED => 2; 20 use constant TYPE_VBLOB => 3; 21 22 use constant DEBUG => 0; 18 sub TYPE_VCHAR () { 1 } 19 sub TYPE_VCHAR_INDEXED () { 2 } 20 sub TYPE_VBLOB () { 3 } 21 sub TYPE_VINTEGER () { 4 } 22 sub TYPE_VINTEGER_INDEXED () { 5 } 23 sub TYPE_VDATETIME () { 6 } 24 sub TYPE_VDATETIME_INDEXED () { 7 } 25 sub TYPE_VFLOAT () { 8 } 26 sub TYPE_VFLOAT_INDEXED () { 9 } 27 28 sub DEBUG () { 0 } 23 29 24 30 ## Specify if the faster REPLACE INTO can be used instead of INSERT/UPDATE … … 26 32 27 33 our %Types = ( 28 TYPE_VCHAR => "vchar", 29 TYPE_VCHAR_INDEXED => "vchar_indexed", 30 TYPE_VBLOB => "vblob", 34 TYPE_VCHAR() => "vchar", 35 TYPE_VCHAR_INDEXED() => "vchar_indexed", 36 TYPE_VINTEGER() => "vinteger", 37 TYPE_VINTEGER_INDEXED() => "vinteger_indexed", 38 TYPE_VDATETIME() => "vdatetime", 39 TYPE_VDATETIME_INDEXED() => "vdatetime_indexed", 40 TYPE_VFLOAT() => "vfloat", 41 TYPE_VFLOAT_INDEXED() => "vfloat_indexed", 42 TYPE_VBLOB() => "vblob", 31 43 ); 32 44 33 45 our %TypesByName = reverse %Types; 46 47 # some other aliases 48 $TypesByName{string} = TYPE_VCHAR; 49 $TypesByName{integer} = TYPE_VINTEGER; 50 $TypesByName{datetime} = TYPE_VDATETIME; 51 $TypesByName{float} = TYPE_VFLOAT; 52 $TypesByName{string_indexed} = TYPE_VCHAR_INDEXED; 53 $TypesByName{integer_indexed} = TYPE_VINTEGER_INDEXED; 54 $TypesByName{datetime_indexed} = TYPE_VDATETIME_INDEXED; 55 $TypesByName{float_indexed} = TYPE_VFLOAT_INDEXED; 56 $TypesByName{hash} = TYPE_VBLOB; 57 $TypesByName{array} = TYPE_VBLOB; 34 58 35 59 ## $Registry = { … … 78 102 my $key = $params->{key}; 79 103 my $inherited = $class->_load_inheritance($pkg, $key); 80 my $fields = delete $params->{fields}; # we'll reduce this big value 104 105 my $fields = delete $params->{fields}; # we'll reduce this big value 81 106 push @$fields, @$inherited; 82 107 … … 92 117 93 118 ## Assume columns are the default types, if they weren't specified. 94 if(!$params->{columns} && $params->{column_defs}) {95 $params->{columns} = [ keys %{ $params->{column_defs} } ];96 }97 elsif (!$params->{columns}) {98 push @{ $params->{columns} }, qw( vchar vchar_indexed vblob );99 @{ $params->{column_defs} }{qw( vchar vchar_indexed vblob )} = qw( string(255) string(255) blob );100 }119 # if(!$params->{columns} && $params->{column_defs}) { 120 # $params->{columns} = [ keys %{ $params->{column_defs} } ]; 121 # } 122 # elsif (!$params->{columns}) { 123 # push @{ $params->{columns} }, qw( vchar vchar_indexed vblob ); 124 # @{ $params->{column_defs} }{qw( vchar vchar_indexed vblob )} = qw( string(255) string(255) blob ); 125 # } 101 126 102 127 ## build subclass 103 128 $class->_build_subclass($pkg, $params); 104 129 105 return 1;130 return $params->{fields}; 106 131 } 107 132 … … 129 154 name => $name, 130 155 type_id => $type_id, 131 type => $ type,156 type => $Types{$type_id}, 132 157 pkg => $pkg, 133 158 }; 134 159 $value->{zip} = $zip if defined $zip; 135 160 136 $Registry->{$key} ->{$pkg}->{$name} = $value;161 $Registry->{$key}{$pkg}{$name} = $value; 137 162 } 138 163 } … … 147 172 my $class = shift; 148 173 my($pkg, $name) = @_; 149 $Registry->{ $pkg->meta_args->{key} }{$pkg} ->{$name};174 $Registry->{ $pkg->meta_args->{key} }{$pkg}{$name}; 150 175 } 151 176 … … 156 181 my($pkg) = @_; 157 182 my $key = $pkg->meta_args->{key}; # xxx is it really safe to call meta_args? 158 exists $Registry->{$key}->{$pkg}; 183 exists $Registry->{$key}{$pkg}; 184 } 185 186 sub normalize_type { 187 my $pkg = shift; 188 my ($type) = @_; 189 return $Types{ $TypesByName{ $type } } || TYPE_VBLOB; 159 190 } 160 191 … … 170 201 return [] if $base eq $pkg; 171 202 my @inherited; 172 if (exists $Registry->{$key} ->{$base}) {203 if (exists $Registry->{$key}{$base}) { 173 204 for my $field ( values %{ $Registry->{$key}->{$base} } ) { 174 205 push @inherited, $field; … … 183 214 184 215 my $subclass = $pkg->meta_pkg; 185 186 return if defined *{"${subclass}::"}; 216 return unless $subclass; 217 218 return if defined ${"${subclass}::VERSION"}; 187 219 188 220 ## Try to use this subclass first to see if it exists … … 203 235 my $base_class = 'MT::Object::Meta'; 204 236 205 ## no critic ProhibitStringyEval206 eval"237 my $subclass_src = " 238 # line " . __LINE__ . " " . __FILE__ . " 207 239 package $subclass; 240 our \$VERSION = 1.0; 208 241 use base qw($base_class); 209 242 1; 210 " or print STDERR "Could not create package $subclass!\n"; 243 "; 244 245 ## no critic ProhibitStringyEval 246 eval $subclass_src or print STDERR "Could not create package $subclass!\n"; 211 247 212 248 $subclass->install_properties($meta); branches/feature-narrow-tables/lib/MT/Meta/Proxy.pm
r1603 r1836 16 16 $HAS_ZLIB = 1 unless $@; 17 17 18 my $serializer = MT::Serialize->new(' Storable');18 my $serializer = MT::Serialize->new('MT'); 19 19 20 20 sub new { … … 63 63 64 64 $proxy->lazy_load_objects; 65 65 66 if (exists $proxy->{__objects}->{$col}) { 66 67 my $pkg = $proxy->{pkg}; … … 71 72 my $type = $field->{type} 72 73 or Carp::croak("$col not found on $pkg meta fields"); 73 74 74 75 unless ($meta->has_column($type)) { 75 76 Carp::croak("something is wrong: $type not in column_values of metadata"); … … 80 81 return undef; 81 82 } 83 } 84 85 sub get_hash { 86 my $proxy = shift; 87 my ($col) = @_; 88 89 $proxy->lazy_load_objects; 90 91 my $collection = {}; 92 93 foreach my $name (keys %{ $proxy->{__objects} }) { 94 $collection->{$name} = $proxy->get($name); 95 } 96 97 return $collection; 98 } 99 100 sub get_collection { 101 my $proxy = shift; 102 my ($col) = @_; 103 104 $proxy->lazy_load_objects; 105 106 my $collection = {}; 107 108 foreach my $name (keys %{ $proxy->{__objects} }) { 109 if ($name =~ m/^\Q$col\E\.(.+)$/) { 110 my $suffix = $1; 111 $collection->{$suffix} = $proxy->get($name); 112 } 113 } 114 115 return $collection; 82 116 } 83 117 … … 226 260 my $type = $field->{type}; 227 261 228 unserialize_blob($meta_obj) if ($meta_obj->properties->{column_defs}->{$type}||'') eq 'blob'; 262 unserialize_blob($meta_obj) 263 if ($meta_obj->properties->{column_defs}->{$type}||'') eq 'blob'; 229 264 $proxy->{__objects}->{$name} = $meta_obj; 230 265 } branches/feature-narrow-tables/lib/MT/Object.pm
r1814 r1836 53 53 } 54 54 55 my %meta; 56 55 57 my $super_props = $class->SUPER::properties(); 58 $props->{meta} = 1 if $super_props && $super_props->{meta}; 59 60 if ($props->{meta}) { 61 # yank out any meta columns before we start working on column_defs 62 $meta{$_} = delete $props->{column_defs}{$_} 63 for grep { $props->{column_defs}{$_} =~ m/\bmeta\b/ } 64 keys %{ $props->{column_defs} }; 65 } 66 56 67 if ($super_props) { 57 68 # subclass; merge hash … … 81 92 # Legacy MT::Object types only define 'columns'; we still support that 82 93 # but they aren't handled properly with the upgrade system as a result. 83 if (exists $props->{column_defs}) { 84 $props->{columns} = [ keys %{ $props->{column_defs} } ]; 85 } else { 94 if (! exists $props->{column_defs}) { 86 95 map { $props->{column_defs}{$_} = () } @{ $props->{columns} }; 87 96 } 97 $props->{columns} = [ keys %{ $props->{column_defs} } ]; 88 98 89 99 # Support audit flags … … 139 149 foreach my $isa_class (@classes) { 140 150 next if UNIVERSAL::isa($class, $isa_class); 141 eval " require $isa_class;" or die;151 eval "# line " . __LINE__ . " " . __FILE__ . "\nrequire $isa_class;" or die; 142 152 no strict 'refs'; ## no critic 143 153 push @{$class . '::ISA'}, $isa_class; … … 148 158 for my $name (keys %$cols) { 149 159 next if exists $props->{column_defs}{$name}; 160 if ($cols->{$name} =~ m/\bmeta\b/) { 161 $meta{$name} = $cols->{$name}; 162 next; 163 } 164 150 165 $class->install_column($name, $cols->{$name}); 151 166 $props->{indexes}{$name} = 1 … … 211 226 212 227 # inherit parent's metadata setup 213 if ($super_props && $super_props->{meta_installed}) { 214 $class->install_meta({ columns => [] }); # no add'l columns 228 if ($props->{meta}) { # if ($super_props && $super_props->{meta_installed}) { 229 $class->install_meta({ ( %meta ? ( column_defs => \%meta ) : ( columns => [] ) ) }); 230 $class->add_trigger( post_remove => \&remove_meta ); 215 231 } 216 232 … … 327 343 return $package; 328 344 } else { 329 eval " use $package;";345 eval "# line " . __LINE__ . " " . __FILE__ . "\nuse $package;"; 330 346 return $package unless $@; 331 eval " use $pkg; $package->new;";347 eval "# line " . __LINE__ . " " . __FILE__ . "\nuse $pkg; $package->new;"; 332 348 return $package unless $@; 333 349 } … … 376 392 } 377 393 394 require MT::Meta; 378 395 my $pkg = ref $class || $class; 379 396 if (!$pkg->SUPER::properties->{meta_installed}) { … … 382 399 } 383 400 384 if (!$params->{columns} && !$params->{fields}) { 401 my $props = $class->properties; 402 403 if (!$params->{columns} && !$params->{fields} && !$params->{column_defs}) { 385 404 return $class->error('No meta fields specified to install_meta'); 386 405 } … … 388 407 $params->{fields} ||= []; 389 408 if (my $cols = delete $params->{columns}) { 390 push @{ $params->{fields} }, 391 map { +{ name => $_, type => 'vblob' } } @$cols; 392 } 393 394 $params->{datasource} ||= join q{_}, $class->datasource, 'meta'; 395 396 require MT::Meta; 397 $class->properties->{meta_installed} = MT::Meta->install($pkg, $params); 409 foreach my $col (@$cols) { 410 push @{ $params->{fields} }, { 411 name => $col, 412 type => 'vblob', 413 }; 414 # $props->{fields}{$col} = 'vblob'; 415 } 416 } 417 if (my $cols = delete $params->{column_defs}) { 418 foreach my $col ( keys %$cols ) { 419 my $type = $cols->{$col}; 420 $type =~ s/\s.*//; # take first keyword, ignoring anything after 421 $type .= '_indexed' 422 if $cols->{$col} =~ m/\bindexed\b/; 423 $type = MT::Meta->normalize_type($type); 424 425 push @{ $params->{fields} }, { 426 name => $col, 427 type => $type, 428 }; 429 # $props->{fields}{$col} = $type; 430 } 431 } 432 433 $params->{datasource} ||= $class->datasource . '_meta'; 434 435 if ($props->{meta_installed} && !@{ $params->{fields} }) { 436 return 1; 437 } 438 439 if (my $fields = MT::Meta->install($pkg, $params)) { 440 # we may have inherited meta fields so lets update with 441 # the fields returned by MT::Meta 442 $props->{fields} = $fields; 443 } 444 445 return $props->{meta_installed} = 1; 398 446 } 399 447 … … 404 452 key => $class->datasource, 405 453 column_defs => { 406 $id_field => 'integer not null', 407 type => 'string(255) not null', 408 vchar => 'string(255)', 409 vchar_indexed => 'string(255)', 410 vblob => 'blob', 454 $id_field => 'integer not null', 455 type => 'string(255) not null', 456 vchar => 'string(255)', 457 vchar_indexed => 'string(255)', 458 vdatetime => 'datetime', 459 vdatetime_indexed => 'datetime', 460 vinteger => 'integer', 461 vinteger_indexed => 'integer', 462 vfloat => 'float', 463 vfloat_indexed => 'float', 464 vblob => 'blob', 411 465 }, 466 columns => [ $id_field, qw( 467 type 468 vchar 469 vchar_indexed 470 vdatetime 471 vdatetime_indexed 472 vinteger 473 vinteger_indexed 474 vfloat 475 vfloat_indexed 476 vblob 477 ) ], 412 478 indexes => { 413 479 $id_field => 1, 414 480 id_type => { columns => [ $id_field, 'type' ] }, 415 id_type_vchar_indexed => { columns => [ $id_field, 'type', 'vchar_indexed' ] }, 481 id_type_vchar => { columns => [ $id_field, 'type', 'vchar_indexed' ] }, 482 id_type_vdatetime => { columns => [ $id_field, 'type', 483 'vdatetime_indexed' ] }, 484 id_type_vinteger => { columns => [ $id_field, 'type', 485 'vinteger_indexed' ] }, 486 id_type_vfloat => { columns => [ $id_field, 'type', 487 'vfloat_indexed' ] }, 416 488 }, 417 489 primary_key => [ $class->datasource . '_id', 'type' ], … … 435 507 sub is_meta_column { 436 508 my $obj = shift; 437 return if !$obj->properties->{meta_installed};438 509 my ($field) = @_; 439 510 511 my $props = $obj->properties; 512 return unless $props->{meta_installed}; 513 440 514 my $meta = $obj->meta_pkg; 441 return 1 if $meta->properties->{fields}->{$field}; 515 return 1 if $props->{fields}{$field}; 516 442 517 return; 443 518 } … … 445 520 sub meta_pkg { 446 521 my $class = shift; 522 my $props = $class->properties; 523 return unless $props->{meta}; # this only works for meta-enabled classes 524 525 return $props->{meta_pkg} if $props->{meta_pkg}; 526 447 527 my $meta = ref $class || $class; 448 528 $meta .= '::Meta'; 449 return $ meta;529 return $props->{meta_pkg} = $meta; 450 530 } 451 531 … … 472 552 : 2 == scalar @_ ? $obj->{__meta}->set($name, $value) 473 553 : 1 == scalar @_ ? $obj->{__meta}->get($name) 474 : Carp::croak('TODO: implement returning a metadata hash')554 : $obj->{__meta}->get_hash 475 555 ; 556 } 557 558 sub meta_obj { 559 my $obj = shift; 560 return $obj->{__meta}; 476 561 } 477 562 … … 848 933 } 849 934 935 sub remove_meta { 936 my $obj = shift; 937 return 1 unless ref $obj; 938 my $mpkg = $obj->meta_pkg or return; 939 my $id_field = $obj->datasource . '_id'; 940 return $mpkg->remove({ $id_field => $obj->id }); 941 } 942 850 943 sub remove_children { 851 944 my $obj = shift; … … 861 954 my $obj_id = $obj->id; 862 955 for my $class (@classes) { 863 eval " use $class;";956 eval "# line " . __LINE__ . " " . __FILE__ . "\nuse $class;"; 864 957 $class->remove({ $key => $obj_id }); 865 958 } … … 970 1063 $def{key} = 1 if ($props->{primary_key}) && ($props->{primary_key} eq $col); 971 1064 $def{auto} = 1 if $def =~ m/\bauto[_ ]increment\b/i; 972 $def{default} = $props->{defaults}{$col} if exists $props->{defaults}{$col}; 1065 $def{default} = $props->{defaults}{$col} 1066 if exists $props->{defaults}{$col}; 973 1067 \%def; 974 1068 } … … 1050 1144 } 1051 1145 1146 sub meta_pkg { undef } 1147 1052 1148 *table_name = \&MT::Object::table_name; 1053 1149 *column_defs = \&MT::Object::column_defs; … … 1056 1152 *__parse_defs = \&MT::Object::__parse_defs; 1057 1153 *__parse_def = \&MT::Object::__parse_def; 1154 *count = \&MT::Object::count; 1058 1155 1059 1156 # TODO: copy this too branches/feature-narrow-tables/lib/MT/ObjectDriver/DDL/mysql.pm
r1174 r1836 22 22 my $field_prefix = $class->datasource; 23 23 my $table_name = $class->table_name; 24 local $dbh->{RaiseError} = 0; 24 25 my $sth = $dbh->prepare('SHOW INDEX FROM ' . $table_name) 25 26 or return undef; branches/feature-narrow-tables/lib/MT/Template.pm
r1535 r1836 35 35 'build_type' => 'smallint', 36 36 'build_interval' => 'integer', 37 38 # meta properties 39 'last_rebuild_time' => 'integer meta', 40 'page_layout' => 'string meta', 41 'include_with_ssi' => 'integer meta', 37 42 }, 38 43 indexes => { … … 54 59 datasource => 'template', 55 60 primary_key => 'id', 56 });57 __PACKAGE__->install_meta({58 columns => [59 'last_rebuild_time',60 'page_layout',61 'include_with_ssi',62 ],63 61 }); 64 62 __PACKAGE__->add_trigger('pre_remove' => \&pre_remove_children); branches/feature-narrow-tables/lib/MT/Upgrade.pm
r1583 r1836 1316 1316 } 1317 1317 } 1318 1319 # handle schema updates for meta table 1320 if ($class->meta_pkg) { 1321 $self->check_type($type . ':meta'); 1322 } 1323 1318 1324 1; 1319 1325 } branches/feature-narrow-tables/t/64-objectmeta.t
r1603 r1836 5 5 6 6 use Data::Dumper; 7 use Test::More tests => 18;7 use Test::More tests => 26; 8 8 9 9 use MT; … … 17 17 require MT::Awesome; 18 18 require MT::Awesome::Image; 19 19 20 my $file = MT::Awesome->new; 20 21 my $image = MT::Awesome::Image->new; … … 52 53 ok($image->has_meta('width'), 'subclass has metadata field that was declared for subclass'); 53 54 ok($image->has_meta('mime_type'), 'subclass has metadata field that was declared for superclass'); 55 ok($image->mime_type('image/jpeg'), 'subclass object mime type set'); 56 ok($image->save(), 'image object saved'); 54 57 58 ok($image->id, 'image object with metadata received id when saved'); 59 60 my $image_2 = MT::Awesome->load($image->id); 61 ok($image_2, 'subclass object could be loaded'); 62 is($image_2->mime_type, 'image/jpeg', 'metadata value as retrieved with auto-installed method is correct on loaded image object'); 63 64 ok(MT::Asset::Image->has_meta('image_width'), 'MT::Asset::Image has an image_width meta column.'); 65 ok(MT::Entry->has_meta, 'MT::Entry has a meta support.'); 66 ok(MT::Page->has_meta, 'MT::Page has a meta support.'); 67 branches/feature-narrow-tables/t/plugins/Awesome/config.yaml
r1603 r1836 4 4 5 5 object_types: 6 blog_meta: MT::Blog::Meta7 6 awesome: MT::Awesome 8 awesome_meta: MT::Awesome::Meta9 7 awesome_image: MT::Awesome::Image 10 8 branches/feature-narrow-tables/t/plugins/Awesome/lib/MT/Awesome.pm
r1603 r1836 9 9 title => 'string(255)', 10 10 file => 'string(255)', 11 mime_type => 'string meta', 11 12 }, 12 13 meta => 1, … … 15 16 primary_key => 'id', 16 17 }); 17 __PACKAGE__->install_meta({18 columns => [ 'mime_type' ]19 });20 18 21 19 1; branches/feature-narrow-tables/t/plugins/Awesome/lib/MT/Awesome/Image.pm
r1603 r1836 1 2 1 package MT::Awesome::Image; 3 2 … … 6 5 __PACKAGE__->install_properties({ 7 6 class_type => 'image', 8 }); 9 __PACKAGE__->install_meta({ 10 columns => [ 'width', 'height' ] 7 column_defs => { 8 'width' => 'integer meta', 9 'height' => 'integer meta indexed', 10 }, 11 11 }); 12 12
