From ed53ecda0546d6c639fa3d227a59ace4d57b81a5 Mon Sep 17 00:00:00 2001 From: Upasana Date: Mon, 5 Mar 2018 00:58:41 +0100 Subject: Bug 1273381 - Improve bugzilla object performance by using Class::XSAccessor for object accessors --- Bugzilla/Attachment.pm | 7 ++ Bugzilla/Bug.pm | 8 ++ Bugzilla/BugUrl.pm | 7 ++ Bugzilla/BugUserLastVisit.pm | 8 +- Bugzilla/Classification.pm | 11 ++ Bugzilla/Comment.pm | 7 ++ Bugzilla/Comment/TagWeights.pm | 13 ++- Bugzilla/Component.pm | 7 ++ Bugzilla/Field.pm | 11 ++ Bugzilla/Field/Choice.pm | 10 ++ Bugzilla/Flag.pm | 7 +- Bugzilla/FlagType.pm | 9 +- Bugzilla/Group.pm | 7 ++ Bugzilla/Keyword.pm | 7 ++ Bugzilla/Milestone.pm | 8 +- Bugzilla/Object.pm | 3 - Bugzilla/Product.pm | 7 ++ Bugzilla/Search/Recent.pm | 11 +- Bugzilla/Search/Saved.pm | 7 ++ Bugzilla/User.pm | 9 +- Bugzilla/User/APIKey.pm | 12 ++- Bugzilla/User/Session.pm | 9 +- Bugzilla/Version.pm | 8 ++ Bugzilla/Whine.pm | 8 ++ Bugzilla/Whine/Query.pm | 9 +- Bugzilla/Whine/Schedule.pm | 7 ++ extensions/BugmailFilter/lib/Filter.pm | 6 ++ extensions/MyDashboard/lib/BugInterest.pm | 8 +- extensions/Push/lib/BacklogMessage.pm | 7 ++ extensions/Push/lib/Backoff.pm | 7 ++ extensions/Push/lib/LogEntry.pm | 7 ++ extensions/Push/lib/Message.pm | 6 ++ extensions/Push/lib/Option.pm | 9 +- extensions/Review/lib/FlagStateActivity.pm | 10 ++ extensions/TrackingFlags/lib/Flag.pm | 11 +- extensions/TrackingFlags/lib/Flag/Bug.pm | 7 ++ extensions/TrackingFlags/lib/Flag/Value.pm | 9 +- extensions/TrackingFlags/lib/Flag/Visibility.pm | 7 ++ t/bugzilla-objects-def.t | 136 ++++++++++++++++++++++++ 39 files changed, 427 insertions(+), 20 deletions(-) create mode 100644 t/bugzilla-objects-def.t diff --git a/Bugzilla/Attachment.pm b/Bugzilla/Attachment.pm index 0bdb50c9a..4498fedf2 100644 --- a/Bugzilla/Attachment.pm +++ b/Bugzilla/Attachment.pm @@ -113,6 +113,13 @@ use constant UPDATE_VALIDATORS => { #### Accessors ###### ############################### +use Class::XSAccessor { + accessors => { + id => __PACKAGE__->ID_FIELD, + name => __PACKAGE__->NAME_FIELD, + }, +}; + =pod =head2 Instance Properties diff --git a/Bugzilla/Bug.pm b/Bugzilla/Bug.pm index ee48ed7a2..5e45b67b1 100644 --- a/Bugzilla/Bug.pm +++ b/Bugzilla/Bug.pm @@ -54,7 +54,15 @@ my %CLEANUP; use constant DB_TABLE => 'bugs'; use constant ID_FIELD => 'bug_id'; + use constant NAME_FIELD => 'alias'; +use Class::XSAccessor { + accessors => { + id => __PACKAGE__->ID_FIELD, + name => __PACKAGE__->NAME_FIELD, + }, +}; + use constant LIST_ORDER => ID_FIELD; # Bugs have their own auditing table, bugs_activity. use constant AUDIT_CREATES => 0; diff --git a/Bugzilla/BugUrl.pm b/Bugzilla/BugUrl.pm index 4724ae71a..9e5750c75 100644 --- a/Bugzilla/BugUrl.pm +++ b/Bugzilla/BugUrl.pm @@ -74,6 +74,13 @@ use constant SUB_CLASSES => qw( #### Accessors ###### ############################### +use Class::XSAccessor { + accessors => { + name => __PACKAGE__->NAME_FIELD, + id => __PACKAGE__->ID_FIELD, + }, +}; + sub class { return $_[0]->{class} } sub bug_id { return $_[0]->{bug_id} } diff --git a/Bugzilla/BugUserLastVisit.pm b/Bugzilla/BugUserLastVisit.pm index f40ea17d3..635cb4392 100644 --- a/Bugzilla/BugUserLastVisit.pm +++ b/Bugzilla/BugUserLastVisit.pm @@ -30,11 +30,17 @@ use constant { AUDIT_CREATES => 0, AUDIT_REMOVES => 0, USE_MEMCACHED => 0 }; +use Class::XSAccessor { + accessors => { + name => __PACKAGE__->NAME_FIELD, + id => __PACKAGE__->ID_FIELD, + }, +}; + ##################################################################### # Provide accessors for our columns ##################################################################### -sub id { return $_[0]->{id} } sub bug_id { return $_[0]->{bug_id} } sub user_id { return $_[0]->{user_id} } sub last_visit_ts { return $_[0]->{last_visit_ts} } diff --git a/Bugzilla/Classification.pm b/Bugzilla/Classification.pm index a931767d2..e34f8dde8 100644 --- a/Bugzilla/Classification.pm +++ b/Bugzilla/Classification.pm @@ -47,6 +47,17 @@ use constant VALIDATORS => { sortkey => \&_check_sortkey, }; +############################### +#### Accessors ###### +############################### + +use Class::XSAccessor { + accessors => { + id => __PACKAGE__->ID_FIELD, + name => __PACKAGE__->NAME_FIELD, + }, +}; + ############################### #### Constructors ##### ############################### diff --git a/Bugzilla/Comment.pm b/Bugzilla/Comment.pm index f9a6f7d3a..86094db59 100644 --- a/Bugzilla/Comment.pm +++ b/Bugzilla/Comment.pm @@ -228,6 +228,13 @@ sub preload { #### Accessors ###### ############################### +use Class::XSAccessor { + accessors => { + id => __PACKAGE__->ID_FIELD, + name => __PACKAGE__->NAME_FIELD, + }, +}; + sub already_wrapped { return $_[0]->{'already_wrapped'}; } sub body { return $_[0]->{'thetext'}; } sub bug_id { return $_[0]->{'bug_id'}; } diff --git a/Bugzilla/Comment/TagWeights.pm b/Bugzilla/Comment/TagWeights.pm index 4919244ce..ba7bdfc5b 100644 --- a/Bugzilla/Comment/TagWeights.pm +++ b/Bugzilla/Comment/TagWeights.pm @@ -39,7 +39,18 @@ use constant VALIDATORS => { }; # There's no gain to caching these objects use constant USE_MEMCACHED => 0; -sub tag { return $_[0]->{'tag'} } +############################### +#### Accessors ###### +############################### + +use Class::XSAccessor { + accessors => { + id => __PACKAGE__->ID_FIELD, + tag => __PACKAGE__->NAME_FIELD, + name => __PACKAGE__->NAME_FIELD, + }, +}; + sub weight { return $_[0]->{'weight'} } sub set_weight { $_[0]->set('weight', $_[1]); } diff --git a/Bugzilla/Component.pm b/Bugzilla/Component.pm index 78e144a55..7e294ba74 100644 --- a/Bugzilla/Component.pm +++ b/Bugzilla/Component.pm @@ -447,6 +447,13 @@ sub is_active { return $_[0]->{'isactive'}; } sub triage_owner_id { return $_[0]->{'triage_owner_id'} } +use Class::XSAccessor { + accessors => { + id => __PACKAGE__->ID_FIELD, + name => __PACKAGE__->NAME_FIELD, + }, +}; + ############################################## # Implement Bugzilla::Field::ChoiceInterface # ############################################## diff --git a/Bugzilla/Field.pm b/Bugzilla/Field.pm index 837e1c0de..d18356d66 100644 --- a/Bugzilla/Field.pm +++ b/Bugzilla/Field.pm @@ -432,6 +432,17 @@ sub _check_reverse_desc { sub _check_is_mandatory { return $_[1] ? 1 : 0; } +############################### +#### Accessors ###### +############################### + +use Class::XSAccessor { + accessors => { + id => __PACKAGE__->ID_FIELD, + name => __PACKAGE__->NAME_FIELD, + }, +}; + =pod =head2 Instance Properties diff --git a/Bugzilla/Field/Choice.pm b/Bugzilla/Field/Choice.pm index 10f8f38e6..9dd7b3ccf 100644 --- a/Bugzilla/Field/Choice.pm +++ b/Bugzilla/Field/Choice.pm @@ -119,6 +119,16 @@ sub new { $class->SUPER::new(@_); } +############################### +#### Accessors ###### +############################### + +use Class::XSAccessor { + accessors => { + id => __PACKAGE__->ID_FIELD, + name => __PACKAGE__->NAME_FIELD, + }, +}; ######################### # Database Manipulation # ######################### diff --git a/Bugzilla/Flag.pm b/Bugzilla/Flag.pm index 625794974..8ace32be6 100644 --- a/Bugzilla/Flag.pm +++ b/Bugzilla/Flag.pm @@ -104,6 +104,12 @@ use constant UPDATE_VALIDATORS => { #### Accessors ###### ############################### +use Class::XSAccessor { + accessors => { + id => __PACKAGE__->ID_FIELD, + }, +}; + =head2 METHODS =over @@ -140,7 +146,6 @@ Returns the timestamp when the flag was last modified. =cut -sub id { return $_[0]->{'id'}; } sub name { return $_[0]->type->name; } sub type_id { return $_[0]->{'type_id'}; } sub bug_id { return $_[0]->{'bug_id'}; } diff --git a/Bugzilla/FlagType.pm b/Bugzilla/FlagType.pm index c973ea662..6aaa79bd1 100644 --- a/Bugzilla/FlagType.pm +++ b/Bugzilla/FlagType.pm @@ -210,6 +210,13 @@ sub update { #### Accessors ###### ############################### +use Class::XSAccessor { + accessors => { + id => __PACKAGE__->ID_FIELD, + name => __PACKAGE__->NAME_FIELD, + }, +}; + =head2 METHODS =over @@ -262,8 +269,6 @@ Returns the sortkey of the flagtype. =cut -sub id { return $_[0]->{'id'}; } -sub name { return $_[0]->{'name'}; } sub description { return $_[0]->{'description'}; } sub cc_list { return $_[0]->{'cc_list'}; } sub target_type { return $_[0]->{'target_type'} eq 'b' ? 'bug' : 'attachment'; } diff --git a/Bugzilla/Group.pm b/Bugzilla/Group.pm index fe2a90c05..6d47f1ee0 100644 --- a/Bugzilla/Group.pm +++ b/Bugzilla/Group.pm @@ -71,6 +71,13 @@ use constant GROUP_PARAMS => qw(chartgroup insidergroup timetrackinggroup #### Accessors ###### ############################### +use Class::XSAccessor { + accessors => { + id => __PACKAGE__->ID_FIELD, + name => __PACKAGE__->NAME_FIELD, + }, +}; + sub description { return $_[0]->{'description'}; } sub is_bug_group { return $_[0]->{'isbuggroup'}; } sub user_regexp { return $_[0]->{'userregexp'}; } diff --git a/Bugzilla/Keyword.pm b/Bugzilla/Keyword.pm index 61038f602..b078294d8 100644 --- a/Bugzilla/Keyword.pm +++ b/Bugzilla/Keyword.pm @@ -47,6 +47,13 @@ use constant UPDATE_COLUMNS => qw( #### Accessors ###### ############################### +use Class::XSAccessor { + accessors => { + id => __PACKAGE__->ID_FIELD, + name => __PACKAGE__->NAME_FIELD, + }, +}; + sub description { return $_[0]->{'description'}; } sub bug_count { diff --git a/Bugzilla/Milestone.pm b/Bugzilla/Milestone.pm index 2f10e1f00..078074dc4 100644 --- a/Bugzilla/Milestone.pm +++ b/Bugzilla/Milestone.pm @@ -227,7 +227,13 @@ sub bug_count { ##### Accessors ###### ################################ -sub name { return $_[0]->{'value'}; } +use Class::XSAccessor { + accessors => { + id => __PACKAGE__->ID_FIELD, + name => __PACKAGE__->NAME_FIELD, + }, +}; + sub product_id { return $_[0]->{'product_id'}; } sub sortkey { return $_[0]->{'sortkey'}; } sub is_active { return $_[0]->{'isactive'}; } diff --git a/Bugzilla/Object.pm b/Bugzilla/Object.pm index 00afbe19f..8660fa551 100644 --- a/Bugzilla/Object.pm +++ b/Bugzilla/Object.pm @@ -445,9 +445,6 @@ sub _do_list_select { #### Accessors ###### ############################### -sub id { return $_[0]->{$_[0]->ID_FIELD}; } -sub name { return $_[0]->{$_[0]->NAME_FIELD}; } - ############################### #### Methods #### ############################### diff --git a/Bugzilla/Product.pm b/Bugzilla/Product.pm index 3ac1692f0..16b753fa8 100644 --- a/Bugzilla/Product.pm +++ b/Bugzilla/Product.pm @@ -831,6 +831,13 @@ sub classification { #### Accessors ###### ############################### +use Class::XSAccessor { + accessors => { + id => __PACKAGE__->ID_FIELD, + name => __PACKAGE__->NAME_FIELD, + }, +}; + sub allows_unconfirmed { return $_[0]->{'allows_unconfirmed'}; } sub description { return $_[0]->{'description'}; } sub is_active { return $_[0]->{'isactive'}; } diff --git a/Bugzilla/Search/Recent.pm b/Bugzilla/Search/Recent.pm index a5d9e2417..f99cda84f 100644 --- a/Bugzilla/Search/Recent.pm +++ b/Bugzilla/Search/Recent.pm @@ -27,6 +27,8 @@ use constant LIST_ORDER => 'id DESC'; use constant AUDIT_CREATES => 0; use constant AUDIT_UPDATES => 0; use constant AUDIT_REMOVES => 0; +use constant USER_ID_FIELD => 'user_id'; +use constant ID_FIELD => 'id'; use constant DB_COLUMNS => qw( id @@ -115,9 +117,16 @@ sub new_from_cookie { # Simple Accessors # #################### +use Class::XSAccessor { + accessors => { + user_id => __PACKAGE__->USER_ID_FIELD, + id => __PACKAGE__->ID_FIELD, + name => __PACKAGE__->NAME_FIELD, + }, +}; + sub bug_list { return [split(',', $_[0]->{'bug_list'})]; } sub list_order { return $_[0]->{'list_order'}; } -sub user_id { return $_[0]->{'user_id'}; } ############ # Mutators # diff --git a/Bugzilla/Search/Saved.pm b/Bugzilla/Search/Saved.pm index 1511cd87b..d57dfa35b 100644 --- a/Bugzilla/Search/Saved.pm +++ b/Bugzilla/Search/Saved.pm @@ -287,6 +287,13 @@ sub shared_with_users { # Simple Accessors # #################### +use Class::XSAccessor { + accessors => { + id => __PACKAGE__->ID_FIELD, + name => __PACKAGE__->NAME_FIELD, + }, +}; + sub url { return $_[0]->{'query'}; } sub user { diff --git a/Bugzilla/User.pm b/Bugzilla/User.pm index dc8f60565..3a0810b64 100644 --- a/Bugzilla/User.pm +++ b/Bugzilla/User.pm @@ -86,8 +86,16 @@ sub DB_COLUMNS { use constant NAME_FIELD => 'login_name'; use constant ID_FIELD => 'userid'; +use constant REAL_NAME_FIELD => 'realname'; use constant LIST_ORDER => NAME_FIELD; +use Class::XSAccessor { + accessors => { + id => __PACKAGE__->ID_FIELD, + name => __PACKAGE__->REAL_NAME_FIELD, + }, +}; + use constant VALIDATORS => { cryptpassword => \&_check_password, disable_mail => \&_check_disable_mail, @@ -640,7 +648,6 @@ sub update_last_seen_date { ################################################################################ # Accessors for user attributes -sub name { $_[0]->{realname}; } sub login { $_[0]->{login_name}; } sub extern_id { $_[0]->{extern_id}; } sub email { $_[0]->login . Bugzilla->params->{'emailsuffix'}; } diff --git a/Bugzilla/User/APIKey.pm b/Bugzilla/User/APIKey.pm index c1a4ed572..62121382b 100644 --- a/Bugzilla/User/APIKey.pm +++ b/Bugzilla/User/APIKey.pm @@ -50,7 +50,17 @@ use constant { AUDIT_CREATES => 0, USE_MEMCACHED => 0 }; # Accessors -sub id { return $_[0]->{id} } +############################### +#### Accessors ###### +############################### + +use Class::XSAccessor { + accessors => { + id => __PACKAGE__->ID_FIELD, + name => __PACKAGE__->NAME_FIELD, + }, +}; + sub user_id { return $_[0]->{user_id} } sub api_key { return $_[0]->{api_key} } sub app_id { return $_[0]->{app_id} } diff --git a/Bugzilla/User/Session.pm b/Bugzilla/User/Session.pm index 56e1cd07a..299ed26f7 100644 --- a/Bugzilla/User/Session.pm +++ b/Bugzilla/User/Session.pm @@ -39,7 +39,14 @@ use constant { AUDIT_CREATES => 0, USE_MEMCACHED => 0 }; # Accessors -sub id { return $_[0]->{id} } + +use Class::XSAccessor { + accessors => { + id => __PACKAGE__->ID_FIELD, + name => __PACKAGE__->NAME_FIELD, + }, +}; + sub userid { return $_[0]->{userid} } sub cookie { return $_[0]->{cookie} } sub lastused { return $_[0]->{lastused} } diff --git a/Bugzilla/Version.pm b/Bugzilla/Version.pm index a078cb4fc..4b509a60e 100644 --- a/Bugzilla/Version.pm +++ b/Bugzilla/Version.pm @@ -28,6 +28,7 @@ use constant DEFAULT_VERSION => 'unspecified'; use constant DB_TABLE => 'versions'; use constant NAME_FIELD => 'value'; + # This is "id" because it has to be filled in and id is probably the fastest. # We do a custom sort in new_from_list below. use constant LIST_ORDER => 'id'; @@ -147,6 +148,13 @@ sub remove_from_db { ##### Accessors #### ############################### +use Class::XSAccessor { + accessors => { + id => __PACKAGE__->ID_FIELD, + name => __PACKAGE__->NAME_FIELD, + }, +}; + sub product_id { return $_[0]->{'product_id'}; } sub is_active { return $_[0]->{'isactive'}; } diff --git a/Bugzilla/Whine.pm b/Bugzilla/Whine.pm index c4301b4f6..e00f9118b 100644 --- a/Bugzilla/Whine.pm +++ b/Bugzilla/Whine.pm @@ -39,6 +39,14 @@ use constant LIST_ORDER => 'id'; #################### # Simple Accessors # #################### + +use Class::XSAccessor { + accessors => { + id => __PACKAGE__->ID_FIELD, + name => __PACKAGE__->NAME_FIELD, + }, +}; + sub subject { return $_[0]->{'subject'}; } sub body { return $_[0]->{'body'}; } sub mail_if_no_bugs { return $_[0]->{'mailifnobugs'}; } diff --git a/Bugzilla/Whine/Query.pm b/Bugzilla/Whine/Query.pm index 6ea91cc51..885737114 100644 --- a/Bugzilla/Whine/Query.pm +++ b/Bugzilla/Whine/Query.pm @@ -33,15 +33,22 @@ use constant DB_COLUMNS => qw( use constant NAME_FIELD => 'id'; use constant LIST_ORDER => 'sortkey'; +use constant QUERY_NAME_FIELD => 'query_name'; #################### # Simple Accessors # #################### +use Class::XSAccessor { + accessors => { + id => __PACKAGE__->ID_FIELD, + name => __PACKAGE__->QUERY_NAME_FIELD, + }, +}; + sub eventid { return $_[0]->{'eventid'}; } sub sortkey { return $_[0]->{'sortkey'}; } sub one_email_per_bug { return $_[0]->{'onemailperbug'}; } sub title { return $_[0]->{'title'}; } -sub name { return $_[0]->{'query_name'}; } 1; diff --git a/Bugzilla/Whine/Schedule.pm b/Bugzilla/Whine/Schedule.pm index 017b744e5..725920cd7 100644 --- a/Bugzilla/Whine/Schedule.pm +++ b/Bugzilla/Whine/Schedule.pm @@ -45,6 +45,13 @@ use constant LIST_ORDER => 'id'; #################### # Simple Accessors # #################### +use Class::XSAccessor { + accessors => { + id => __PACKAGE__->ID_FIELD, + name => __PACKAGE__->NAME_FIELD, + }, +}; + sub eventid { return $_[0]->{'eventid'}; } sub run_day { return $_[0]->{'run_day'}; } sub run_time { return $_[0]->{'run_time'}; } diff --git a/extensions/BugmailFilter/lib/Filter.pm b/extensions/BugmailFilter/lib/Filter.pm index 7f2f4cb87..e7e339cd4 100644 --- a/extensions/BugmailFilter/lib/Filter.pm +++ b/extensions/BugmailFilter/lib/Filter.pm @@ -54,6 +54,12 @@ use constant AUDIT_REMOVES => 0; use constant USE_MEMCACHED => 0; # getters +use Class::XSAccessor { + accessors => { + id => __PACKAGE__->ID_FIELD, + name => __PACKAGE__->NAME_FIELD, + }, +}; sub user { my ($self) = @_; diff --git a/extensions/MyDashboard/lib/BugInterest.pm b/extensions/MyDashboard/lib/BugInterest.pm index cf33900c5..2e8655261 100644 --- a/extensions/MyDashboard/lib/BugInterest.pm +++ b/extensions/MyDashboard/lib/BugInterest.pm @@ -34,7 +34,13 @@ use constant { AUDIT_CREATES => 0, # Provide accessors for our columns ##################################################################### -sub id { return $_[0]->{id} } +use Class::XSAccessor { + accessors => { + id => __PACKAGE__->ID_FIELD, + name => __PACKAGE__->NAME_FIELD, + }, +}; + sub bug_id { return $_[0]->{bug_id} } sub user_id { return $_[0]->{user_id} } sub modification_time { return $_[0]->{modification_time} } diff --git a/extensions/Push/lib/BacklogMessage.pm b/extensions/Push/lib/BacklogMessage.pm index 28b17bae3..7c248a501 100644 --- a/extensions/Push/lib/BacklogMessage.pm +++ b/extensions/Push/lib/BacklogMessage.pm @@ -79,6 +79,13 @@ sub create_from_message { # accessors # +use Class::XSAccessor { + accessors => { + id => __PACKAGE__->ID_FIELD, + name => __PACKAGE__->NAME_FIELD, + }, +}; + sub message_id { return $_[0]->{'message_id'} } sub push_ts { return $_[0]->{'push_ts'}; } sub payload { return $_[0]->{'payload'}; } diff --git a/extensions/Push/lib/Backoff.pm b/extensions/Push/lib/Backoff.pm index f0116a2a7..d0de1310d 100644 --- a/extensions/Push/lib/Backoff.pm +++ b/extensions/Push/lib/Backoff.pm @@ -47,6 +47,13 @@ use constant LIST_ORDER => 'next_attempt_ts'; # accessors # +use Class::XSAccessor { + accessors => { + id => __PACKAGE__->ID_FIELD, + name => __PACKAGE__->NAME_FIELD, + }, +}; + sub connector { return $_[0]->{'connector'}; } sub next_attempt_ts { return $_[0]->{'next_attempt_ts'}; } sub attempts { return $_[0]->{'attempts'}; } diff --git a/extensions/Push/lib/LogEntry.pm b/extensions/Push/lib/LogEntry.pm index f4e894b94..2d45b9ee1 100644 --- a/extensions/Push/lib/LogEntry.pm +++ b/extensions/Push/lib/LogEntry.pm @@ -48,6 +48,13 @@ use constant LIST_ORDER => 'processed_ts DESC'; # accessors # +use Class::XSAccessor { + accessors => { + id => __PACKAGE__->ID_FIELD, + name => __PACKAGE__->NAME_FIELD, + }, +}; + sub message_id { return $_[0]->{'message_id'}; } sub change_set { return $_[0]->{'change_set'}; } sub routing_key { return $_[0]->{'routing_key'}; } diff --git a/extensions/Push/lib/Message.pm b/extensions/Push/lib/Message.pm index 1beb18ef0..d8a7f7a26 100644 --- a/extensions/Push/lib/Message.pm +++ b/extensions/Push/lib/Message.pm @@ -61,6 +61,12 @@ sub create_from_transient { # # accessors # +use Class::XSAccessor { + accessors => { + id => __PACKAGE__->ID_FIELD, + name => __PACKAGE__->NAME_FIELD, + }, +}; sub push_ts { return $_[0]->{'push_ts'}; } sub payload { return $_[0]->{'payload'}; } diff --git a/extensions/Push/lib/Option.pm b/extensions/Push/lib/Option.pm index a08e4c11d..c2e23d513 100644 --- a/extensions/Push/lib/Option.pm +++ b/extensions/Push/lib/Option.pm @@ -35,13 +35,18 @@ use constant VALIDATORS => { connector => \&_check_connector, }; use constant LIST_ORDER => 'connector'; - +use constant NAME_FIELD => 'option_name'; # # accessors # +use Class::XSAccessor { + accessors => { + id => __PACKAGE__->ID_FIELD, + name => __PACKAGE__->NAME_FIELD, + }, +}; sub connector { return $_[0]->{'connector'}; } -sub name { return $_[0]->{'option_name'}; } sub value { return $_[0]->{'option_value'}; } # diff --git a/extensions/Review/lib/FlagStateActivity.pm b/extensions/Review/lib/FlagStateActivity.pm index 35da42351..fcc799a79 100644 --- a/extensions/Review/lib/FlagStateActivity.pm +++ b/extensions/Review/lib/FlagStateActivity.pm @@ -35,6 +35,16 @@ use constant DB_COLUMNS => qw( status ); +############################### +#### Accessors ###### +############################### + +use Class::XSAccessor { + accessors => { + id => __PACKAGE__->ID_FIELD, + name => __PACKAGE__->NAME_FIELD, + }, +}; sub _check_param_required { my ($param) = @_; diff --git a/extensions/TrackingFlags/lib/Flag.pm b/extensions/TrackingFlags/lib/Flag.pm index 82c0314e3..f54e42a7a 100644 --- a/extensions/TrackingFlags/lib/Flag.pm +++ b/extensions/TrackingFlags/lib/Flag.pm @@ -376,8 +376,16 @@ sub set_is_active { $_[0]->set('is_active', $_[1]); } #### Accessors #### ############################### +use constant ID_FIELD => 'field_id'; + +use Class::XSAccessor { + accessors => { + id => __PACKAGE__->ID_FIELD, + name => __PACKAGE__->NAME_FIELD, + }, +}; + sub flag_id { return $_[0]->{'id'}; } -sub name { return $_[0]->{'name'}; } sub description { return $_[0]->{'description'}; } sub flag_type { return $_[0]->{'type'}; } sub sortkey { return $_[0]->{'sortkey'}; } @@ -460,7 +468,6 @@ sub activity_count { # Here we return 'field_id' instead of the real # id as we want other Bugzilla code to treat this # as a Bugzilla::Field object in certain places. -sub id { return $_[0]->{'field_id'}; } sub type { return FIELD_TYPE_EXTENSION; } sub legal_values { return $_[0]->values; } sub custom { return 1; } diff --git a/extensions/TrackingFlags/lib/Flag/Bug.pm b/extensions/TrackingFlags/lib/Flag/Bug.pm index 7be661720..62f103ee5 100644 --- a/extensions/TrackingFlags/lib/Flag/Bug.pm +++ b/extensions/TrackingFlags/lib/Flag/Bug.pm @@ -169,6 +169,13 @@ sub set_value { $_[0]->set('value', $_[1]); } #### Accessors #### ############################### +use Class::XSAccessor { + accessors => { + id => __PACKAGE__->ID_FIELD, + name => __PACKAGE__->NAME_FIELD, + }, +}; + sub tracking_flag_id { return $_[0]->{'tracking_flag_id'}; } sub bug_id { return $_[0]->{'bug_id'}; } sub value { return $_[0]->{'value'}; } diff --git a/extensions/TrackingFlags/lib/Flag/Value.pm b/extensions/TrackingFlags/lib/Flag/Value.pm index 4f2aacc3a..c1b3ef4f1 100644 --- a/extensions/TrackingFlags/lib/Flag/Value.pm +++ b/extensions/TrackingFlags/lib/Flag/Value.pm @@ -35,6 +35,7 @@ use constant DB_COLUMNS => qw( ); use constant LIST_ORDER => 'sortkey'; +use constant NAME_FIELD => 'value'; use constant UPDATE_COLUMNS => qw( setter_group_id @@ -111,6 +112,13 @@ sub set_comment { $_[0]->set('comment', $_[1]); } #### Accessors #### ############################### +use Class::XSAccessor { + accessors => { + id => __PACKAGE__->ID_FIELD, + name => __PACKAGE__->NAME_FIELD, + }, +}; + sub tracking_flag_id { return $_[0]->{'tracking_flag_id'}; } sub setter_group_id { return $_[0]->{'setter_group_id'}; } sub value { return $_[0]->{'value'}; } @@ -140,7 +148,6 @@ sub setter_group { ## Compatibility with Bugzilla::Field ## ######################################## -sub name { return $_[0]->{'value'}; } sub is_visible_on_bug { return 1; } 1; diff --git a/extensions/TrackingFlags/lib/Flag/Visibility.pm b/extensions/TrackingFlags/lib/Flag/Visibility.pm index 878c16f99..a16ddfe75 100644 --- a/extensions/TrackingFlags/lib/Flag/Visibility.pm +++ b/extensions/TrackingFlags/lib/Flag/Visibility.pm @@ -147,6 +147,13 @@ sub _check_component { #### Accessors #### ############################### +use Class::XSAccessor { + accessors => { + id => __PACKAGE__->ID_FIELD, + name => __PACKAGE__->NAME_FIELD, + }, +}; + sub tracking_flag_id { return $_[0]->{'tracking_flag_id'}; } sub product_id { return $_[0]->{'product_id'}; } sub component_id { return $_[0]->{'component_id'}; } diff --git a/t/bugzilla-objects-def.t b/t/bugzilla-objects-def.t new file mode 100644 index 000000000..6ba33f450 --- /dev/null +++ b/t/bugzilla-objects-def.t @@ -0,0 +1,136 @@ +#!/usr/bin/perl +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This Source Code Form is "Incompatible With Secondary Licenses", as +# defined by the Mozilla Public License, v. 2.0. +use 5.10.1; +use strict; +use warnings; +use autodie; +use lib qw(. lib local/lib/perl5); +use constant HAVE_DATABASE => 0; + +use if HAVE_DATABASE, 'Bugzilla'; +BEGIN { + if (HAVE_DATABASE) { + Bugzilla->extensions + } +} +use Bugzilla::DB::Schema; +use Module::Runtime qw(require_module); +use Test::More; + +# These are all subclasses of Bugzilla::Object +my @packages = qw( + Bugzilla::Attachment + Bugzilla::Bug + Bugzilla::BugUrl + Bugzilla::BugUserLastVisit + Bugzilla::Classification + Bugzilla::Comment + Bugzilla::Comment::TagWeights + Bugzilla::Component + Bugzilla::Extension::BugmailFilter::Filter + Bugzilla::Extension::MyDashboard::BugInterest + Bugzilla::Extension::Push::BacklogMessage + Bugzilla::Extension::Push::Backoff + Bugzilla::Extension::Push::LogEntry + Bugzilla::Extension::Push::Message + Bugzilla::Extension::Push::Option + Bugzilla::Extension::Review::FlagStateActivity + Bugzilla::Extension::TrackingFlags::Flag + Bugzilla::Extension::TrackingFlags::Flag::Bug + Bugzilla::Extension::TrackingFlags::Flag::Value + Bugzilla::Extension::TrackingFlags::Flag::Visibility + Bugzilla::Field + Bugzilla::Field::Choice + Bugzilla::Flag + Bugzilla::FlagType + Bugzilla::Group + Bugzilla::Keyword + Bugzilla::Milestone + Bugzilla::Product + Bugzilla::Search::Recent + Bugzilla::Search::Saved + Bugzilla::User + Bugzilla::User::APIKey + Bugzilla::User::Session + Bugzilla::Version + Bugzilla::Whine + Bugzilla::Whine::Query + Bugzilla::Whine::Schedule +); + +# some of the subclasses have things to skip. +# 'name' means skip checking the name() method +# 'id' means skip checking the id() method +# 'db_name' means NAME_FIELD isn't a database field. +my %skip = ( + 'Bugzilla::Attachment' => { db_name => 1 }, + 'Bugzilla::Comment' => { db_name => 1 }, + 'Bugzilla::Extension::BugmailFilter::Filter' => { db_name => 1 }, + 'Bugzilla::Extension::Push::BacklogMessage' => { db_name => 1 }, + 'Bugzilla::Extension::Push::Backoff' => { db_name => 1 }, + 'Bugzilla::Extension::Push::Message' => { db_name => 1 }, + 'Bugzilla::Extension::Push::Option' => { name => 1 }, + 'Bugzilla::Extension::Review::FlagStateActivity' => { db_name => 1 }, + 'Bugzilla::Extension::TrackingFlags::Flag' => { id => 1 }, + 'Bugzilla::Extension::TrackingFlags::Flag::Bug' => { db_name => 1 }, + 'Bugzilla::Extension::TrackingFlags::Flag::Value' => { name => 1 }, + 'Bugzilla::Extension::TrackingFlags::Flag::Visibility' => { db_name => 1 }, + 'Bugzilla::Flag' => { name => 1, id => 1 }, + 'Bugzilla::Search::Recent' => { db_name => 1 }, + 'Bugzilla::User' => { name => 1 }, + 'Bugzilla::Whine' => { db_name => 1 }, + 'Bugzilla::Whine::Query' => { name => 1 }, +); + +# this is kind of evil, but I want a copy +# of the schema without accessing a real DB. +my $schema = Bugzilla::DB::Schema::ABSTRACT_SCHEMA; +if (HAVE_DATABASE) { + Bugzilla::Hook::process( 'db_schema_abstract_schema', { schema => $schema } ); +} + +foreach my $package (@packages) { + next if $package =~ /^Bugzilla::Extension::/ && !HAVE_DATABASE; + require_module($package); + isa_ok($package, 'Bugzilla::Object'); + can_ok($package, qw( id name ID_FIELD NAME_FIELD)); + my $fake = bless {}, $package; + my ($NAME_FIELD, $ID_FIELD); + unless ($skip{$package}{id}) { + $ID_FIELD = $package->ID_FIELD; + $fake->{ $package->ID_FIELD } = 42; + my $ok = eval { + is($fake->id, 42, "$package->id is ID_FIELD"); + 1; + }; + ok($ok, "$package->id is not a fatal error"); + } + unless ($skip{$package}{name}) { + $NAME_FIELD = $package->NAME_FIELD; + $fake->{ $package->NAME_FIELD } = 'camel'; + my $ok = eval { + is($fake->name, 'camel', "$package->name is NAME_FIELD"); + 1; + }; + ok($ok, "$package->name is not a fatal error"); + } + if ($package->can('DB_TABLE')) { + my $table = $package->DB_TABLE; + my $table_def = $schema->{$table}; + my %fields = @{ $table_def->{FIELDS} }; + ok($table_def, "$package has a table definition"); + if ($ID_FIELD and not $skip{$package}{db_id}) { + ok($fields{ $ID_FIELD }, "$package table $table has column named by $ID_FIELD"); + } + if ($NAME_FIELD and not $skip{$package}{db_name}) { + ok($fields{ $NAME_FIELD }, "$package table $table has column named $NAME_FIELD"); + } + } +} + +done_testing; -- cgit v1.2.3-24-g4f1b