5 * Copyright (c) 2006 - 2014 PHPExcel
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 * @package PHPExcel_CachedObjectStorage
23 * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
24 * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
25 * @version ##VERSION##, ##DATE##
30 * PHPExcel_CachedObjectStorage_SQLite
33 * @package PHPExcel_CachedObjectStorage
34 * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
36 class PHPExcel_CachedObjectStorage_SQLite
extends PHPExcel_CachedObjectStorage_CacheBase
implements PHPExcel_CachedObjectStorage_ICache
{
43 private $_TableName = null;
50 private $_DBHandle = null;
53 * Store cell data in cache for the current cell object if it's "dirty",
54 * and the 'nullify' the current cell object
57 * @throws PHPExcel_Exception
59 protected function _storeData() {
60 if ($this->_currentCellIsDirty
&& !empty($this->_currentObjectID
)) {
61 $this->_currentObject
->detach();
63 if (!$this->_DBHandle
->queryExec("INSERT OR REPLACE INTO kvp_".$this->_TableName
." VALUES('".$this->_currentObjectID
."','".sqlite_escape_string(serialize($this->_currentObject
))."')"))
64 throw new PHPExcel_Exception(sqlite_error_string($this->_DBHandle
->lastError()));
65 $this->_currentCellIsDirty
= false;
67 $this->_currentObjectID
= $this->_currentObject
= null;
68 } // function _storeData()
72 * Add or Update a cell in cache identified by coordinate address
74 * @param string $pCoord Coordinate address of the cell to update
75 * @param PHPExcel_Cell $cell Cell to update
76 * @return PHPExcel_Cell
77 * @throws PHPExcel_Exception
79 public function addCacheData($pCoord, PHPExcel_Cell
$cell) {
80 if (($pCoord !== $this->_currentObjectID
) && ($this->_currentObjectID
!== null)) {
84 $this->_currentObjectID
= $pCoord;
85 $this->_currentObject
= $cell;
86 $this->_currentCellIsDirty
= true;
89 } // function addCacheData()
93 * Get cell at a specific coordinate
95 * @param string $pCoord Coordinate of the cell
96 * @throws PHPExcel_Exception
97 * @return PHPExcel_Cell Cell that was found, or null if not found
99 public function getCacheData($pCoord) {
100 if ($pCoord === $this->_currentObjectID
) {
101 return $this->_currentObject
;
105 $query = "SELECT value FROM kvp_".$this->_TableName
." WHERE id='".$pCoord."'";
106 $cellResultSet = $this->_DBHandle
->query($query,SQLITE_ASSOC
);
107 if ($cellResultSet === false) {
108 throw new PHPExcel_Exception(sqlite_error_string($this->_DBHandle
->lastError()));
109 } elseif ($cellResultSet->numRows() == 0) {
110 // Return null if requested entry doesn't exist in cache
114 // Set current entry to the requested entry
115 $this->_currentObjectID
= $pCoord;
117 $cellResult = $cellResultSet->fetchSingle();
118 $this->_currentObject
= unserialize($cellResult);
119 // Re-attach this as the cell's parent
120 $this->_currentObject
->attach($this);
122 // Return requested entry
123 return $this->_currentObject
;
124 } // function getCacheData()
128 * Is a value set for an indexed cell?
130 * @param string $pCoord Coordinate address of the cell to check
133 public function isDataSet($pCoord) {
134 if ($pCoord === $this->_currentObjectID
) {
138 // Check if the requested entry exists in the cache
139 $query = "SELECT id FROM kvp_".$this->_TableName
." WHERE id='".$pCoord."'";
140 $cellResultSet = $this->_DBHandle
->query($query,SQLITE_ASSOC
);
141 if ($cellResultSet === false) {
142 throw new PHPExcel_Exception(sqlite_error_string($this->_DBHandle
->lastError()));
143 } elseif ($cellResultSet->numRows() == 0) {
144 // Return null if requested entry doesn't exist in cache
148 } // function isDataSet()
152 * Delete a cell in cache identified by coordinate address
154 * @param string $pCoord Coordinate address of the cell to delete
155 * @throws PHPExcel_Exception
157 public function deleteCacheData($pCoord) {
158 if ($pCoord === $this->_currentObjectID
) {
159 $this->_currentObject
->detach();
160 $this->_currentObjectID
= $this->_currentObject
= null;
163 // Check if the requested entry exists in the cache
164 $query = "DELETE FROM kvp_".$this->_TableName
." WHERE id='".$pCoord."'";
165 if (!$this->_DBHandle
->queryExec($query))
166 throw new PHPExcel_Exception(sqlite_error_string($this->_DBHandle
->lastError()));
168 $this->_currentCellIsDirty
= false;
169 } // function deleteCacheData()
173 * Move a cell object from one address to another
175 * @param string $fromAddress Current address of the cell to move
176 * @param string $toAddress Destination address of the cell to move
179 public function moveCell($fromAddress, $toAddress) {
180 if ($fromAddress === $this->_currentObjectID
) {
181 $this->_currentObjectID
= $toAddress;
184 $query = "DELETE FROM kvp_".$this->_TableName
." WHERE id='".$toAddress."'";
185 $result = $this->_DBHandle
->exec($query);
186 if ($result === false)
187 throw new PHPExcel_Exception($this->_DBHandle
->lastErrorMsg());
189 $query = "UPDATE kvp_".$this->_TableName
." SET id='".$toAddress."' WHERE id='".$fromAddress."'";
190 $result = $this->_DBHandle
->exec($query);
191 if ($result === false)
192 throw new PHPExcel_Exception($this->_DBHandle
->lastErrorMsg());
195 } // function moveCell()
199 * Get a list of all cell addresses currently held in cache
203 public function getCellList() {
204 if ($this->_currentObjectID
!== null) {
208 $query = "SELECT id FROM kvp_".$this->_TableName
;
209 $cellIdsResult = $this->_DBHandle
->unbufferedQuery($query,SQLITE_ASSOC
);
210 if ($cellIdsResult === false)
211 throw new PHPExcel_Exception(sqlite_error_string($this->_DBHandle
->lastError()));
214 foreach($cellIdsResult as $row) {
215 $cellKeys[] = $row['id'];
219 } // function getCellList()
223 * Clone the cell collection
225 * @param PHPExcel_Worksheet $parent The new worksheet
228 public function copyCellCollection(PHPExcel_Worksheet
$parent) {
229 $this->_currentCellIsDirty
;
232 // Get a new id for the new table name
233 $tableName = str_replace('.','_',$this->_getUniqueID());
234 if (!$this->_DBHandle
->queryExec('CREATE TABLE kvp_'.$tableName.' (id VARCHAR(12) PRIMARY KEY, value BLOB)
235 AS SELECT * FROM kvp_'.$this->_TableName
))
236 throw new PHPExcel_Exception(sqlite_error_string($this->_DBHandle
->lastError()));
238 // Copy the existing cell cache file
239 $this->_TableName
= $tableName;
240 } // function copyCellCollection()
244 * Clear the cell collection and disconnect from our parent
248 public function unsetWorksheetCells() {
249 if(!is_null($this->_currentObject
)) {
250 $this->_currentObject
->detach();
251 $this->_currentObject
= $this->_currentObjectID
= null;
253 // detach ourself from the worksheet, so that it can then delete this object successfully
254 $this->_parent
= null;
256 // Close down the temporary cache file
258 } // function unsetWorksheetCells()
262 * Initialise this new cell collection
264 * @param PHPExcel_Worksheet $parent The worksheet for this cell collection
266 public function __construct(PHPExcel_Worksheet
$parent) {
267 parent
::__construct($parent);
268 if (is_null($this->_DBHandle
)) {
269 $this->_TableName
= str_replace('.','_',$this->_getUniqueID());
270 $_DBName = ':memory:';
272 $this->_DBHandle
= new SQLiteDatabase($_DBName);
273 if ($this->_DBHandle
=== false)
274 throw new PHPExcel_Exception(sqlite_error_string($this->_DBHandle
->lastError()));
275 if (!$this->_DBHandle
->queryExec('CREATE TABLE kvp_'.$this->_TableName
.' (id VARCHAR(12) PRIMARY KEY, value BLOB)'))
276 throw new PHPExcel_Exception(sqlite_error_string($this->_DBHandle
->lastError()));
278 } // function __construct()
282 * Destroy this cell collection
284 public function __destruct() {
285 if (!is_null($this->_DBHandle
)) {
286 $this->_DBHandle
->queryExec('DROP TABLE kvp_'.$this->_TableName
);
288 $this->_DBHandle
= null;
289 } // function __destruct()
293 * Identify whether the caching method is currently available
294 * Some methods are dependent on the availability of certain extensions being enabled in the PHP build
298 public static function cacheMethodIsAvailable() {
299 if (!function_exists('sqlite_open')) {