简体   繁体   中英

How do I reduce repetitive code when inserting the same metadata into identical columns over multiple tables?

My goals:

  • Follow database-normalization.
  • Ability to track changes in my tables.
  • Ability to restore the state of my database from a given point in time, eg last month.
  • Separate the code that is processing the data so that the input can come either from a HTML-form or a script in another language (Ruby/perl).

To accomplish this, I've opted for a database design like the one described in this answer:

StackOverflow: Is there a MySQL option/feature to track history of changes to records?

However, when a user updates several fields, the same metadata has to be inserted into multiple tables that contain identical columns, and my code becomes repetitive.

Example:

A user submits data through a HTML-form. PHP processes the data like below, with the help of Propel ORM.

function insertEvent($name, $venueId, $user, $date, $id = 0) {
    //validation and formatting..
    //if id == 0, new event, 
    //else, this is an update, archive the old database row on successful processing and maintain a common id as a parent
    //...
    $event = new Event();
    $event->setName($name); 
    $event->setVenueId($venueId); 
    $event->setUser($user); //1
    $event->setValidFrom($date); //1
    $event->setValidUntil(null); //1 
    $event->save(); 
    // ...
}

function insertEventPhonenumber($phonenumber, $pid, $user, $date, $id = 0) {
    //...
    $event_phonenumber = new EventPhonenumber();
    $event_phonenumber->setPid($pid); //2
    $event_phonenumber->setPhonenumber($phonenumber);
    $event_phonenumber->setUser($user); //2
    $event_phonenumber->setValidFrom($date); //2
    $event_phonenumber->setValidUntil(null); //2 
    $event_phonenumber->save(); 
    // ...
} 

function insertEventArtistId($artistId, $pid, $user, $date, $id = 0) {
    //...
    $event_artistId = new EventArtistId();
    $event_artistId->setPid($pid); //3
    $event_artistId->setArtistId($artistId);
    $event_artistId->setUser($user); //3
    $event_artistId->setValidFrom($date); //3
    $event_artistId->setValidUntil(null); //3
    $event_artistId->save(); 
    // ...
}

My problem:

In my full code there are more tables affected than the three in the example.

Marked with //1, //2 and //3, you see data input that is often going to be identical.

In my stomach, I don't like this. I've been trying search engines with queries like 'common columns in SQL insert queries over multiple tables' and variations of the wording, without finding anything directly related to my problem.

Is this bad practice like it feels to me?

How can I minimize the repetition in my code?

Are you trying to get rid of all of those functions? If so you can use the call_user_func to eliminate most of your code.

<?php
class MyApp {


     static function insert($name, $params) {
         $ob = new $name();
         foreach($params as $k=>$v) {
            $op = array($ob,"set".ucfirst($k));
            //if (is_callable($op)) {
                call_user_func($op,$v);
            //}
         }
         $ob->save();
     } 

}

MyApp::insert(
    "EventArtistId",
    array(
        "pid"=>$_REQUEST['pid'],
        "artistId"=>$_REQUEST['artistId'],
        "user" => $_REQUEST['user'],
        "validFrom" => $_REQUEST['date'], // may need to convert date
        "validUntil" => isset($_REQUEST['validUntil']) ? $_REQUEST['validUntil'] : null,
    )
);

// More cool
// MyApp::insert($_REQUEST['action'],$_REQUEST['params']);

?>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM