]> git.ipfire.org Git - thirdparty/bugzilla.git/commitdiff
Bug 1273381 - Improve bugzilla object performance by using Class::XSAccessor for...
authorUpasana <upasana-me@users.noreply.github.com>
Sun, 4 Mar 2018 23:58:41 +0000 (00:58 +0100)
committerDylan William Hardison <dylan@hardison.net>
Sun, 4 Mar 2018 23:58:41 +0000 (18:58 -0500)
39 files changed:
Bugzilla/Attachment.pm
Bugzilla/Bug.pm
Bugzilla/BugUrl.pm
Bugzilla/BugUserLastVisit.pm
Bugzilla/Classification.pm
Bugzilla/Comment.pm
Bugzilla/Comment/TagWeights.pm
Bugzilla/Component.pm
Bugzilla/Field.pm
Bugzilla/Field/Choice.pm
Bugzilla/Flag.pm
Bugzilla/FlagType.pm
Bugzilla/Group.pm
Bugzilla/Keyword.pm
Bugzilla/Milestone.pm
Bugzilla/Object.pm
Bugzilla/Product.pm
Bugzilla/Search/Recent.pm
Bugzilla/Search/Saved.pm
Bugzilla/User.pm
Bugzilla/User/APIKey.pm
Bugzilla/User/Session.pm
Bugzilla/Version.pm
Bugzilla/Whine.pm
Bugzilla/Whine/Query.pm
Bugzilla/Whine/Schedule.pm
extensions/BugmailFilter/lib/Filter.pm
extensions/MyDashboard/lib/BugInterest.pm
extensions/Push/lib/BacklogMessage.pm
extensions/Push/lib/Backoff.pm
extensions/Push/lib/LogEntry.pm
extensions/Push/lib/Message.pm
extensions/Push/lib/Option.pm
extensions/Review/lib/FlagStateActivity.pm
extensions/TrackingFlags/lib/Flag.pm
extensions/TrackingFlags/lib/Flag/Bug.pm
extensions/TrackingFlags/lib/Flag/Value.pm
extensions/TrackingFlags/lib/Flag/Visibility.pm
t/bugzilla-objects-def.t [new file with mode: 0644]

index 0bdb50c9aea872e0b234577ae1ccfb9ca10f83e8..4498fedf2f947a5e216234af6abea74f83d1aaa0 100644 (file)
@@ -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
index ee48ed7a2b030840688a6b6a3bee3cde9e8beb9a..5e45b67b10de0b0af280add90a821b3405668048 100644 (file)
@@ -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;
index 4724ae71a1011d73a256fd67c8159e4abf40bb1f..9e5750c7586b3a7487115301b62cf5395c02a639 100644 (file)
@@ -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} }
 
index f40ea17d3a737960caa82eb3595e788c598e3090..635cb4392404c25db6a3dd014f3700521cc1c089 100644 (file)
@@ -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} }
index a931767d2bed27e7260d110591ec1314f4788367..e34f8dde82dfbb684a3dc5eff468fb57481d08ea 100644 (file)
@@ -47,6 +47,17 @@ use constant VALIDATORS => {
     sortkey     => \&_check_sortkey,
 };
 
+###############################
+####      Accessors      ######
+###############################
+
+use Class::XSAccessor {
+    accessors => {
+        id   => __PACKAGE__->ID_FIELD,
+        name => __PACKAGE__->NAME_FIELD,
+    },
+};
+
 ###############################
 ####     Constructors     #####
 ###############################
index f9a6f7d3a948717ff7171a50f1e7dc2cdc87380d..86094db59510f281d829149449abed46569d7401 100644 (file)
@@ -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'};    }
index 4919244cecafb2f7ede3deb4978db9415b126933..ba7bdfc5b1af9c10eba1254f4f58fcc4c3861da1 100644 (file)
@@ -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]); }
index 78e144a5597348000d3d4cd41431433dcd390104..7e294ba74f92753a9610e745ca24681d212249e6 100644 (file)
@@ -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 #
 ##############################################
index 837e1c0de0b385892d5e82ab23a2bae9af2d59aa..d18356d6637488ad8a0bd7c5c5beb21a99ab4f78 100644 (file)
@@ -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
index 10f8f38e6651cdeb896ef492f26f33245b822571..9dd7b3ccfae8d1d96e74ea394ad01f1995d3b704 100644 (file)
@@ -119,6 +119,16 @@ sub new {
     $class->SUPER::new(@_);
 }
 
+###############################
+####      Accessors      ######
+###############################
+
+use Class::XSAccessor {
+    accessors => {
+        id   => __PACKAGE__->ID_FIELD,
+        name => __PACKAGE__->NAME_FIELD,
+    },
+};
 #########################
 # Database Manipulation #
 #########################
index 62579497496c9d66089e261f02013798e7e2aa2f..8ace32be67cbbaa60b4987d5a228505f7b5641cb 100644 (file)
@@ -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'};       }
index c973ea6626431316a3daf5b6e7cdc0a6b53915a8..6aaa79bd1c9893597387e9d39dbabf22e112ae57 100644 (file)
@@ -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'; }
index fe2a90c05a3172b936fc189183eca62014151f39..6d47f1ee0be3adf92e5b9aba1212d93bb2ba3bd7 100644 (file)
@@ -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'};   }
index 61038f6027972befd39b69c6e2d2b2f1c2ef1d5c..b078294d8c6e79143c060683feeb77016ab4e383 100644 (file)
@@ -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 {
index 2f10e1f001acd0e2eeee12c34396b9b26b95fe94..078074dc45b7bfac7d7f37aa15259a616c40e323 100644 (file)
@@ -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'};   }
index 00afbe19f8883a3c4ee1bfb82988d3194a4e9bfe..8660fa55145b4a306704438e4249d5df611fdf1f 100644 (file)
@@ -445,9 +445,6 @@ sub _do_list_select {
 ####      Accessors      ######
 ###############################
 
-sub id   { return $_[0]->{$_[0]->ID_FIELD};   }
-sub name { return $_[0]->{$_[0]->NAME_FIELD}; }
-
 ###############################
 ####        Methods        ####
 ###############################
index 3ac1692f0ddae8a1bd3aefc4b1657c06e97be5f9..16b753fa8121f08482a619ccb5cace6c4eff27c4 100644 (file)
@@ -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'};       }
index a5d9e2417462fcb1e77d52c683c547cffeeddb18..f99cda84fd7f064071873d05ed0dad0c3d522e6a 100644 (file)
@@ -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 #
index 1511cd87b14831f7b211e2d8e9eca9c38605498c..d57dfa35bb3aa3832c6b98ef6640b30b96e178b5 100644 (file)
@@ -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 {
index dc8f6056514a644f6f0af53ea60648a120bac93a..3a0810b64d759b4540bde5d68360633548929d2e 100644 (file)
@@ -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'}; }
index c1a4ed57264126018909d6404fe72e11047101ea..62121382bd57b1645c32e34878b48f3bb64f03db 100644 (file)
@@ -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}      }
index 56e1cd07a025c4fad0f9c63809029ad33474a190..299ed26f7fd9fdea3502741c3d633c0959bbb8db 100644 (file)
@@ -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}        }
index a078cb4fc49e868c663f8f98fe11fbb9f75eb93f..4b509a60e7948b00d5c9ff43756ac570da751db7 100644 (file)
@@ -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'};   }
 
index c4301b4f610ad28fe6acc22ffd99ab02602efc6c..e00f9118bc8874ca8f5b246ac484e5b55e82ebbb 100644 (file)
@@ -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'}; }
index 6ea91cc5134ca20fa5bd3fb14b5b0019eb126acb..885737114e56a4a1d77a65a38b6a33a0f8317549 100644 (file)
@@ -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;
index 017b744e5a01b6a3263d612d0cb6c3186ff6c9a2..725920cd7f5aeb81bbb9f5513a2d972a17bdea25 100644 (file)
@@ -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'};    }
index 7f2f4cb87f72bef5dc00d0cbbba4354522aa26f7..e7e339cd43fef39926a03c80667b7f12517c152a 100644 (file)
@@ -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) = @_;
index cf33900c5cdc5126d72080560c54c804c0898e8e..2e86552613bc1fcfb33e372a58ad928e26fc06d7 100644 (file)
@@ -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} }
index 28b17bae302680c24d7c442b4fc0211b71d15d17..7c248a5015281ab1d979dcb0ae55989ae61dd86b 100644 (file)
@@ -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'};     }
index f0116a2a7b6f536060f5a432614c65552212cc01..d0de1310d58e344a02bdfc4b1cca3cf1ae48fa23 100644 (file)
@@ -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'};        }
index f4e894b941ee836c0670723ade16a40a323ab23a..2d45b9ee10a6e4a3b600d6fc1bf0463e4581767d 100644 (file)
@@ -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'};  }
index 1beb18ef01e2949ea001333f1679accb19d81c12..d8a7f7a2626e20006446889efbcc2c773dbcad90 100644 (file)
@@ -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'};     }
index a08e4c11ddee0598e470789f7cc62a06a657f711..c2e23d513e2699b55640fc39821eca6dd4fe5018 100644 (file)
@@ -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'}; }
 
 #
index 35da42351cd0df1ea4ff7d85aa53c96e886397a4..fcc799a79748f834c9d20be745f95534f21e3a99 100644 (file)
@@ -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) = @_;
index 82c0314e39b222cce6082c3922be3661d06efd24..f54e42a7a2aacc0bc5664866776f7cf179e866f3 100644 (file)
@@ -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;     }
index 7be6617203aef5b9f5d09fe1b6090b159b49cc64..62f103ee5533c029203d9a61ee7d3adce0683afa 100644 (file)
@@ -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'};            }
index 4f2aacc3ab88de738f2de880959c028ab26b2b8e..c1b3ef4f17cbc70bd7b706a9450be5780e6d8cb9 100644 (file)
@@ -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;
index 878c16f990da77608518336a60cc0ccd053bca59..a16ddfe758f440d8f4bed21c02828f8f32f8cd5d 100644 (file)
@@ -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 (file)
index 0000000..6ba33f4
--- /dev/null
@@ -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;