4

Given example: "table->person" - "table->books"(uses->person_id) - "table->notebook"(uses->person_id)

In my Zend classes i define all relations from person to books and notebook and reverse. Now obviously if i want to delete that person, my application should make sure that this person no longer is in possession of anything (at least that's what i want to achieve).

Obviously with a small example i could check easily if $person->hasBooks() || $person->hasNotebooks() but as the database grows theres shoes and pants and glasses and lots of small stuff.

Is there ANY want to automate it in a way like

foreach ( connectedGoods in person as theGood) 
{
  if ( person->hasGood( theGood ) ) {
    //log person still uses theGood
  } 
} 

Or do i at all times have to manually check each "connectedGood"?

To Clarify: i do know how i can findDepentendRowset('singleTable') - i just wanna know if there's like a findDepentendRowset('allDependentTables')

Thanks in advance

//Edit Here is my current table structure to give a little more insight:

tbl_buildings:
b_id
b_*

tbl_asset_x
a_id
b_id (tbl_buildings)

tbl_asset_y
y_id
b_id (tbl_buildings)
Book Of Zeus
  • 49,509
  • 18
  • 174
  • 171
Sam
  • 16,435
  • 6
  • 55
  • 89
  • Do you have a table for each of your items ? if this is the case you should creaate another table linking an object and it's type to a personId, like items_belong_to(person_id, table, id_item) where table is something like `book` or `notebook`. Then you can get every connected good to one or several persons with a request on a single table – Jerec TheSith Oct 20 '11 at 08:49
  • For clarification i added the data structure. Using a keytable in between would kinda .. suck i guess, but maybe that would be the only way to automate these things a little bit... because that table would have looooots of keys only then (a new column for each asset im adding, phew) – Sam Oct 20 '11 at 09:03
  • 2
    What kind of engine are you using ? because if you are using foreign keys with innoDb the rows deletion is automated when deleting a `tbl_building`row, but for row retrieval, if you have many `tbl_asset` I don't see any other way than creating creating a table like `buildings_dependancies(building_asset_tbl)` if every builing has the same assets, or `buildings_dependancies(b_id, building_asset_tbl)` if assets varies depending on the building. (my db skills are limited) – Jerec TheSith Oct 20 '11 at 09:18
  • Yeah i know about the cascading deletion, but that's not what i want. I really want to display the user a message "freaking remove assets first" - and i guess this has to be solved via table dependencies then manually, sigh - would have been too good, thanks though! :) – Sam Oct 20 '11 at 09:20

1 Answers1

2

If I understand you correctly, this should achieve your goals. I've added a method to the table row which checks each of its dependents.

abstract class MyBaseTable extends Zend_Db_Table_Abstract {
    protected $_rowClass = 'MyBaseTableRow';
    public function getReferences() {
        return $this->_referenceMap;
    }
}

abstract class MyBaseTableRow extends Zend_Db_Table_Abstract {
    public function hasDependents() {
        foreach ($this->_getTable()->getReferences() as $entity => $info) {
            if (count($this->findDependentRowset($entity) > 0) {
                return true;
            }
        }
        return false;
    }
}

class Persons extends MyBaseTable {
    protected $_referenceMap    = array(
        'Book' => array(
            'columns'           => 'reported_by',
            'refTableClass'     => 'Books',
            'refColumns'        => 'account_name'
        ),
        'Notebook' => array(
            'columns'           => 'assigned_to',
            'refTableClass'     => 'Notebooks',
            'refColumns'        => 'account_name'
        )
    );
}

$persons = new Persons();
$person = $persons->find(1234);

if ($person->hasDependents()) {
    echo 'freaking remove assets first';    
} else {
    $person->delete();
}

Note: Untested!

James Newell
  • 652
  • 8
  • 12
  • This is untested indeed, but from the way it looks, it should actually work out quite well. I will not have time to check this out within the next weeks, but i hope to remind myself of your approach when i return from vacation :P Thanks in advance! – Sam May 04 '12 at 06:34