DBUtil.php
1 <?php
2 /**
3  * wCMF - wemove Content Management Framework
4  * Copyright (C) 2005-2015 wemove digital solutions GmbH
5  *
6  * Licensed under the terms of the MIT License.
7  *
8  * See the LICENSE file distributed with this work for
9  * additional information.
10  */
11 namespace wcmf\lib\util;
12 
13 use PDO;
19 use Zend_Db;
20 
21 /**
22  * DBUtil provides database helper functions.
23  *
24  * @author ingo herwig <ingo@wemove.com>
25  */
26 class DBUtil {
27 
28  private static function createConnection($connectionParams) {
29  // connect
30  if (isset($connectionParams['dbType']) && isset($connectionParams['dbHostName']) &&
31  isset($connectionParams['dbUserName']) && isset($connectionParams['dbPassword']) &&
32  isset($connectionParams['dbName'])) {
33 
34  try {
35  // create new connection
36  $pdoParams = array(
37  PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
38  );
39  if ($connectionParams['dbType'] == 'mysql') {
40  $pdoParams[PDO::MYSQL_ATTR_USE_BUFFERED_QUERY] = true;
41  }
42  $params = array(
43  'host' => $connectionParams['dbHostName'],
44  'username' => $connectionParams['dbUserName'],
45  'password' => $connectionParams['dbPassword'],
46  'dbname' => $connectionParams['dbName'],
47  'driver_options' => $pdoParams,
48  'profiler' => false
49  );
50  if (!empty($connectionParams['dbPort'])) {
51  $params['port'] = $connectionParams['dbPort'];
52  }
53  $conn = Zend_Db::factory('Pdo_'.ucfirst($connectionParams['dbType']), $params);
54  $conn->setFetchMode(Zend_Db::FETCH_ASSOC);
55  return $conn;
56  }
57  catch(\Exception $ex) {
58  throw new PersistenceException("Connection to ".$connectionParams['dbHostName'].".".
59  $connectionParams['dbName']." failed: ".$ex->getMessage());
60  }
61  }
62  else {
63  throw new IllegalArgumentException("Wrong parameters for creating connection.");
64  }
65  }
66 
67  /**
68  * Execute a sql script. Execution is done inside a transaction, which is rolled back in case of failure.
69  * @param $file The filename of the sql script
70  * @param $initSection The name of the configuration section that defines the database connection
71  * @return Boolean whether execution succeeded or not.
72  */
73  public static function executeScript($file, $initSection) {
74  $logger = LogManager::getLogger(__CLASS__);
75  if (file_exists($file)) {
76  $logger->info('Executing SQL script '.$file.' ...');
77 
78  // find init params
79  $config = ObjectFactory::getInstance('configuration');
80  if (($connectionParams = $config->getSection($initSection)) === false) {
81  throw new ConfigurationException("No '".$initSection."' section given in configfile.");
82  }
83  // connect to the database
84  $conn = self::createConnection($connectionParams);
85 
86  $logger->debug('Starting transaction ...');
87  $conn->beginTransaction();
88 
89  $exception = null;
90  $fh = fopen($file, 'r');
91  if ($fh) {
92  while (!feof($fh)) {
93  $command = fgets($fh, 8192);
94  if (strlen(trim($command)) > 0) {
95  $logger->debug('Executing command: '.preg_replace('/[\n]+$/', '', $command));
96  try {
97  $conn->query($command);
98  }
99  catch(\Exception $ex) {
100  $exception = $ex;
101  break;
102  }
103  }
104  }
105  fclose($fh);
106  }
107  if ($exception == null) {
108  $logger->debug('Execution succeeded, committing ...');
109  $conn->commit();
110  }
111  else {
112  $logger->error('Execution failed. Reason'.$exception->getMessage());
113  $logger->debug('Rolling back ...');
114  $conn->rollBack();
115  }
116  $logger->debug('Finished SQL script '.$file.'.');
117  $conn->closeConnection();
118  }
119  else {
120  $logger->error('SQL script '.$file.' not found.');
121  }
122  }
123 
124  /**
125  * Duplicate a database on the same server (same user). This works only for MySQL databases.
126  * @param $srcName The name of the source database
127  * @param $destName The name of the source database
128  * @param $server The name of the database server
129  * @param $user The user name
130  * @param $password The password
131  */
132  public static function copyDatabase($srcName, $destName, $server, $user, $password) {
133  $logger = LogManager::getLogger(__CLASS__);
134  if ($srcName && $destName && $server && $user) {
135  self::createDatabase($destName, $server, $user, $password);
136 
137  // setup connection
138  $conn =null;
139  try {
140  $conn = new PDO("mysql:host=$server", $user, $password);
141  }
142  catch(\Exception $ex) {
143  throw new PersistenceException("Couldn't connect to MySql: ".$ex->getMessage());
144  }
145 
146  $conn->beginTransaction();
147  try {
148  // get table list from source database
149  foreach ($conn->query("SHOW TABLES FROM ".$srcName) as $row) {
150  // create new table
151  $sqlStmt = "CREATE TABLE ".$destName.".".$row[0]." LIKE ".$srcName.".".$row[0];
152  $logger->debug($sqlStmt);
153  $result = $conn->query($sqlStmt);
154  if (!$result) {
155  throw new PersistenceException("Couldn't create table: ".$conn->errorInfo());
156  }
157 
158  // insert data
159  $sqlStmt = "INSERT INTO ".$destName.".".$row[0]." SELECT * FROM ".$srcName.".".$row[0];
160  $logger->debug($sqlStmt);
161  $result = $conn->query($sqlStmt);
162  if (!$result) {
163  throw new PersistenceException("Couldn't copy data: ".$conn->errorInfo());
164  }
165  $conn->commit();
166  }
167  } catch (\Exception $ex) {
168  $conn->rollback();
169  }
170  }
171  }
172 
173  /**
174  * Crate a database on the server. This works only for MySQL databases.
175  * @param $name The name of the source database
176  * @param $server The name of the database server
177  * @param $user The user name
178  * @param $password The password
179  */
180  public static function createDatabase($name, $server, $user, $password) {
181  $created = false;
182  if($name && $server && $user) {
183  // setup connection
184  $conn =null;
185  try {
186  $conn = new PDO("mysql:host=$server", $user, $password);
187  }
188  catch(\Exception $ex) {
189  throw new PersistenceException("Couldn't connect to MySql: ".$ex->getMessage());
190  }
191  // create database
192  $sqlStmt = "CREATE DATABASE IF NOT EXISTS ".$name;
193  $result = $conn->query($sqlStmt);
194  if ($result) {
195  $created = true;
196  }
197  if (!$created) {
198  throw new PersistenceException("Couldn't create database: ".$conn->errorInfo());
199  }
200  }
201  }
202 }
203 ?>
static copyDatabase($srcName, $destName, $server, $user, $password)
Duplicate a database on the same server (same user).
Definition: DBUtil.php:132
DBUtil provides database helper functions.
Definition: DBUtil.php:26
IllegalArgumentException signals an exception in method arguments.
Utility classes.
Definition: namespaces.php:97
static getLogger($name)
Get the logger with the given name.
Definition: LogManager.php:35
static createDatabase($name, $server, $user, $password)
Crate a database on the server.
Definition: DBUtil.php:180
static getInstance($name, $dynamicConfiguration=array())
PersistenceException signals an exception in the persistence service.
static executeScript($file, $initSection)
Execute a sql script.
Definition: DBUtil.php:73
ConfigurationException signals an exception in the configuration.