Changeset 1836

Show
Ignore:
Timestamp:
04/10/08 18:23:37 (8 months ago)
Author:
bchoate
Message:

Updates to support expressing meta columns in 'column_defs' structure.
Changes to registry lookup to support handler declarations.
Added meta type aliases for MT type names ('string', 'integer', etc.). BugId:68749

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/feature-narrow-tables/lib/MT.pm.pre

    r1554 r1836  
    5757            no strict 'refs'; 
    5858            unless ( defined *{ $compat . '::' } ) { 
    59                 eval "require $compat;"; 
     59                eval "# line " . __LINE__ . " " . __FILE__ . "\nrequire $compat;"; 
    6060            } 
    6161        } 
     
    266266        return $object_types{$k} if exists $object_types{$k}; 
    267267 
     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 
    268274        my $model = $pkg->registry( 'object_types', $k ); 
    269275        if ( ref($model) eq 'ARRAY' ) { 
     
    286292        unless ( defined *{ $model . '::__properties' } ) { 
    287293            use strict 'refs'; 
    288             eval "require $model;"; 
     294            eval "# line " . __LINE__ . " " . __FILE__ . "\nrequire $model;"; 
    289295            if ( $@ && ( $k =~ m/^(.+)\./ ) ) { 
    290296 
     
    611617 
    612618    $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    }; 
    614623    if ( my $err = $@ ) { 
    615624        $cb->error($err); 
     
    12501259                    $Plugins{$plugin_sig}{full_path} = $plugin_full_path; 
    12511260                    $timer->pause_partial if $timer; 
    1252                     eval { require $plugin }
     1261                    eval "# line " . __LINE__ . " " . __FILE__ . "\nrequire '$plugin';"
    12531262                    $timer->mark("Loaded plugin " . $sig) if $timer; 
    12541263                    if ($@) { 
     
    12581267                        # the database has been initialized... 
    12591268                        eval { 
     1269                            # line __LINE__ __FILE__ 
    12601270                            require MT::Log; 
    12611271                            $mt->log( 
     
    25742584            if ($method) { 
    25752585                return sub { 
    2576                     eval "require $hdlr_pkg;" 
     2586                    eval "# line " . __LINE__ . " " . __FILE__ . "\nrequire $hdlr_pkg;" 
    25772587                      or Carp::confess( 
    25782588                        "failed loading package $hdlr_pkg for routine $name: $@"); 
     
    25852595            else { 
    25862596                return sub { 
    2587                     eval "require $hdlr_pkg;" 
     2597                    eval "# line " . __LINE__ . " " . __FILE__ . "\nrequire $hdlr_pkg;" 
    25882598                      or Carp::confess( 
    25892599                        "failed loading package $hdlr_pkg for routine $name: $@"); 
     
    25992609        } 
    26002610        else { 
    2601             eval "require $hdlr_pkg;" 
     2611            eval "# line " . __LINE__ . " " . __FILE__ . "\nrequire $hdlr_pkg;" 
    26022612              or Carp::confess( 
    26032613                "failed loading package $hdlr_pkg for routine $name: $@"); 
  • branches/feature-narrow-tables/lib/MT/Asset.pm

    r1763 r1836  
    4141}); 
    4242 
    43 __PACKAGE__->install_meta({ 
    44     columns => [], 
    45 }); 
    46  
    4743require MT::Asset::Image; 
    4844require MT::Asset::Audio; 
  • branches/feature-narrow-tables/lib/MT/Asset/Image.pm

    r1174 r1836  
    1010use base qw( MT::Asset ); 
    1111 
    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} ); 
    1419 
    1520# List of supported file extensions (to aid the stock 'can_handle' method.) 
  • branches/feature-narrow-tables/lib/MT/Author.pm

    r1522 r1836  
    3737        'userpic_asset_id' => 'integer', 
    3838        'basename' => 'string(255)', 
     39 
     40        # meta properties 
     41        'widgets' => 'hash meta', 
     42        'favorite_blogs' => 'array meta', 
    3943    }, 
    4044    defaults => { 
     
    5963    audit => 1, 
    6064}); 
    61 __PACKAGE__->install_meta({ 
    62     columns => [ 
    63         'favorite_blogs', 
    64         'widgets', 
    65     ], 
    66 }); 
    6765 
    6866sub class_label { 
  • branches/feature-narrow-tables/lib/MT/Blog.pm

    r1554 r1836  
    7777        'archive_tmpl_category' => 'string(255)', 
    7878        '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', 
    79101    }, 
    80102    meta => 1, 
     
    87109        'custom_dynamic_templates' => 'none', 
    88110    }, 
    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    ], 
    93117    datasource => 'blog', 
    94118    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     ], 
    119119}); 
    120120 
  • branches/feature-narrow-tables/lib/MT/Component.pm

    r1572 r1836  
    508508 
    509509                # 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); 
    521527                        } 
    522528                    } 
  • branches/feature-narrow-tables/lib/MT/Core.pm

    r1790 r1836  
    5151        object_types   => { 
    5252            'entry'           => 'MT::Entry', 
    53             'entry_meta'      => 'MT::Entry::Meta', 
    5453            'author'          => 'MT::Author', 
    55             'author_meta'     => 'MT::Author::Meta', 
    5654            'asset'           => 'MT::Asset', 
    57             'asset_meta'      => 'MT::Asset::Meta', 
    5855            'file'            => 'MT::Asset', 
    5956            'asset.image'     => 'MT::Asset::Image', 
     
    7168            'commenter'       => 'MT::Author', 
    7269            'blog'            => 'MT::Blog', 
    73             'blog_meta'       => 'MT::Blog::Meta', 
    7470            'template'        => 'MT::Template', 
    75             'template_meta'   => 'MT::Template::Meta', 
    7671            'comment'         => 'MT::Comment', 
    7772            'notification'    => 'MT::Notification', 
  • branches/feature-narrow-tables/lib/MT/Entry.pm

    r1763 r1836  
    105105}); 
    106106 
    107 __PACKAGE__->install_meta({ 
    108     columns => [], 
    109 }); 
    110  
    111107sub HOLD ()    { 1 } 
    112108sub RELEASE () { 2 } 
  • branches/feature-narrow-tables/lib/MT/Meta.pm

    r1814 r1836  
    1616# Constants 
    1717 
    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; 
     18sub TYPE_VCHAR ()             { 1 } 
     19sub TYPE_VCHAR_INDEXED ()     { 2 } 
     20sub TYPE_VBLOB ()             { 3 } 
     21sub TYPE_VINTEGER ()          { 4 } 
     22sub TYPE_VINTEGER_INDEXED ()  { 5 } 
     23sub TYPE_VDATETIME ()         { 6 } 
     24sub TYPE_VDATETIME_INDEXED () { 7 } 
     25sub TYPE_VFLOAT ()            { 8 } 
     26sub TYPE_VFLOAT_INDEXED ()    { 9 } 
     27 
     28sub DEBUG () { 0 } 
    2329 
    2430## Specify if the faster REPLACE INTO can be used instead of INSERT/UPDATE 
     
    2632 
    2733our %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", 
    3143); 
    3244 
    3345our %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; 
    3458 
    3559## $Registry = { 
     
    78102    my $key = $params->{key}; 
    79103    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 
    81106    push @$fields, @$inherited; 
    82107 
     
    92117     
    93118    ## 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    #
    101126 
    102127    ## build subclass 
    103128    $class->_build_subclass($pkg, $params); 
    104129 
    105     return 1
     130    return $params->{fields}
    106131} 
    107132 
     
    129154            name    => $name, 
    130155            type_id => $type_id, 
    131             type    => $type
     156            type    => $Types{$type_id}
    132157            pkg     => $pkg, 
    133158        }; 
    134159        $value->{zip} = $zip if defined $zip; 
    135160 
    136         $Registry->{$key}->{$pkg}->{$name} = $value; 
     161        $Registry->{$key}{$pkg}{$name} = $value; 
    137162    } 
    138163} 
     
    147172    my $class = shift; 
    148173    my($pkg, $name) = @_; 
    149     $Registry->{ $pkg->meta_args->{key} }{$pkg}->{$name}; 
     174    $Registry->{ $pkg->meta_args->{key} }{$pkg}{$name}; 
    150175} 
    151176 
     
    156181    my($pkg)  = @_; 
    157182    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 
     186sub normalize_type { 
     187    my $pkg = shift; 
     188    my ($type) = @_; 
     189    return $Types{ $TypesByName{ $type } } || TYPE_VBLOB; 
    159190} 
    160191 
     
    170201    return [] if $base eq $pkg; 
    171202    my @inherited; 
    172     if (exists $Registry->{$key}->{$base}) { 
     203    if (exists $Registry->{$key}{$base}) { 
    173204        for my $field ( values %{ $Registry->{$key}->{$base} } ) { 
    174205            push @inherited, $field; 
     
    183214 
    184215    my $subclass = $pkg->meta_pkg; 
    185  
    186     return if defined *{"${subclass}::"}; 
     216    return unless $subclass; 
     217 
     218    return if defined ${"${subclass}::VERSION"}; 
    187219 
    188220    ## Try to use this subclass first to see if it exists 
     
    203235    my $base_class = 'MT::Object::Meta'; 
    204236 
    205     ## no critic ProhibitStringyEval  
    206     eval
     237    my $subclass_src = " 
     238        # line " . __LINE__ . " " . __FILE__ .
    207239        package $subclass; 
     240        our \$VERSION = 1.0; 
    208241        use base qw($base_class); 
    209242        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"; 
    211247 
    212248    $subclass->install_properties($meta); 
  • branches/feature-narrow-tables/lib/MT/Meta/Proxy.pm

    r1603 r1836  
    1616$HAS_ZLIB = 1 unless $@; 
    1717 
    18 my $serializer = MT::Serialize->new('Storable'); 
     18my $serializer = MT::Serialize->new('MT'); 
    1919 
    2020sub new { 
     
    6363 
    6464    $proxy->lazy_load_objects; 
     65 
    6566    if (exists $proxy->{__objects}->{$col}) { 
    6667        my $pkg  = $proxy->{pkg}; 
     
    7172        my $type = $field->{type} 
    7273            or Carp::croak("$col not found on $pkg meta fields"); 
    73              
     74 
    7475        unless ($meta->has_column($type)) { 
    7576            Carp::croak("something is wrong: $type not in column_values of metadata"); 
     
    8081        return undef; 
    8182    } 
     83} 
     84 
     85sub 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 
     100sub 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; 
    82116} 
    83117 
     
    226260        my $type  = $field->{type}; 
    227261 
    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'; 
    229264        $proxy->{__objects}->{$name} = $meta_obj; 
    230265    } 
  • branches/feature-narrow-tables/lib/MT/Object.pm

    r1814 r1836  
    5353    } 
    5454 
     55    my %meta; 
     56 
    5557    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 
    5667    if ($super_props) { 
    5768        # subclass; merge hash 
     
    8192    # Legacy MT::Object types only define 'columns'; we still support that 
    8293    # 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}) { 
    8695        map { $props->{column_defs}{$_} = () } @{ $props->{columns} }; 
    8796    } 
     97    $props->{columns} = [ keys %{ $props->{column_defs} } ]; 
    8898 
    8999    # Support audit flags 
     
    139149        foreach my $isa_class (@classes) { 
    140150            next if UNIVERSAL::isa($class, $isa_class); 
    141             eval "require $isa_class;" or die; 
     151            eval "# line " . __LINE__ . " " . __FILE__ . "\nrequire $isa_class;" or die; 
    142152            no strict 'refs'; ## no critic 
    143153            push @{$class . '::ISA'}, $isa_class; 
     
    148158            for my $name (keys %$cols) { 
    149159                next if exists $props->{column_defs}{$name}; 
     160                if ($cols->{$name} =~ m/\bmeta\b/) { 
     161                    $meta{$name} = $cols->{$name}; 
     162                    next; 
     163                } 
     164 
    150165                $class->install_column($name, $cols->{$name}); 
    151166                $props->{indexes}{$name} = 1 
     
    211226 
    212227    # 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 ); 
    215231    } 
    216232 
     
    327343            return $package; 
    328344        } else { 
    329             eval "use $package;"; 
     345            eval "# line " . __LINE__ . " " . __FILE__ . "\nuse $package;"; 
    330346            return $package unless $@; 
    331             eval "use $pkg; $package->new;"; 
     347            eval "# line " . __LINE__ . " " . __FILE__ . "\nuse $pkg; $package->new;"; 
    332348            return $package unless $@; 
    333349        } 
     
    376392    } 
    377393 
     394    require MT::Meta; 
    378395    my $pkg = ref $class || $class; 
    379396    if (!$pkg->SUPER::properties->{meta_installed}) { 
     
    382399    } 
    383400 
    384     if (!$params->{columns} && !$params->{fields}) { 
     401    my $props = $class->properties; 
     402 
     403    if (!$params->{columns} && !$params->{fields} && !$params->{column_defs}) { 
    385404        return $class->error('No meta fields specified to install_meta'); 
    386405    } 
     
    388407    $params->{fields} ||= []; 
    389408    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; 
    398446} 
    399447 
     
    404452        key         => $class->datasource, 
    405453        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', 
    411465        }, 
     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        ) ], 
    412478        indexes => { 
    413479            $id_field => 1, 
    414480            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' ] }, 
    416488        }, 
    417489        primary_key => [ $class->datasource . '_id', 'type' ], 
     
    435507sub is_meta_column { 
    436508    my $obj = shift; 
    437     return if !$obj->properties->{meta_installed}; 
    438509    my ($field) = @_; 
    439510 
     511    my $props = $obj->properties; 
     512    return unless $props->{meta_installed}; 
     513 
    440514    my $meta = $obj->meta_pkg; 
    441     return 1 if $meta->properties->{fields}->{$field}; 
     515    return 1 if $props->{fields}{$field}; 
     516 
    442517    return; 
    443518} 
     
    445520sub meta_pkg { 
    446521    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 
    447527    my $meta = ref $class || $class; 
    448528    $meta .= '::Meta'; 
    449     return $meta; 
     529    return $props->{meta_pkg} = $meta; 
    450530} 
    451531 
     
    472552         : 2 == scalar @_  ? $obj->{__meta}->set($name, $value) 
    473553         : 1 == scalar @_  ? $obj->{__meta}->get($name) 
    474          :                   Carp::croak('TODO: implement returning a metadata hash') 
     554         :                   $obj->{__meta}->get_hash 
    475555         ; 
     556} 
     557 
     558sub meta_obj { 
     559    my $obj = shift; 
     560    return $obj->{__meta}; 
    476561} 
    477562 
     
    848933} 
    849934 
     935sub 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 
    850943sub remove_children { 
    851944    my $obj = shift; 
     
    861954    my $obj_id = $obj->id; 
    862955    for my $class (@classes) { 
    863         eval "use $class;"; 
     956        eval "# line " . __LINE__ . " " . __FILE__ . "\nuse $class;"; 
    864957        $class->remove({ $key => $obj_id }); 
    865958    } 
     
    9701063    $def{key} = 1 if ($props->{primary_key}) && ($props->{primary_key} eq $col); 
    9711064    $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}; 
    9731067    \%def; 
    9741068} 
     
    10501144} 
    10511145 
     1146sub meta_pkg { undef } 
     1147 
    10521148*table_name = \&MT::Object::table_name; 
    10531149*column_defs = \&MT::Object::column_defs; 
     
    10561152*__parse_defs = \&MT::Object::__parse_defs; 
    10571153*__parse_def = \&MT::Object::__parse_def; 
     1154*count = \&MT::Object::count; 
    10581155 
    10591156# TODO: copy this too 
  • branches/feature-narrow-tables/lib/MT/ObjectDriver/DDL/mysql.pm

    r1174 r1836  
    2222    my $field_prefix = $class->datasource; 
    2323    my $table_name = $class->table_name; 
     24    local $dbh->{RaiseError} = 0; 
    2425    my $sth = $dbh->prepare('SHOW INDEX FROM ' . $table_name) 
    2526        or return undef; 
  • branches/feature-narrow-tables/lib/MT/Template.pm

    r1535 r1836  
    3535        'build_type' => 'smallint', 
    3636        'build_interval' => 'integer', 
     37 
     38        # meta properties 
     39        'last_rebuild_time' => 'integer meta', 
     40        'page_layout' => 'string meta', 
     41        'include_with_ssi' => 'integer meta', 
    3742    }, 
    3843    indexes => { 
     
    5459    datasource => 'template', 
    5560    primary_key => 'id', 
    56 }); 
    57 __PACKAGE__->install_meta({ 
    58     columns => [ 
    59         'last_rebuild_time', 
    60         'page_layout', 
    61         'include_with_ssi', 
    62     ], 
    6361}); 
    6462__PACKAGE__->add_trigger('pre_remove' => \&pre_remove_children); 
  • branches/feature-narrow-tables/lib/MT/Upgrade.pm

    r1583 r1836  
    13161316        } 
    13171317    } 
     1318 
     1319    # handle schema updates for meta table 
     1320    if ($class->meta_pkg) { 
     1321        $self->check_type($type . ':meta'); 
     1322    } 
     1323 
    13181324    1; 
    13191325} 
  • branches/feature-narrow-tables/t/64-objectmeta.t

    r1603 r1836  
    55 
    66use Data::Dumper; 
    7 use Test::More tests => 18
     7use Test::More tests => 26
    88 
    99use MT; 
     
    1717require MT::Awesome; 
    1818require MT::Awesome::Image; 
     19 
    1920my $file  = MT::Awesome->new; 
    2021my $image = MT::Awesome::Image->new; 
     
    5253ok($image->has_meta('width'), 'subclass has metadata field that was declared for subclass'); 
    5354ok($image->has_meta('mime_type'), 'subclass has metadata field that was declared for superclass'); 
     55ok($image->mime_type('image/jpeg'), 'subclass object mime type set'); 
     56ok($image->save(), 'image object saved'); 
    5457 
     58ok($image->id, 'image object with metadata received id when saved'); 
     59 
     60my $image_2 = MT::Awesome->load($image->id); 
     61ok($image_2, 'subclass object could be loaded'); 
     62is($image_2->mime_type, 'image/jpeg', 'metadata value as retrieved with auto-installed method is correct on loaded image object'); 
     63 
     64ok(MT::Asset::Image->has_meta('image_width'), 'MT::Asset::Image has an image_width meta column.'); 
     65ok(MT::Entry->has_meta, 'MT::Entry has a meta support.'); 
     66ok(MT::Page->has_meta, 'MT::Page has a meta support.'); 
     67 
  • branches/feature-narrow-tables/t/plugins/Awesome/config.yaml

    r1603 r1836  
    44 
    55object_types: 
    6     blog_meta:     MT::Blog::Meta 
    76    awesome:       MT::Awesome 
    8     awesome_meta:  MT::Awesome::Meta 
    97    awesome_image: MT::Awesome::Image 
    108 
  • branches/feature-narrow-tables/t/plugins/Awesome/lib/MT/Awesome.pm

    r1603 r1836  
    99        title => 'string(255)', 
    1010        file => 'string(255)', 
     11        mime_type => 'string meta', 
    1112    }, 
    1213    meta => 1, 
     
    1516    primary_key => 'id', 
    1617}); 
    17 __PACKAGE__->install_meta({ 
    18     columns => [ 'mime_type' ] 
    19 }); 
    2018 
    21191; 
  • branches/feature-narrow-tables/t/plugins/Awesome/lib/MT/Awesome/Image.pm

    r1603 r1836  
    1  
    21package MT::Awesome::Image; 
    32 
     
    65__PACKAGE__->install_properties({ 
    76    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    }, 
    1111}); 
    1212