Process/FixMysqlCharset.php
[Pman.Core] / Process / FixMysqlCharset.php
1 <?php
2
3 require_once 'Pman/Core/Cli.php';
4
5 class Pman_Core_Process_FixMysqlCharset extends Pman_Core_Cli {
6     
7     static $cli_desc = "Base class for CLI only commands";
8     static $cli_opts = array(
9         'table' => array(
10             'desc' => 'Database Table',
11             'short' => 't',
12             'min' => 1,
13             'max' => 1,
14             
15         ),
16         /*
17         'field' => array(
18             'desc' => 'Table Column Name',
19             'short' => 'f',
20             'min' => 1,
21             'max' => 1,
22             
23         ),
24         */
25     );
26     
27     
28     // bugs: 'PICUT, MAƋPPE' << strips out chars..
29     
30     
31     /*
32      *
33      * should we do it in PHP - not using the lating stuff?
34      */
35     
36     function get($req , $opts=array())
37     {
38        // DB_DataObject::debugLevel(1);
39        
40         if (file_exists('/tmp/fix_mysql_charset_'. $opts['table'])) {
41             echo "Conversion for {$opts['table']} has already been done - doing it again will mess things up.. - delete the /tmp/fix_mysql_charset file if you really want to do this\n\n";
42             exit;
43         }
44         touch('/tmp/fix_mysql_charset_'. $opts['table']);
45         
46         $this->disableTriggers($opts['table']);
47         $this->enableTriggers($opts['table']);
48         
49         $t = DB_DataObject::factory($opts['table']);
50         $cols = $t->tableColumns();
51         $t->selectAdd();
52         $t->selectAdd("id");
53         
54         $conv = array();
55         $w = array();
56         foreach($cols as $k=>$v) {
57             if (!($v & 2)) {
58                 continue;
59             }
60             if (($v & 4)) { // date?
61                 continue;
62             }
63             $conv[] = $k;
64             $t->selectAdd($k);
65             $t->selectAdd("COALESCE(convert(cast(convert({$k} using  latin1) as binary) using utf8), '') as zz_{$k}");
66             $w[] = " convert(cast(convert({$k} using  latin1) as binary) using utf8) != $k";
67         }
68         $t->whereAdd(implode(" OR ", $w));
69         //$t->whereAdd('id=4555');
70        // $t->limit(100);
71         $t->orderBy('id ASC');
72         $all = $t->fetchAll();
73         foreach($all as $t) {
74             $up =false;
75             $tt = clone($t);
76             //print_r($tt); exit;
77             foreach($conv as $k) {
78                if ($t->{$k} != $t->{'zz_'.$k}) {
79                     if (strpos($t->{'zz_'. $k}, '?') !== false) {
80                         $up = false;
81                         continue;
82                     }
83                 
84                     $t->{$k} = $t->{'zz_'.$k};
85                     $up =true;
86                }
87                
88                
89             }
90             if ($up) {
91                 echo "UPDATE $t->id\n";
92                 $t->_skip_write_xml= true;
93                 DB_DataObject::debugLevel(1);
94                 $t->update($tt);
95                 DB_DataObject::debugLevel(0);
96                //  print_r($t);exit;; 
97             }
98         }
99         
100         
101          
102         exit;
103     }
104     
105     var $triggers = array();
106     function disabletriggers($tbl)
107     {
108         
109         $t = DB_DataObject::factory($tbl);
110          DB_DataObject::debugLevel(1);
111         $t->query("SHOW TRIGGERS FROM {$t->databaseNickname()} where `table` = '{$tbl}'");
112         $this->triggers = array();
113         while ($t->fetch()) {
114             $this->triggers[] = $t->toArray('%s', true);
115             $d = DB_DataObject::factory($tbl);
116             $d->query("DROP TRIGGER {$t->Trigger}");
117         }
118         
119         
120     }
121     /*
122      [Trigger] => account_transaction_before_delete
123     [Event] => DELETE
124     [Table] => account_transaction
125     [Statement] => BEGIN
126             
127             UPDATE `Error: Not allow to delete transaction` SET x = 1;
128
129         END
130     [Timing] => BEFORE
131    */
132     function enabletriggers($tbl)
133     {
134         
135         
136         DB_DataObject::debugLevel(1);
137         foreach($this->triggers as $tr) {
138             $t = DB_DataObject::factory($tbl);
139             $t->query("
140                 CREATE TRIGGER {$tr['Trigger']} 
141                 {$tr['Timing']} {$tr['Event']} ON {$tbl}
142                 FOR EACH ROW
143                 {$tr['Statement']}
144             ");
145             
146             
147             
148         }
149         
150     }
151     
152     
153 }