Project

General

Profile

« Previous | Next » 

Revision 2105

Added by darkviper almost 10 years ago

- removed importSql() method from class WbDatabase
+ new class SqlImport added

View differences:

branches/2.8.x/CHANGELOG
11 11
! = Update/Change
12 12
===============================================================================
13 13

  
14
24 Nov-2014 Build 2105 Manuela v.d.Decken(DarkViper)
15
- removed importSql() method from class WbDatabase
16
+ new class SqlImport added
14 17
20 Nov-2014 Build 2104 Manuela v.d.Decken(DarkViper)
15 18
! complete rebuild of wb/install/ - changed to use import-struct.sql
16 19
! change class WbDatabase from mysql to msqli
branches/2.8.x/wb/admin/interface/version.php
51 51

  
52 52
// check if defined to avoid errors during installation (redirect to admin panel fails if PHP error/warnings are enabled)
53 53
if(!defined('VERSION')) define('VERSION', '2.8.4');
54
if(!defined('REVISION')) define('REVISION', '2104');
54
if(!defined('REVISION')) define('REVISION', '2105');
55 55
if(!defined('SP')) define('SP', '');
branches/2.8.x/wb/framework/WbDatabase.php
526 526
	                          $sEngine      = 'MyISAM',
527 527
	                          $sCollation   = 'utf8_unicode_ci')
528 528
	{
529
		return $this->importSql($sSqlDump, $sTablePrefix, $bPreserve, $sEngine, $sCollation);
529
		return $this->importSql($sSqlDump, $sTablePrefix, $sAction, $sEngine, $sCollation);
530 530
	}
531
/**
532
 * Import an SQl-Dumpfile witch can include unlimited placeholders for values
533
 * @param mixed  $mSqlDump      can be string with filename or array with additional vars
534
 * @param string $sTablePrefix  can be used to override settings from WbDatabase object
535
 * @param string $sAction       'install', 'uninstall', 'upgrade', 'repair
536
 * @param string $sEngine       kind of table engine: MyIsam(default)
537
 * @param string $sCollation    utf8_unicode_ci(default)
538
 * @return bool  false on error
539
 */
540
	public function importSql(
541
        $mSqlDump,
542
        $sTablePrefix = '',               // can override settings from WbDatabase object
543
        $sAction      = 'install',        // skip 'DROP TABLE' statements
544
        $sEngine      = 'MyISAM',         // the default table engine
545
        $sCollation   = 'utf8_unicode_ci' // the default collation to use
546
    )
547
    {
548
		$retval = true;
549
		$this->error = '';
550
        // sanitize arguments
551
        if (! is_string($sAction)) {
552
            $sAction = $sAction ? 'repair' : 'install';
553
        }
554
        $aAllowedActions = array('install', 'uninstall', 'upgrade', 'repair');
555
        $sAction = strtolower(preg_replace('/^.*?('.implode('|', $aAllowedActions).')(\.php)?$/iU', '$1', $sAction));
556
        $sAction = (in_array($sAction, $aAllowedActions) ? $sAction : 'install');
557
        $sTablePrefix = trim($sTablePrefix);
558
        $aEngineTypes = array(
559
            'csv'        => 'CSV',
560
            'blackhole'  => 'BLACKHOLE',
561
            'memory'     => 'MEMORY',
562
            'myisam'     => 'MyISAM',
563
            'innodb'     => 'InnoDB',
564
            'archive'    => 'ARCHIVE',
565
            'mrg_myisam' => 'MRG_MYISAM'
566
        );
567
        if (isset($aEngineTypes[strtolower($sEngine)])) {
568
            $sEngine = $aEngineTypes[strtolower($sEngine)];
569
        } else {
570
            $sEngine = 'MyISAM';
571
        }
572
        // test if selected collation is available. Otherwise select 'utf8_unicode_ci'
573
        $sql = 'SELECT COUNT(*) FROM `COLLATIONS` '
574
             . 'WHERE `COLLATION_NAME`=\''.$sCollation.'\'';
575
        $sCollation = ($this->get_one($sql) ? $sCollation : 'utf8_unicode_ci');
576
        $aTmp = preg_split('/_/', $sCollation, null, PREG_SPLIT_NO_EMPTY);
577
        $sCharset = $aTmp[0];
578
        // define array of searches
579
        $aSearch  = array(
580
            '/\{TABLE_PREFIX\}/',
581
            '/\{TABLE_COLLATION\}/', // deprecated from 2.8.4
582
            '/\{FIELD_COLLATION\}/', // deprecated from 2.8.4
583
            '/\{TABLE_ENGINE\}/',
584
            '/\{TABLE_ENGINE=([a-zA-Z_0-9]*)\}/',
585
            '/\{CHARSET\}/',
586
            '/\{COLLATION\}/'
587
        );
588
        // define array of replacements
589
        $aReplace = array(
590
            $sTablePrefix,
591
            ' COLLATE {COLLATION}', // deprecated from 2.8.4
592
            ' COLLATE {COLLATION}', // deprecated from 2.8.4
593
            ' {ENGINE='.$sEngine.'}',
594
            ' ENGINE=$1 DEFAULT CHARSET={CHARSET} COLLATION={COLLATION}',
595
            $sCharset,
596
            $sCollation
597
        );
598 531

  
599
        if (is_array($mSqlDump)) {
600
            // try to get dumpfile name
601
            if (!isset($mSqlDump['sSqlDump'])) {
602
                $this->error = 'missing index \'sSqlDump\' in $mSqlDump';
603
                return false;
604
            } else {
605
            // get dumpfile name from array and then remove entry
606
                $sDumpFile = (string)$mSqlDump['sSqlDump'];
607
                unset($mSqlDump['sSqlDump']);
608
                // import all vars and it's values from array
609
                foreach ($mSqlDump as $sIndex => $sValue) {
610
                    // transform varname into placeholder name ('sPageTitle' => 'PAGE_TITLE')
611
                    $sIndex = strtoupper(preg_replace('/([a-z0-9])([A-Z])/', '\1_\2', ltrim($sIndex, 'a..z')));
612
                    // fill search/replace arrays
613
                    $aSearch[]  = '/\{'.$sIndex.'\}/';
614
                    $aReplace[] = $sValue ;
615
                }
616
            }
617
        } elseif (is_string($mSqlDump)) {
618
            $sDumpFile = (string)$mSqlDump;
619
        } else {
620
            $this->error = 'invalid argument $mSqlDump';
621
            return false;
622
        }
623
        if (!is_readable($sDumpFile)) {
624
            $this->Error = 'unable to open \''.$sDumpFile.'\'';
625
            return false;
626
        }
627
		$sql = '';
628
		$aSql = file($sDumpFile, FILE_SKIP_EMPTY_LINES);
629
        //	remove possible ByteOrderMark
630
		$aSql[0] = preg_replace('/^[\xAA-\xFF]{3}/', '', $aSql[0]);
631
		while (sizeof($aSql) > 0) {
632
			$sSqlLine = trim(array_shift($aSql));
633
			if (!preg_match('/^[-\/]+.*/', $sSqlLine)) {
634
				$sql = $sql.' '.$sSqlLine;
635
				if ((substr($sql,-1,1) == ';')) {
636
					$sql = trim(preg_replace($aSearch, $aReplace, $sql));
637
                    $sAvailSqlObjects = 'TABLE|VIEW|INDEX|PROCEDURE|FUNCTION|TRIGGER|EVENT';
638
                    switch ($sAction) {
639
                        case 'uninstall': // skip CREATE; execute DROP
640
                            if (preg_match('/^\s*CREATE ('.$sAvailSqlObjects.') /siU', $sql)) {
641
                                $sql = '';
642
                                continue; // read next statement
643
                            }
644
                            break;
645
                        case 'upgrade': // skip DROP; execute CREATE
646
                        case 'repair':  // skip DROP; execute CREATE
647
                            if (preg_match('/^\s*DROP ('.$sAvailSqlObjects.') /siU', $sql)) {
648
                                $sql = '';
649
                                continue; // read next statement
650
                            }
651
                            break;
652
                        default: // install:  execute DROP; execute CREATE
653
                            break;
654
                    }
655
                    if (!$this->doQuery($sql)) {
656
                        $retval = false;
657
                        $this->error = $this->getError();
658
                        unset($aSql);
659
                        break;
660
                    }
661
					$sql = '';
662
				}
663
			}
664
		}
665
		return $retval;
666
    } // end of function importSql()
667 532
/**
668 533
 * retuns the type of the engine used for requested table
669 534
 * @param string $table name of the table, including prefix
branches/2.8.x/wb/framework/SqlImport.php
1
<?php
2

  
3
/**
4
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
5
 *
6
 * This program is free software: you can redistribute it and/or modify
7
 * it under the terms of the GNU General Public License as published by
8
 * the Free Software Foundation, either version 3 of the License, or
9
 * (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18
 */
19

  
20
/**
21
 * SqlImport.php
22
 *
23
 * @category     Core
24
 * @package      Core_Database
25
 * @copyright    Manuela v.d.Decken <manuela@isteam.de>
26
 * @author       Manuela v.d.Decken <manuela@isteam.de>
27
 * @license      http://www.gnu.org/licenses/gpl.html   GPL License
28
 * @version      0.0.1
29
 * @revision     $Revision: 2070 $
30
 * @lastmodified $Date: 2014-01-03 02:21:42 +0100 (Fr, 03 Jan 2014) $
31
 * @since        File available since 30.11.2014
32
 * @description  can handle different actions with SQL-Import files
33
 */
34
class SqlImport {
35

  
36
/** WbDatabase object */
37
    protected $oDb          = null;
38
/** valide structure file to use for import */
39
    protected $sStructFile  = '';
40
/** valide TablePrefix to use for import */
41
    protected $sTablePrefix = '';
42
/** default Collation to use for import of chars/text */
43
    protected $sCollation   = 'utf8_unicode_ci';
44
/** default engine for tables */
45
    protected $sEngine      = 'MyISAM';
46
/** collected error messages */
47
    protected $aErrMsg      = array();
48
/** possible actions for doImport() */
49
    protected $aActions     = array(
50
        'uninstall',
51
        'install',
52
        'upgrade'
53
    );
54
/** collected additional replacements pairs */
55
    protected $aReplacements = array('key'=>array(), 'value'=>array());
56
/** possible engines to use */
57
    protected $aEngineTypesAvail = array(
58
        'memory'     => 'MEMORY',
59
        'myisam'     => 'MyISAM',
60
        'innodb'     => 'InnoDB',
61
        'archive'    => 'ARCHIVE'
62
    );
63
/** SQL objects witch can be handled */
64
    protected $aAvailSqlObjects = array(
65
        'TABLE',
66
        'VIEW',
67
        'INDEX',
68
        'PROCEDURE',
69
        'FUNCTION',
70
        'TRIGGER',
71
        'EVENT'
72
    );
73
/**
74
 * Constructor
75
 * @param WbDatabase $oDb
76
 * @param string $sStructFile
77
 */
78
    public function __construct(WbDatabase $oDb, $sStructFile)
79
    {
80
        $this->oDb = $oDb;
81
        $this->sTablePrefix = $oDb->TablePrefix;
82
        if (file_exists($sStructFile)) {
83
            $this->sStructFile = str_replace('\\', '/', $sStructFile);
84
        } else {
85
            $this->sStructFile = '';
86
            $this->aErrMsg[] = 'file with structure not available! ['.$sStructFile.']';
87
        }
88
    }
89
/**
90
 * Add Key-Value pairs for additional placeholders
91
 * @param string $sKey
92
 * @param mixed $sValue
93
 */
94
    public function addReplacement($sKey, $sValue = '')
95
    {
96
        $sKey = strtoupper(preg_replace('/([a-z0-9])([A-Z])/', '\1_\2', ltrim($sKey, 'a..z')));
97
        $this->aReplacements['key'][]  = '/\{'.$sKey.'\}/';
98
        $this->aReplacements['value'][] = $sValue;
99
    }
100
/**
101
 * define another collation then default utf8_unicode_ci
102
 * @param string $sCollation
103
 * @return boolean
104
 */
105
    public function setDefaultCollation($sCollation = 'utf8_unicode_ci')
106
    {
107
        $bRetval = false;
108
        // test if selected collation is available on current server.
109
        $sql = 'SHOW COLLATION LIKE \''.$this->oDb->escapeString($sCollation).'\'';
110
        if (($oAvailCollations = $this->oDb->doQuery($sql))) {
111
            if (($oAvailCollations->numRows())) {
112
                //use new collation
113
                $this->sCollation = $sCollation;
114
                $bRetval = true;
115
            }
116
        }
117
        return $bRetval;
118
    }
119
/**
120
 * define another prefix then 'MyISAM'
121
 * @param string $sEngine
122
 * @return boolean
123
 */
124
    public function setDefaultEngine($sEngine ='MyISAM')
125
    {
126
        $bRetval = false;
127
        if (isset($this->aEngineTypesAvail[strtolower($sEngine)])) {
128
            // use new engine
129
            $this->sEngine = $this->aEngineTypesAvail[strtolower($sEngine)];
130
            $bRetval = true;
131
        }
132
        return $bRetval;
133
    }
134
/**
135
 * define another prefix then default in Wbdatabase
136
 * @param string $sTablePrefix
137
 * @return boolean
138
 */
139
    public function setTablePrefix($sTablePrefix = '')
140
    {
141
        $bRetval = false;
142
        if (
143
        // Prefix must be empty or matching allowed table names
144
            $sTablePrefix == '' ||
145
            preg_match('/^[a-z][a-z0-9_]*$/i', $sTablePrefix)
146
        ) {
147
            // use new TablePrefix
148
            $this->sTablePrefix = $sTablePrefix;
149
            $bRetval = true;
150
        }
151
        return $bRetval;
152
    }
153
/**
154
 * Start and execute the import
155
 * @param string $sAction
156
 * @return boolean
157
 */
158
    public function doImport($sAction)
159
    {
160
        if (! $this->sStructFile) {
161
        // no file found so ignore import method
162
            return true;
163
        }
164
        if (! is_readable($this->sStructFile)) {
165
        // file fond but it's not readable
166
            $this->aErrMsg[] = 'unable to read file ['.$this->sStructFile.']';
167
            return false;
168
        }
169
        $sAction = strtolower(
170
            preg_replace(
171
                '/^.*?('.implode('|', $this->aActions).')(\.php)?$/i',
172
                '$1',
173
                $sAction
174
            )
175
        );
176
        $sAction = ($sAction == '' ? 'install' : $sAction);
177
        if ($this->importSql($sAction)) {
178
            return true;
179
        } else {
180
            $this->aErrMsg[] = $this->oDb->getError();
181
            return false;
182
        }
183
    }
184
/**
185
 * return errorstrings, concatet by LF
186
 * @return string
187
 */
188
    public function getError()
189
    {
190
        return implode(PHP_EOL, $this->aErrMsg);
191
    }
192
/**
193
 * Import an SQl-Dumpfile witch can include unlimited additional placeholders for values
194
 * @param string $sAction 'install' || 'uninstall' || 'upgrade'
195
 * @return bool  false on error
196
 */
197
    protected function importSql($sAction = 'install')
198
    {
199
        $retval = true;
200
        $this->error = '';
201
        // sanitize arguments
202
        $aTmp = preg_split('/_/', $this->sCollation, null, PREG_SPLIT_NO_EMPTY);
203
        $sCharset = $aTmp[0];
204
        // get from addReplacements
205
        $aSearch  = $this->aReplacements['key'];
206
        // define basic array of searches
207
        $aSearch[] = '/\{TABLE_PREFIX\}/';
208
        $aSearch[] = '/\{FIELD_COLLATION\}/';
209
        $aSearch[] = '/\{TABLE_ENGINE\}/';
210
        $aSearch[] = '/\{TABLE_ENGINE=([a-zA-Z_0-9]*)\}/';
211
        $aSearch[] = '/\{CHARSET\}/';
212
        $aSearch[] = '/\{COLLATION\}/';
213
        // get from addReplacements
214
        $aReplace = $this->aReplacements['value'];
215
        // define basic array of replacements
216
        $aReplace[] = $this->sTablePrefix;
217
        $aReplace[] = ' COLLATE {COLLATION}';
218
        $aReplace[] = ' {ENGINE='.$this->sEngine.'}';
219
        $aReplace[] = ' ENGINE=$1 DEFAULT CHARSET={CHARSET} COLLATE={COLLATION}';
220
        $aReplace[] = $sCharset;
221
        $aReplace[] = $this->sCollation;
222

  
223
        $sql = ''; // buffer for statements
224
        $aSql = file($this->sStructFile, FILE_SKIP_EMPTY_LINES|FILE_IGNORE_NEW_LINES);
225
        //  remove possible ByteOrderMark
226
        $aSql[0] = preg_replace('/^[\xAA-\xFF]{3}/', '', $aSql[0]);
227
    // iterate file line by line
228
        while (sizeof($aSql) > 0) {
229
            // remove trailing and leading whitespaces
230
            $sSqlLine = trim(array_shift($aSql));
231
            // skip line if it's a comment
232
            if (preg_match('/^--/', $sSqlLine)) { continue; }
233
            // attach line to buffer
234
            $sql = $sql.' '.$sSqlLine;
235
            // detect end of statement
236
            if ((substr($sql,-1,1) == ';')) {
237
                // replace placeholders in statement
238
                $sql = trim(preg_replace($aSearch, $aReplace, $sql));
239
                $sAvailSqlObjects = implode('|', $this->aAvailSqlObjects);
240
                switch ($sAction) {
241
                    case 'uninstall': // execute DROP - skip CREATE
242
                        if (preg_match('/^\s*CREATE ('.$sAvailSqlObjects.') /si', $sql)) {
243
                            $sql = ''; // clear buffer
244
                            continue 2; // read next statement
245
                        }
246
                        break;
247
                    case 'upgrade': // skip DROP; execute CREATE
248
                        if (preg_match('/^\s*DROP ('.$sAvailSqlObjects.') /si', $sql)) {
249
                            $sql = ''; // clear buffer
250
                            continue 2; // read next statement
251
                        }
252
                        break;
253
                    default: // install:  execute DROP; execute CREATE
254
                        break;
255
                }
256
                if (!$this->oDb->doQuery($sql)) {
257
                    $retval = false;
258
                    $this->aErrMsg[] = $this->oDb->getError();
259
                    unset($aSql);
260
                    break;
261
                }
262
                $sql = ''; // clear buffer
263
            }
264
        }
265
        return $retval;
266
    } // end of function importSql()
267

  
268
}

Also available in: Unified diff