Porter   A
last analyzed

Complexity

Total Complexity 19

Size/Duplication

Total Lines 156
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 0

Importance

Changes 0
Metric Value
dl 0
loc 156
rs 10
c 0
b 0
f 0
wmc 19
lcom 1
cbo 0

6 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A run() 0 13 3
A getFormatsFromDb() 0 5 1
C fixFormats() 0 43 7
B dumpTable() 0 24 2
B translateRow() 0 21 5
1
<?php namespace Garden;
2
3
    /**
4
     * Format of a porter run.
5
     *
6
     *     array('source' => array(
7
     *        ['source' => array('table', array(filter)),]
8
     *        'destination' => tablename,
9
     *        'columns' => array(
10
     *           'sourcecolumn' => array('destcolumn'
11
     *              [, 'type' => dbtype]
12
     *              [, 'sourcecolumn' => 'name']
13
     *              [, 'filter' => callable]
14
     *           )
15
     *        )
16
     *        [, 'rowfilter' => callable]
17
     */
18
19
/**
20
 *
21
 */
22
class Porter {
23
    /// Properties ///
24
25
    /**
26
     * The destination database.
27
     * @var Db
28
     */
29
    protected $destination;
30
31
    /**
32
     * @var array
33
     */
34
    protected $formats;
35
36
    /**
37
     * The source database.
38
     * @var Db
39
     */
40
    protected $source;
41
42
    /// Methods ///
43
44
    /**
45
     *
46
     * @param Db $source
47
     * @param Db $destination
48
     */
49
    public function __construct($source, $destination) {
50
        $this->source = $source;
51
        $this->destination = $destination;
52
    }
53
54
    public function run() {
55
        // Get all of the tables in the source database.
56
        if (!isset($this->formats)) {
57
            $this->formats = $this->getFormatsFromDb($this->source);
58
        } else {
59
            $this->fixFormats($this->formats);
60
        }
61
62
        // Port the data in each table.
63
        foreach ($this->formats as $name => $format) {
64
            $this->dumpTable($format);
65
        }
66
    }
67
68
    /**
69
     * Get the translation format from the database.
70
     *
71
     * @param Db $db
72
     * @return type
73
     */
74
    protected function getFormatsFromDb($db) {
75
        $tables = $db->tables(true);
76
        $formats = $this->fixFormats($tables);
77
        return $formats;
78
    }
79
80
    protected function fixFormats($data) {
81
        $result = array();
82
83
84
        foreach ($data as $table => $tdef) {
85
            $format = $tdef;
86
87
            // Set the source query.
88
            array_touch('source', $format, array($table, array()));
89
            array_touch('destination', $format, $format['destination']);
90
91
            // Coax the columns into the proper format.
92
            $columns = array();
93
            if (isset($tdef['columns'])) {
94
                foreach ($tdef['columns'] as $sourceColumn => $cdef) {
95
                    if (is_string($cdef)) {
96
                        // This is a format in the form sourcecolumns => destcolumn
97
                        $cformat = array($cdef);
98
                    } elseif (isset($cdef[0])) {
99
                        $cformat = array_change_key_case($cdef);
100
                    } elseif (isset($cdef['column'])) {
101
                        // This is an old porter format.
102
                        $cformat = array($cdef['column']) + $cdef;
103
                        unset($cformat['column']);
104
                    } else {
105
                        $cformat = array(val('sourcecolumn', $cdef, $sourceColumn)) + array_change_key_case($cdef);
106
                    }
107
108
                    array_touch('sourcecolumn', $cformat, $sourceColumn);
109
                    array_touch('type', $cformat, 'varchar(255)');
110
                    array_touch('default', $cformat, null);
111
112
                    $columns[$sourceColumn] = $cformat;
113
                }
114
            }
115
            $format['columns'] = $columns;
116
//            $format['defaultrow'] = $this->getDefaultRow($format);
117
118
            $result[$table] = $columns;
119
        }
120
121
        return $result;
122
    }
123
124
    public function dumpTable($format) {
125
        $table = $format['destination'];
126
127
        timerStart("dumping $table");
128
129
        // Define the table.
130
        timerStart("defining $table");
131
        $this->destination->defineTable($format);
132
        timerStop();
133
134
        // Loop over the data from the source.
135
        timerStart("loading $table");
136
        $rows = $this->source->get($format['source'][0], $format['source'][1], null, null, array(Db::GET_UNBUFFERED => true));
137
138
        $this->destination->loadStart($table);
139
        foreach ($rows as $row) {
140
            $trow = $this->translateRow($row, $format);
141
            $this->destination->loadRow($trow);
142
        }
143
        $load = $this->destination->loadFinish();
144
        timerStop(array_translate($load, array('count' => 'rows'))); // loading table
145
146
        timerStop(); // dumping table
147
    }
148
149
    /**
150
     * Translate a row from one row format to another.
151
     *
152
     * @param array $row The data to translate.
153
     * @param array $format The translation format.
154
     * @return array The translated row.
155
     */
156
    protected function translateRow($row, $format) {
157
        // Apply the row filter.
158
        if (isset($format['rowfilter'])) {
159
            call_user_func_array($format['rowfilter'], array(&$row));
160
        }
161
162
        $result = array();
163
        foreach ($format['columns'] as $key => $cdef) {
164
            if (array_key_exists($cdef['sourcecolumn'], $row))
165
                $value = $row[$cdef['sourcecolumn']];
166
            else
167
                $value = $cdef['default'];
168
169
            if (isset($cdef['filter'])) {
170
                $value = call_user_func($cdef['filter'], $value, $key, $row);
171
            }
172
173
            $result[$cdef[0]] = $value;
174
        }
175
        return $result;
176
    }
177
}
178