Вход Регистрация
Файл: concrete5.7.5.6/concrete/vendor/tedivm/stash/src/Stash/Driver/Sub/Sqlite.php
Строк: 230
<?php

/*
 * This file is part of the Stash package.
 *
 * (c) Robert Hafner <tedivm@tedivm.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace StashDriverSub;

use 
StashExceptionRuntimeException;
use 
StashExceptionInvalidArgumentException;

/**
 * Class Sqlite
 *
 * This SQLite subdriver is used by the main Sqlite driver for interacting with the SQLite extension.
 *
 * @internal
 * @package Stash
 * @author  Robert Hafner <tedivm@tedivm.com>
 */
class Sqlite
{
    
/**
     * Directory where the SQLite databases are stored.
     *
     * @var string
     */
    
protected $path;

    
/**
     * Output of buildDriver, used to interact with the relevant SQLite extension.
     *
     * @var SQLiteDatabase
     */
    
protected $driver;

    
/**
     * The SQLite query used to generate the database.
     *
     * @var string
     */
    
protected $creationSql 'CREATE TABLE cacheStore (
                              key TEXT UNIQUE ON CONFLICT REPLACE,
                              expiration INTEGER,
                              encoding TEXT,
                              data BLOB
                              );
                              CREATE INDEX keyIndex ON cacheStore (key);'
;

    
/**
     * File permissions of new SQLite databases.
     *
     * @var string
     */
    
protected $filePermissions;

    
/**
     * File permissions of new directories leading to SQLite databases.
     *
     * @var string
     */
    
protected $dirPermissions;

    
/**
     * Amounts of time to wait for the SQLite engine before timing out.
     *
     * @var int milliseconds
     */
    
protected $busyTimeout;

    
/**
     * The appropriate response code to use when retrieving data.
     *
     * @var int
     */
    
protected $responseCode;

    
/**
     * @param string $path
     * @param string $directoryPermission
     * @param string $filePermission
     * @param int    $busyTimeout
     */
    
public function __construct($path$directoryPermission$filePermission$busyTimeout)
    {
        
$this->path $path;
        
$this->filePermissions $filePermission;
        
$this->dirPermissions $directoryPermission;
        
$this->busyTimeout $busyTimeout;
        
$this->responseCode 1// SQLITE_ASSOC
    
}

    
/**
     * Clear out driver, closing file sockets.
     */
    
public function __destruct()
    {
        
$this->driver null;
    }

    
/**
     * Retrieves data from cache store.
     *
     * @param  string     $key
     * @return bool|mixed
     */
    
public function get($key)
    {
        if (!(
$driver $this->getDriver())) {
            return 
false;
        }

        
$query $driver->query("SELECT * FROM cacheStore WHERE key LIKE '{$key}'");
        if (
$query === false) {
            return 
false;
        }

        if (
$resultArray $query->fetch($this->responseCode)) {
            return 
unserialize(base64_decode($resultArray['data']));
        }

        return 
false;
    }

    
/**
     * Stores data in sqlite database.
     *
     * @param  string $key
     * @param  mixed  $value
     * @param  int    $expiration
     * @return bool
     */
    
public function set($key$value$expiration)
    {
        if (!(
$driver $this->getDriver())) {
            return 
false;
        }

        
$data base64_encode(serialize($value));

        
$contentLength strlen($data);
        if (
$contentLength 100000) {
            
$this->setTimeout($this->busyTimeout * (ceil($contentLength 100000))); // .5s per 100k
        
}

        
$driver->query("INSERT INTO cacheStore (key, expiration, data)
                                  VALUES ('
{$key}', '{$expiration}', '{$data}')");

        return 
true;
    }

    
/**
     * Clears data from database. If a key is defined only it and it's children are removed. If everything is set to be
     * cleared then the database itself is deleted off disk.
     *
     * @param  null|string $key
     * @return bool
     */
    
public function clear($key null)
    {
        
// return true if the cache is already empty
        
if (!($driver $this->getDriver())) {
            return 
true;
        }

        if (!isset(
$key)) {
            unset(
$driver);
            
$this->driver null;
            
$this->driver false;
            
StashUtilities::deleteRecursive($this->path);
        } else {
            
$driver->query("DELETE FROM cacheStore WHERE key LIKE '{$key}%'");
        }

        return 
true;
    }

    
/**
     * Old data is removed and the "vacuum" operation is run.
     *
     * @return bool
     */
    
public function purge()
    {
        if (!(
$driver $this->getDriver())) {
            return 
false;
        }

        
$driver->query('DELETE FROM cacheStore WHERE expiration < ' time());
        
$driver->query('VACUUM');

        return 
true;
    }

    
/**
     * Filesystem integrity and permissions are checked and exceptions thrown for relevant issues.
     *
     * @throws StashExceptionInvalidArgumentException
     * @throws StashExceptionRuntimeException
     */
    
public function checkFileSystemPermissions()
    {
        if (!isset(
$this->path)) {
            throw new 
RuntimeException('No cache path is set.');
        }

        if (!
is_writable($this->path) && !is_writable(dirname($this->path))) {
            throw new 
InvalidArgumentException('The cache sqlite file is not writable.');
        }
    }

    
/**
     * Returns true if the SQLiteDatabase class exists.
     *
     * @return bool
     */
    
public static function isAvailable()
    {
        return 
class_exists('SQLiteDatabase'false);
    }

    
/**
     * Tells the SQLite driver how long to wait for data to be written.
     *
     * @param  int  $milliseconds
     * @return bool
     */
    
protected function setTimeout($milliseconds)
    {
        if (!(
$driver $this->getDriver())) {
            return 
false;
        }
        
$driver->busyTimeout($milliseconds);
    }

    
/**
     * Retrieves the relevant SQLite driver, creating the database file if necessary.
     *
     * @return SQLiteDatabase
     * @throws StashExceptionRuntimeException
     */
    
protected function getDriver()
    {
        if (isset(
$this->driver) && $this->driver !== false) {
            return 
$this->driver;
        }

        if (!
file_exists($this->path)) {
            
$dir $this->path;

            
// Since PHP will understand paths with mixed slashes- both the windows  and unix / variants- we have
            // to test for both and see which one is the last in the string.
            
$pos1 strrpos($this->path'/');
            
$pos2 strrpos($this->path'\');

            if ($pos1 || $pos2) {
                $pos = $pos1 >= $pos2 ? $pos1 : $pos2;
                $dir = substr($this->path, 0, $pos);
            }

            if (!is_dir($dir)) {
                mkdir($dir, $this->dirPermissions, true);
            }
            $runInstall = true;
        } else {
            $runInstall = false;
        }

        $db = $this->buildDriver();

        if ($runInstall && !$db->query($this->creationSql)) {
            unlink($this->path);
            throw new RuntimeException('
Unable to set SQLitestructure');
        }
        $this->driver = $db;

        // prevent the cache from getting hungup waiting on a return
        $this->setTimeout($this->busyTimeout);

        return $db;
    }

    /**
     * Creates the actual database driver itself.
     *
     * @return SQLiteDatabase
     * @throws StashExceptionRuntimeException
     */
    protected function buildDriver()
    {
        if (!$db = new SQLiteDatabase($this->path, $this->filePermissions, $errorMessage)) {
            throw new RuntimeException('
Unable to open SQLite Database' . $errorMessage);
        }

        return $db;
    }
}
Онлайн: 0
Реклама