| @@ -0,0 +1,5 @@ | |||
| <?xml version="1.0" encoding="UTF-8"?> | |||
| <buildpath> | |||
| <buildpathentry kind="src" path=""/> | |||
| <buildpathentry kind="con" path="org.eclipse.php.core.LANGUAGE"/> | |||
| </buildpath> | |||
| @@ -0,0 +1,22 @@ | |||
| <?xml version="1.0" encoding="UTF-8"?> | |||
| <projectDescription> | |||
| <name>dedicatedip</name> | |||
| <comment></comment> | |||
| <projects> | |||
| </projects> | |||
| <buildSpec> | |||
| <buildCommand> | |||
| <name>org.eclipse.wst.validation.validationbuilder</name> | |||
| <arguments> | |||
| </arguments> | |||
| </buildCommand> | |||
| <buildCommand> | |||
| <name>org.eclipse.dltk.core.scriptbuilder</name> | |||
| <arguments> | |||
| </arguments> | |||
| </buildCommand> | |||
| </buildSpec> | |||
| <natures> | |||
| <nature>org.eclipse.php.core.PHPNature</nature> | |||
| </natures> | |||
| </projectDescription> | |||
| @@ -0,0 +1,3 @@ | |||
| eclipse.preferences.version=1 | |||
| include_path=0;/dedicatedip | |||
| use_asp_tags_as_php=false | |||
| @@ -0,0 +1,5 @@ | |||
| { | |||
| "require": { | |||
| "sergeytsalkov/meekrodb": "2.3.*" | |||
| } | |||
| } | |||
| @@ -0,0 +1,67 @@ | |||
| { | |||
| "_readme": [ | |||
| "This file locks the dependencies of your project to a known state", | |||
| "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", | |||
| "This file is @generated automatically" | |||
| ], | |||
| "content-hash": "cc9d0acf6729c4427cfdbe3415e626ba", | |||
| "packages": [ | |||
| { | |||
| "name": "sergeytsalkov/meekrodb", | |||
| "version": "v2.3.1", | |||
| "source": { | |||
| "type": "git", | |||
| "url": "https://github.com/SergeyTsalkov/meekrodb.git", | |||
| "reference": "e8c19ca2f8ed6a0fd0012c6c97e78aac80fded30" | |||
| }, | |||
| "dist": { | |||
| "type": "zip", | |||
| "url": "https://api.github.com/repos/SergeyTsalkov/meekrodb/zipball/e8c19ca2f8ed6a0fd0012c6c97e78aac80fded30", | |||
| "reference": "e8c19ca2f8ed6a0fd0012c6c97e78aac80fded30", | |||
| "shasum": "" | |||
| }, | |||
| "require": { | |||
| "php": ">=5.2.0" | |||
| }, | |||
| "type": "library", | |||
| "autoload": { | |||
| "classmap": [ | |||
| "db.class.php" | |||
| ] | |||
| }, | |||
| "notification-url": "https://packagist.org/downloads/", | |||
| "license": [ | |||
| "LGPL-3.0" | |||
| ], | |||
| "authors": [ | |||
| { | |||
| "name": "Sergey Tsalkov", | |||
| "email": "stsalkov@gmail.com" | |||
| } | |||
| ], | |||
| "description": "The Simple PHP/MySQL Library", | |||
| "homepage": "http://www.meekro.com", | |||
| "keywords": [ | |||
| "database", | |||
| "mysql", | |||
| "mysqli", | |||
| "pdo" | |||
| ], | |||
| "support": { | |||
| "email": "support@meekro.com", | |||
| "issues": "https://github.com/SergeyTsalkov/meekrodb/issues", | |||
| "source": "https://github.com/SergeyTsalkov/meekrodb/tree/v2.3.1" | |||
| }, | |||
| "time": "2020-07-10T01:13:31+00:00" | |||
| } | |||
| ], | |||
| "packages-dev": [], | |||
| "aliases": [], | |||
| "minimum-stability": "stable", | |||
| "stability-flags": [], | |||
| "prefer-stable": false, | |||
| "prefer-lowest": false, | |||
| "platform": [], | |||
| "platform-dev": [], | |||
| "plugin-api-version": "2.0.0" | |||
| } | |||
| @@ -0,0 +1,6 @@ | |||
| <?php | |||
| $dbhost = "localhost"; | |||
| $dbuser = "license"; | |||
| $dbpass = "Nbc3PhYCn3Fn0a7"; | |||
| $dbname = "license"; | |||
| @@ -0,0 +1,21 @@ | |||
| ----Mon, 30 Nov 2020 13:44:22 +1100 --- | |||
| {"license":"XDTG-ADQE-DQERG-QERFDA1","mid":"1606703887734-5558960d-7efe-411c-a247-6931b5049b5a"} | |||
| ----------Mon, 30 Nov 2020 13:59:23 +1100 --- | |||
| {"license":"VOL-1XDTG-ADQE-DQERG-QERFDA","mid":"1606704894892-7dfa9c36-81d3-4d1b-93a9-2885d06df415"} | |||
| ----------Mon, 30 Nov 2020 17:04:44 +1100 --- | |||
| ----------Mon, 30 Nov 2020 17:09:15 +1100 --- | |||
| ----------Mon, 30 Nov 2020 21:19:29 +1100 --- | |||
| ------ | |||
| @@ -0,0 +1,46 @@ | |||
| <?php | |||
| require "vendor/autoload.php"; | |||
| require "config.php"; | |||
| // Takes raw data from the request | |||
| $json = file_get_contents('php://input'); | |||
| // | |||
| // Converts it into a PHP object | |||
| $data = json_decode($json); | |||
| $db = new MeekroDB($dbhost, $dbuser, $dbpass,$dbname); | |||
| $result = $db->query("SELECT * FROM servers"); | |||
| foreach ($result as $row) { | |||
| echo "id: " . $row['id'] . "\n"; | |||
| echo "host: " . $row['host'] . "\n"; | |||
| echo "type: " . $row['type'] . "\n"; | |||
| echo "-------------\n"; | |||
| } | |||
| $now = date(DATE_RFC2822); | |||
| if ( $data->license != "VOL-XDTG-ADQE-DQERG-QERFDA" ) { | |||
| echo "invalid license"; | |||
| file_put_contents(dirname(__FILE__) . "/fail.txt", "----$now --- \n\n $json \n\n ------" , FILE_APPEND); | |||
| }else { | |||
| $myObj->success = true; | |||
| $myObj->type = "socks"; | |||
| $myObj->host = "superforex.vip.biukop.com.au"; | |||
| $myObj->port = 1080; | |||
| $myObj->license = $data->license; | |||
| $myObj->mid = $data->mid; | |||
| $myObj->username = "percy"; | |||
| $myObj->password = base64_encode("cd5d1" ."superforex" . "12#!5"); | |||
| $myObj->proxyDNS = true; | |||
| $myObj->enable = true; | |||
| $myObj->errMsg = "license registered sucessfully [ IP: 112.213.36.86 ] "; | |||
| $myObj->link = "https://hk-01.biukop.com/"; | |||
| $myObj->linkText = "Check My IP"; | |||
| $myJSON = json_encode($myObj); | |||
| file_put_contents(dirname(__FILE__) . "/success.txt", "$now , license: $myObj->license , mid: $myObj->mid\n", FILE_APPEND); | |||
| echo $myJSON; | |||
| } | |||
| ?> | |||
| @@ -0,0 +1,19 @@ | |||
| Mon, 30 Nov 2020 13:42:50 +1100 , license: XDTG-ADQE-DQERG-QERFDA , mid: 1606703887734-5558960d-7efe-411c-a247-6931b5049b5a | |||
| Mon, 30 Nov 2020 13:43:06 +1100 , license: XDTG-ADQE-DQERG-QERFDA , mid: 1606703887734-5558960d-7efe-411c-a247-6931b5049b5a | |||
| Mon, 30 Nov 2020 13:44:51 +1100 , license: XDTG-ADQE-DQERG-QERFDA , mid: 1606703887734-5558960d-7efe-411c-a247-6931b5049b5a | |||
| Mon, 30 Nov 2020 13:45:47 +1100 , license: XDTG-ADQE-DQERG-QERFDA , mid: 1606703887734-5558960d-7efe-411c-a247-6931b5049b5a | |||
| Mon, 30 Nov 2020 13:45:59 +1100 , license: XDTG-ADQE-DQERG-QERFDA , mid: 1606703887734-5558960d-7efe-411c-a247-6931b5049b5a | |||
| Mon, 30 Nov 2020 13:46:11 +1100 , license: XDTG-ADQE-DQERG-QERFDA , mid: 1606703887734-5558960d-7efe-411c-a247-6931b5049b5a | |||
| Mon, 30 Nov 2020 13:47:07 +1100 , license: XDTG-ADQE-DQERG-QERFDA , mid: 1606703887734-5558960d-7efe-411c-a247-6931b5049b5a | |||
| Mon, 30 Nov 2020 13:48:51 +1100 , license: XDTG-ADQE-DQERG-QERFDA , mid: 1606703887734-5558960d-7efe-411c-a247-6931b5049b5a | |||
| Mon, 30 Nov 2020 13:49:06 +1100 , license: XDTG-ADQE-DQERG-QERFDA , mid: 1606703887734-5558960d-7efe-411c-a247-6931b5049b5a | |||
| Mon, 30 Nov 2020 13:54:30 +1100 , license: XDTG-ADQE-DQERG-QERFDA , mid: 1606703887734-5558960d-7efe-411c-a247-6931b5049b5a | |||
| Mon, 30 Nov 2020 13:55:07 +1100 , license: XDTG-ADQE-DQERG-QERFDA , mid: 1606704894892-7dfa9c36-81d3-4d1b-93a9-2885d06df415 | |||
| Mon, 30 Nov 2020 13:59:21 +1100 , license: VOL-XDTG-ADQE-DQERG-QERFDA , mid: 1606704894892-7dfa9c36-81d3-4d1b-93a9-2885d06df415 | |||
| Mon, 30 Nov 2020 13:59:24 +1100 , license: VOL-XDTG-ADQE-DQERG-QERFDA , mid: 1606704894892-7dfa9c36-81d3-4d1b-93a9-2885d06df415 | |||
| Mon, 30 Nov 2020 15:03:59 +1100 , license: VOL-XDTG-ADQE-DQERG-QERFDA , mid: 1606709032059-bf7a8a2a-62c8-4f45-a44f-1ffb2337fd3c | |||
| Mon, 30 Nov 2020 18:10:29 +1100 , license: VOL-XDTG-ADQE-DQERG-QERFDA , mid: test-mid1 | |||
| Mon, 30 Nov 2020 21:40:47 +1100 , license: VOL-XDTG-ADQE-DQERG-QERFDA , mid: test-mid1 | |||
| Mon, 30 Nov 2020 21:44:17 +1100 , license: VOL-XDTG-ADQE-DQERG-QERFDA , mid: test-mid1 | |||
| Mon, 30 Nov 2020 22:44:45 +1100 , license: VOL-XDTG-ADQE-DQERG-QERFDA , mid: test-mid1 | |||
| Mon, 30 Nov 2020 23:38:33 +1100 , license: VOL-XDTG-ADQE-DQERG-QERFDA , mid: test-mid1 | |||
| @@ -0,0 +1,7 @@ | |||
| <?php | |||
| // autoload.php @generated by Composer | |||
| require_once __DIR__ . '/composer/autoload_real.php'; | |||
| return ComposerAutoloaderInit9e6487acd796bef3591a49601b8f5a50::getLoader(); | |||
| @@ -0,0 +1,445 @@ | |||
| <?php | |||
| /* | |||
| * This file is part of Composer. | |||
| * | |||
| * (c) Nils Adermann <naderman@naderman.de> | |||
| * Jordi Boggiano <j.boggiano@seld.be> | |||
| * | |||
| * For the full copyright and license information, please view the LICENSE | |||
| * file that was distributed with this source code. | |||
| */ | |||
| namespace Composer\Autoload; | |||
| /** | |||
| * ClassLoader implements a PSR-0, PSR-4 and classmap class loader. | |||
| * | |||
| * $loader = new \Composer\Autoload\ClassLoader(); | |||
| * | |||
| * // register classes with namespaces | |||
| * $loader->add('Symfony\Component', __DIR__.'/component'); | |||
| * $loader->add('Symfony', __DIR__.'/framework'); | |||
| * | |||
| * // activate the autoloader | |||
| * $loader->register(); | |||
| * | |||
| * // to enable searching the include path (eg. for PEAR packages) | |||
| * $loader->setUseIncludePath(true); | |||
| * | |||
| * In this example, if you try to use a class in the Symfony\Component | |||
| * namespace or one of its children (Symfony\Component\Console for instance), | |||
| * the autoloader will first look for the class under the component/ | |||
| * directory, and it will then fallback to the framework/ directory if not | |||
| * found before giving up. | |||
| * | |||
| * This class is loosely based on the Symfony UniversalClassLoader. | |||
| * | |||
| * @author Fabien Potencier <fabien@symfony.com> | |||
| * @author Jordi Boggiano <j.boggiano@seld.be> | |||
| * @see https://www.php-fig.org/psr/psr-0/ | |||
| * @see https://www.php-fig.org/psr/psr-4/ | |||
| */ | |||
| class ClassLoader | |||
| { | |||
| // PSR-4 | |||
| private $prefixLengthsPsr4 = array(); | |||
| private $prefixDirsPsr4 = array(); | |||
| private $fallbackDirsPsr4 = array(); | |||
| // PSR-0 | |||
| private $prefixesPsr0 = array(); | |||
| private $fallbackDirsPsr0 = array(); | |||
| private $useIncludePath = false; | |||
| private $classMap = array(); | |||
| private $classMapAuthoritative = false; | |||
| private $missingClasses = array(); | |||
| private $apcuPrefix; | |||
| public function getPrefixes() | |||
| { | |||
| if (!empty($this->prefixesPsr0)) { | |||
| return call_user_func_array('array_merge', array_values($this->prefixesPsr0)); | |||
| } | |||
| return array(); | |||
| } | |||
| public function getPrefixesPsr4() | |||
| { | |||
| return $this->prefixDirsPsr4; | |||
| } | |||
| public function getFallbackDirs() | |||
| { | |||
| return $this->fallbackDirsPsr0; | |||
| } | |||
| public function getFallbackDirsPsr4() | |||
| { | |||
| return $this->fallbackDirsPsr4; | |||
| } | |||
| public function getClassMap() | |||
| { | |||
| return $this->classMap; | |||
| } | |||
| /** | |||
| * @param array $classMap Class to filename map | |||
| */ | |||
| public function addClassMap(array $classMap) | |||
| { | |||
| if ($this->classMap) { | |||
| $this->classMap = array_merge($this->classMap, $classMap); | |||
| } else { | |||
| $this->classMap = $classMap; | |||
| } | |||
| } | |||
| /** | |||
| * Registers a set of PSR-0 directories for a given prefix, either | |||
| * appending or prepending to the ones previously set for this prefix. | |||
| * | |||
| * @param string $prefix The prefix | |||
| * @param array|string $paths The PSR-0 root directories | |||
| * @param bool $prepend Whether to prepend the directories | |||
| */ | |||
| public function add($prefix, $paths, $prepend = false) | |||
| { | |||
| if (!$prefix) { | |||
| if ($prepend) { | |||
| $this->fallbackDirsPsr0 = array_merge( | |||
| (array) $paths, | |||
| $this->fallbackDirsPsr0 | |||
| ); | |||
| } else { | |||
| $this->fallbackDirsPsr0 = array_merge( | |||
| $this->fallbackDirsPsr0, | |||
| (array) $paths | |||
| ); | |||
| } | |||
| return; | |||
| } | |||
| $first = $prefix[0]; | |||
| if (!isset($this->prefixesPsr0[$first][$prefix])) { | |||
| $this->prefixesPsr0[$first][$prefix] = (array) $paths; | |||
| return; | |||
| } | |||
| if ($prepend) { | |||
| $this->prefixesPsr0[$first][$prefix] = array_merge( | |||
| (array) $paths, | |||
| $this->prefixesPsr0[$first][$prefix] | |||
| ); | |||
| } else { | |||
| $this->prefixesPsr0[$first][$prefix] = array_merge( | |||
| $this->prefixesPsr0[$first][$prefix], | |||
| (array) $paths | |||
| ); | |||
| } | |||
| } | |||
| /** | |||
| * Registers a set of PSR-4 directories for a given namespace, either | |||
| * appending or prepending to the ones previously set for this namespace. | |||
| * | |||
| * @param string $prefix The prefix/namespace, with trailing '\\' | |||
| * @param array|string $paths The PSR-4 base directories | |||
| * @param bool $prepend Whether to prepend the directories | |||
| * | |||
| * @throws \InvalidArgumentException | |||
| */ | |||
| public function addPsr4($prefix, $paths, $prepend = false) | |||
| { | |||
| if (!$prefix) { | |||
| // Register directories for the root namespace. | |||
| if ($prepend) { | |||
| $this->fallbackDirsPsr4 = array_merge( | |||
| (array) $paths, | |||
| $this->fallbackDirsPsr4 | |||
| ); | |||
| } else { | |||
| $this->fallbackDirsPsr4 = array_merge( | |||
| $this->fallbackDirsPsr4, | |||
| (array) $paths | |||
| ); | |||
| } | |||
| } elseif (!isset($this->prefixDirsPsr4[$prefix])) { | |||
| // Register directories for a new namespace. | |||
| $length = strlen($prefix); | |||
| if ('\\' !== $prefix[$length - 1]) { | |||
| throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); | |||
| } | |||
| $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; | |||
| $this->prefixDirsPsr4[$prefix] = (array) $paths; | |||
| } elseif ($prepend) { | |||
| // Prepend directories for an already registered namespace. | |||
| $this->prefixDirsPsr4[$prefix] = array_merge( | |||
| (array) $paths, | |||
| $this->prefixDirsPsr4[$prefix] | |||
| ); | |||
| } else { | |||
| // Append directories for an already registered namespace. | |||
| $this->prefixDirsPsr4[$prefix] = array_merge( | |||
| $this->prefixDirsPsr4[$prefix], | |||
| (array) $paths | |||
| ); | |||
| } | |||
| } | |||
| /** | |||
| * Registers a set of PSR-0 directories for a given prefix, | |||
| * replacing any others previously set for this prefix. | |||
| * | |||
| * @param string $prefix The prefix | |||
| * @param array|string $paths The PSR-0 base directories | |||
| */ | |||
| public function set($prefix, $paths) | |||
| { | |||
| if (!$prefix) { | |||
| $this->fallbackDirsPsr0 = (array) $paths; | |||
| } else { | |||
| $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths; | |||
| } | |||
| } | |||
| /** | |||
| * Registers a set of PSR-4 directories for a given namespace, | |||
| * replacing any others previously set for this namespace. | |||
| * | |||
| * @param string $prefix The prefix/namespace, with trailing '\\' | |||
| * @param array|string $paths The PSR-4 base directories | |||
| * | |||
| * @throws \InvalidArgumentException | |||
| */ | |||
| public function setPsr4($prefix, $paths) | |||
| { | |||
| if (!$prefix) { | |||
| $this->fallbackDirsPsr4 = (array) $paths; | |||
| } else { | |||
| $length = strlen($prefix); | |||
| if ('\\' !== $prefix[$length - 1]) { | |||
| throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); | |||
| } | |||
| $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; | |||
| $this->prefixDirsPsr4[$prefix] = (array) $paths; | |||
| } | |||
| } | |||
| /** | |||
| * Turns on searching the include path for class files. | |||
| * | |||
| * @param bool $useIncludePath | |||
| */ | |||
| public function setUseIncludePath($useIncludePath) | |||
| { | |||
| $this->useIncludePath = $useIncludePath; | |||
| } | |||
| /** | |||
| * Can be used to check if the autoloader uses the include path to check | |||
| * for classes. | |||
| * | |||
| * @return bool | |||
| */ | |||
| public function getUseIncludePath() | |||
| { | |||
| return $this->useIncludePath; | |||
| } | |||
| /** | |||
| * Turns off searching the prefix and fallback directories for classes | |||
| * that have not been registered with the class map. | |||
| * | |||
| * @param bool $classMapAuthoritative | |||
| */ | |||
| public function setClassMapAuthoritative($classMapAuthoritative) | |||
| { | |||
| $this->classMapAuthoritative = $classMapAuthoritative; | |||
| } | |||
| /** | |||
| * Should class lookup fail if not found in the current class map? | |||
| * | |||
| * @return bool | |||
| */ | |||
| public function isClassMapAuthoritative() | |||
| { | |||
| return $this->classMapAuthoritative; | |||
| } | |||
| /** | |||
| * APCu prefix to use to cache found/not-found classes, if the extension is enabled. | |||
| * | |||
| * @param string|null $apcuPrefix | |||
| */ | |||
| public function setApcuPrefix($apcuPrefix) | |||
| { | |||
| $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null; | |||
| } | |||
| /** | |||
| * The APCu prefix in use, or null if APCu caching is not enabled. | |||
| * | |||
| * @return string|null | |||
| */ | |||
| public function getApcuPrefix() | |||
| { | |||
| return $this->apcuPrefix; | |||
| } | |||
| /** | |||
| * Registers this instance as an autoloader. | |||
| * | |||
| * @param bool $prepend Whether to prepend the autoloader or not | |||
| */ | |||
| public function register($prepend = false) | |||
| { | |||
| spl_autoload_register(array($this, 'loadClass'), true, $prepend); | |||
| } | |||
| /** | |||
| * Unregisters this instance as an autoloader. | |||
| */ | |||
| public function unregister() | |||
| { | |||
| spl_autoload_unregister(array($this, 'loadClass')); | |||
| } | |||
| /** | |||
| * Loads the given class or interface. | |||
| * | |||
| * @param string $class The name of the class | |||
| * @return bool|null True if loaded, null otherwise | |||
| */ | |||
| public function loadClass($class) | |||
| { | |||
| if ($file = $this->findFile($class)) { | |||
| includeFile($file); | |||
| return true; | |||
| } | |||
| } | |||
| /** | |||
| * Finds the path to the file where the class is defined. | |||
| * | |||
| * @param string $class The name of the class | |||
| * | |||
| * @return string|false The path if found, false otherwise | |||
| */ | |||
| public function findFile($class) | |||
| { | |||
| // class map lookup | |||
| if (isset($this->classMap[$class])) { | |||
| return $this->classMap[$class]; | |||
| } | |||
| if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) { | |||
| return false; | |||
| } | |||
| if (null !== $this->apcuPrefix) { | |||
| $file = apcu_fetch($this->apcuPrefix.$class, $hit); | |||
| if ($hit) { | |||
| return $file; | |||
| } | |||
| } | |||
| $file = $this->findFileWithExtension($class, '.php'); | |||
| // Search for Hack files if we are running on HHVM | |||
| if (false === $file && defined('HHVM_VERSION')) { | |||
| $file = $this->findFileWithExtension($class, '.hh'); | |||
| } | |||
| if (null !== $this->apcuPrefix) { | |||
| apcu_add($this->apcuPrefix.$class, $file); | |||
| } | |||
| if (false === $file) { | |||
| // Remember that this class does not exist. | |||
| $this->missingClasses[$class] = true; | |||
| } | |||
| return $file; | |||
| } | |||
| private function findFileWithExtension($class, $ext) | |||
| { | |||
| // PSR-4 lookup | |||
| $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext; | |||
| $first = $class[0]; | |||
| if (isset($this->prefixLengthsPsr4[$first])) { | |||
| $subPath = $class; | |||
| while (false !== $lastPos = strrpos($subPath, '\\')) { | |||
| $subPath = substr($subPath, 0, $lastPos); | |||
| $search = $subPath . '\\'; | |||
| if (isset($this->prefixDirsPsr4[$search])) { | |||
| $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1); | |||
| foreach ($this->prefixDirsPsr4[$search] as $dir) { | |||
| if (file_exists($file = $dir . $pathEnd)) { | |||
| return $file; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } | |||
| // PSR-4 fallback dirs | |||
| foreach ($this->fallbackDirsPsr4 as $dir) { | |||
| if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) { | |||
| return $file; | |||
| } | |||
| } | |||
| // PSR-0 lookup | |||
| if (false !== $pos = strrpos($class, '\\')) { | |||
| // namespaced class name | |||
| $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1) | |||
| . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR); | |||
| } else { | |||
| // PEAR-like class name | |||
| $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext; | |||
| } | |||
| if (isset($this->prefixesPsr0[$first])) { | |||
| foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) { | |||
| if (0 === strpos($class, $prefix)) { | |||
| foreach ($dirs as $dir) { | |||
| if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { | |||
| return $file; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } | |||
| // PSR-0 fallback dirs | |||
| foreach ($this->fallbackDirsPsr0 as $dir) { | |||
| if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { | |||
| return $file; | |||
| } | |||
| } | |||
| // PSR-0 include paths. | |||
| if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) { | |||
| return $file; | |||
| } | |||
| return false; | |||
| } | |||
| } | |||
| /** | |||
| * Scope isolated include. | |||
| * | |||
| * Prevents access to $this/self from included files. | |||
| */ | |||
| function includeFile($file) | |||
| { | |||
| include $file; | |||
| } | |||
| @@ -0,0 +1,218 @@ | |||
| <?php | |||
| namespace Composer; | |||
| use Composer\Semver\VersionParser; | |||
| class InstalledVersions | |||
| { | |||
| private static $installed = array ( | |||
| 'root' => | |||
| array ( | |||
| 'pretty_version' => '1.0.0+no-version-set', | |||
| 'version' => '1.0.0.0', | |||
| 'aliases' => | |||
| array ( | |||
| ), | |||
| 'reference' => NULL, | |||
| 'name' => '__root__', | |||
| ), | |||
| 'versions' => | |||
| array ( | |||
| '__root__' => | |||
| array ( | |||
| 'pretty_version' => '1.0.0+no-version-set', | |||
| 'version' => '1.0.0.0', | |||
| 'aliases' => | |||
| array ( | |||
| ), | |||
| 'reference' => NULL, | |||
| ), | |||
| 'sergeytsalkov/meekrodb' => | |||
| array ( | |||
| 'pretty_version' => 'v2.3.1', | |||
| 'version' => '2.3.1.0', | |||
| 'aliases' => | |||
| array ( | |||
| ), | |||
| 'reference' => 'e8c19ca2f8ed6a0fd0012c6c97e78aac80fded30', | |||
| ), | |||
| ), | |||
| ); | |||
| public static function getInstalledPackages() | |||
| { | |||
| return array_keys(self::$installed['versions']); | |||
| } | |||
| public static function isInstalled($packageName) | |||
| { | |||
| return isset(self::$installed['versions'][$packageName]); | |||
| } | |||
| public static function satisfies(VersionParser $parser, $packageName, $constraint) | |||
| { | |||
| $constraint = $parser->parseConstraints($constraint); | |||
| $provided = $parser->parseConstraints(self::getVersionRanges($packageName)); | |||
| return $provided->matches($constraint); | |||
| } | |||
| public static function getVersionRanges($packageName) | |||
| { | |||
| if (!isset(self::$installed['versions'][$packageName])) { | |||
| throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); | |||
| } | |||
| $ranges = array(); | |||
| if (isset(self::$installed['versions'][$packageName]['pretty_version'])) { | |||
| $ranges[] = self::$installed['versions'][$packageName]['pretty_version']; | |||
| } | |||
| if (array_key_exists('aliases', self::$installed['versions'][$packageName])) { | |||
| $ranges = array_merge($ranges, self::$installed['versions'][$packageName]['aliases']); | |||
| } | |||
| if (array_key_exists('replaced', self::$installed['versions'][$packageName])) { | |||
| $ranges = array_merge($ranges, self::$installed['versions'][$packageName]['replaced']); | |||
| } | |||
| if (array_key_exists('provided', self::$installed['versions'][$packageName])) { | |||
| $ranges = array_merge($ranges, self::$installed['versions'][$packageName]['provided']); | |||
| } | |||
| return implode(' || ', $ranges); | |||
| } | |||
| public static function getVersion($packageName) | |||
| { | |||
| if (!isset(self::$installed['versions'][$packageName])) { | |||
| throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); | |||
| } | |||
| if (!isset(self::$installed['versions'][$packageName]['version'])) { | |||
| return null; | |||
| } | |||
| return self::$installed['versions'][$packageName]['version']; | |||
| } | |||
| public static function getPrettyVersion($packageName) | |||
| { | |||
| if (!isset(self::$installed['versions'][$packageName])) { | |||
| throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); | |||
| } | |||
| if (!isset(self::$installed['versions'][$packageName]['pretty_version'])) { | |||
| return null; | |||
| } | |||
| return self::$installed['versions'][$packageName]['pretty_version']; | |||
| } | |||
| public static function getReference($packageName) | |||
| { | |||
| if (!isset(self::$installed['versions'][$packageName])) { | |||
| throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); | |||
| } | |||
| if (!isset(self::$installed['versions'][$packageName]['reference'])) { | |||
| return null; | |||
| } | |||
| return self::$installed['versions'][$packageName]['reference']; | |||
| } | |||
| public static function getRootPackage() | |||
| { | |||
| return self::$installed['root']; | |||
| } | |||
| public static function getRawData() | |||
| { | |||
| return self::$installed; | |||
| } | |||
| public static function reload($data) | |||
| { | |||
| self::$installed = $data; | |||
| } | |||
| } | |||
| @@ -0,0 +1,21 @@ | |||
| Copyright (c) Nils Adermann, Jordi Boggiano | |||
| Permission is hereby granted, free of charge, to any person obtaining a copy | |||
| of this software and associated documentation files (the "Software"), to deal | |||
| in the Software without restriction, including without limitation the rights | |||
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |||
| copies of the Software, and to permit persons to whom the Software is furnished | |||
| to do so, subject to the following conditions: | |||
| The above copyright notice and this permission notice shall be included in all | |||
| copies or substantial portions of the Software. | |||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |||
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |||
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |||
| THE SOFTWARE. | |||
| @@ -0,0 +1,17 @@ | |||
| <?php | |||
| // autoload_classmap.php @generated by Composer | |||
| $vendorDir = dirname(dirname(__FILE__)); | |||
| $baseDir = dirname($vendorDir); | |||
| return array( | |||
| 'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php', | |||
| 'DB' => $vendorDir . '/sergeytsalkov/meekrodb/db.class.php', | |||
| 'DBHelper' => $vendorDir . '/sergeytsalkov/meekrodb/db.class.php', | |||
| 'DBTransaction' => $vendorDir . '/sergeytsalkov/meekrodb/db.class.php', | |||
| 'MeekroDB' => $vendorDir . '/sergeytsalkov/meekrodb/db.class.php', | |||
| 'MeekroDBEval' => $vendorDir . '/sergeytsalkov/meekrodb/db.class.php', | |||
| 'MeekroDBException' => $vendorDir . '/sergeytsalkov/meekrodb/db.class.php', | |||
| 'WhereClause' => $vendorDir . '/sergeytsalkov/meekrodb/db.class.php', | |||
| ); | |||
| @@ -0,0 +1,9 @@ | |||
| <?php | |||
| // autoload_namespaces.php @generated by Composer | |||
| $vendorDir = dirname(dirname(__FILE__)); | |||
| $baseDir = dirname($vendorDir); | |||
| return array( | |||
| ); | |||
| @@ -0,0 +1,9 @@ | |||
| <?php | |||
| // autoload_psr4.php @generated by Composer | |||
| $vendorDir = dirname(dirname(__FILE__)); | |||
| $baseDir = dirname($vendorDir); | |||
| return array( | |||
| ); | |||
| @@ -0,0 +1,57 @@ | |||
| <?php | |||
| // autoload_real.php @generated by Composer | |||
| class ComposerAutoloaderInit9e6487acd796bef3591a49601b8f5a50 | |||
| { | |||
| private static $loader; | |||
| public static function loadClassLoader($class) | |||
| { | |||
| if ('Composer\Autoload\ClassLoader' === $class) { | |||
| require __DIR__ . '/ClassLoader.php'; | |||
| } | |||
| } | |||
| /** | |||
| * @return \Composer\Autoload\ClassLoader | |||
| */ | |||
| public static function getLoader() | |||
| { | |||
| if (null !== self::$loader) { | |||
| return self::$loader; | |||
| } | |||
| require __DIR__ . '/platform_check.php'; | |||
| spl_autoload_register(array('ComposerAutoloaderInit9e6487acd796bef3591a49601b8f5a50', 'loadClassLoader'), true, true); | |||
| self::$loader = $loader = new \Composer\Autoload\ClassLoader(); | |||
| spl_autoload_unregister(array('ComposerAutoloaderInit9e6487acd796bef3591a49601b8f5a50', 'loadClassLoader')); | |||
| $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded()); | |||
| if ($useStaticLoader) { | |||
| require __DIR__ . '/autoload_static.php'; | |||
| call_user_func(\Composer\Autoload\ComposerStaticInit9e6487acd796bef3591a49601b8f5a50::getInitializer($loader)); | |||
| } else { | |||
| $map = require __DIR__ . '/autoload_namespaces.php'; | |||
| foreach ($map as $namespace => $path) { | |||
| $loader->set($namespace, $path); | |||
| } | |||
| $map = require __DIR__ . '/autoload_psr4.php'; | |||
| foreach ($map as $namespace => $path) { | |||
| $loader->setPsr4($namespace, $path); | |||
| } | |||
| $classMap = require __DIR__ . '/autoload_classmap.php'; | |||
| if ($classMap) { | |||
| $loader->addClassMap($classMap); | |||
| } | |||
| } | |||
| $loader->register(true); | |||
| return $loader; | |||
| } | |||
| } | |||
| @@ -0,0 +1,27 @@ | |||
| <?php | |||
| // autoload_static.php @generated by Composer | |||
| namespace Composer\Autoload; | |||
| class ComposerStaticInit9e6487acd796bef3591a49601b8f5a50 | |||
| { | |||
| public static $classMap = array ( | |||
| 'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php', | |||
| 'DB' => __DIR__ . '/..' . '/sergeytsalkov/meekrodb/db.class.php', | |||
| 'DBHelper' => __DIR__ . '/..' . '/sergeytsalkov/meekrodb/db.class.php', | |||
| 'DBTransaction' => __DIR__ . '/..' . '/sergeytsalkov/meekrodb/db.class.php', | |||
| 'MeekroDB' => __DIR__ . '/..' . '/sergeytsalkov/meekrodb/db.class.php', | |||
| 'MeekroDBEval' => __DIR__ . '/..' . '/sergeytsalkov/meekrodb/db.class.php', | |||
| 'MeekroDBException' => __DIR__ . '/..' . '/sergeytsalkov/meekrodb/db.class.php', | |||
| 'WhereClause' => __DIR__ . '/..' . '/sergeytsalkov/meekrodb/db.class.php', | |||
| ); | |||
| public static function getInitializer(ClassLoader $loader) | |||
| { | |||
| return \Closure::bind(function () use ($loader) { | |||
| $loader->classMap = ComposerStaticInit9e6487acd796bef3591a49601b8f5a50::$classMap; | |||
| }, null, ClassLoader::class); | |||
| } | |||
| } | |||
| @@ -0,0 +1,57 @@ | |||
| { | |||
| "packages": [ | |||
| { | |||
| "name": "sergeytsalkov/meekrodb", | |||
| "version": "v2.3.1", | |||
| "version_normalized": "2.3.1.0", | |||
| "source": { | |||
| "type": "git", | |||
| "url": "https://github.com/SergeyTsalkov/meekrodb.git", | |||
| "reference": "e8c19ca2f8ed6a0fd0012c6c97e78aac80fded30" | |||
| }, | |||
| "dist": { | |||
| "type": "zip", | |||
| "url": "https://api.github.com/repos/SergeyTsalkov/meekrodb/zipball/e8c19ca2f8ed6a0fd0012c6c97e78aac80fded30", | |||
| "reference": "e8c19ca2f8ed6a0fd0012c6c97e78aac80fded30", | |||
| "shasum": "" | |||
| }, | |||
| "require": { | |||
| "php": ">=5.2.0" | |||
| }, | |||
| "time": "2020-07-10T01:13:31+00:00", | |||
| "type": "library", | |||
| "installation-source": "dist", | |||
| "autoload": { | |||
| "classmap": [ | |||
| "db.class.php" | |||
| ] | |||
| }, | |||
| "notification-url": "https://packagist.org/downloads/", | |||
| "license": [ | |||
| "LGPL-3.0" | |||
| ], | |||
| "authors": [ | |||
| { | |||
| "name": "Sergey Tsalkov", | |||
| "email": "stsalkov@gmail.com" | |||
| } | |||
| ], | |||
| "description": "The Simple PHP/MySQL Library", | |||
| "homepage": "http://www.meekro.com", | |||
| "keywords": [ | |||
| "database", | |||
| "mysql", | |||
| "mysqli", | |||
| "pdo" | |||
| ], | |||
| "support": { | |||
| "email": "support@meekro.com", | |||
| "issues": "https://github.com/SergeyTsalkov/meekrodb/issues", | |||
| "source": "https://github.com/SergeyTsalkov/meekrodb/tree/v2.3.1" | |||
| }, | |||
| "install-path": "../sergeytsalkov/meekrodb" | |||
| } | |||
| ], | |||
| "dev": true, | |||
| "dev-package-names": [] | |||
| } | |||
| @@ -0,0 +1,33 @@ | |||
| <?php return array ( | |||
| 'root' => | |||
| array ( | |||
| 'pretty_version' => '1.0.0+no-version-set', | |||
| 'version' => '1.0.0.0', | |||
| 'aliases' => | |||
| array ( | |||
| ), | |||
| 'reference' => NULL, | |||
| 'name' => '__root__', | |||
| ), | |||
| 'versions' => | |||
| array ( | |||
| '__root__' => | |||
| array ( | |||
| 'pretty_version' => '1.0.0+no-version-set', | |||
| 'version' => '1.0.0.0', | |||
| 'aliases' => | |||
| array ( | |||
| ), | |||
| 'reference' => NULL, | |||
| ), | |||
| 'sergeytsalkov/meekrodb' => | |||
| array ( | |||
| 'pretty_version' => 'v2.3.1', | |||
| 'version' => '2.3.1.0', | |||
| 'aliases' => | |||
| array ( | |||
| ), | |||
| 'reference' => 'e8c19ca2f8ed6a0fd0012c6c97e78aac80fded30', | |||
| ), | |||
| ), | |||
| ); | |||
| @@ -0,0 +1,26 @@ | |||
| <?php | |||
| // platform_check.php @generated by Composer | |||
| $issues = array(); | |||
| if (!(PHP_VERSION_ID >= 50200)) { | |||
| $issues[] = 'Your Composer dependencies require a PHP version ">= 5.2.0". You are running ' . PHP_VERSION . '.'; | |||
| } | |||
| if ($issues) { | |||
| if (!headers_sent()) { | |||
| header('HTTP/1.1 500 Internal Server Error'); | |||
| } | |||
| if (!ini_get('display_errors')) { | |||
| if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') { | |||
| fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL); | |||
| } elseif (!headers_sent()) { | |||
| echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL; | |||
| } | |||
| } | |||
| trigger_error( | |||
| 'Composer detected issues in your platform: ' . implode(' ', $issues), | |||
| E_USER_ERROR | |||
| ); | |||
| } | |||
| @@ -0,0 +1 @@ | |||
| simpletest/test_setup.php | |||
| @@ -0,0 +1,165 @@ | |||
| GNU LESSER GENERAL PUBLIC LICENSE | |||
| Version 3, 29 June 2007 | |||
| Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> | |||
| Everyone is permitted to copy and distribute verbatim copies | |||
| of this license document, but changing it is not allowed. | |||
| This version of the GNU Lesser General Public License incorporates | |||
| the terms and conditions of version 3 of the GNU General Public | |||
| License, supplemented by the additional permissions listed below. | |||
| 0. Additional Definitions. | |||
| As used herein, "this License" refers to version 3 of the GNU Lesser | |||
| General Public License, and the "GNU GPL" refers to version 3 of the GNU | |||
| General Public License. | |||
| "The Library" refers to a covered work governed by this License, | |||
| other than an Application or a Combined Work as defined below. | |||
| An "Application" is any work that makes use of an interface provided | |||
| by the Library, but which is not otherwise based on the Library. | |||
| Defining a subclass of a class defined by the Library is deemed a mode | |||
| of using an interface provided by the Library. | |||
| A "Combined Work" is a work produced by combining or linking an | |||
| Application with the Library. The particular version of the Library | |||
| with which the Combined Work was made is also called the "Linked | |||
| Version". | |||
| The "Minimal Corresponding Source" for a Combined Work means the | |||
| Corresponding Source for the Combined Work, excluding any source code | |||
| for portions of the Combined Work that, considered in isolation, are | |||
| based on the Application, and not on the Linked Version. | |||
| The "Corresponding Application Code" for a Combined Work means the | |||
| object code and/or source code for the Application, including any data | |||
| and utility programs needed for reproducing the Combined Work from the | |||
| Application, but excluding the System Libraries of the Combined Work. | |||
| 1. Exception to Section 3 of the GNU GPL. | |||
| You may convey a covered work under sections 3 and 4 of this License | |||
| without being bound by section 3 of the GNU GPL. | |||
| 2. Conveying Modified Versions. | |||
| If you modify a copy of the Library, and, in your modifications, a | |||
| facility refers to a function or data to be supplied by an Application | |||
| that uses the facility (other than as an argument passed when the | |||
| facility is invoked), then you may convey a copy of the modified | |||
| version: | |||
| a) under this License, provided that you make a good faith effort to | |||
| ensure that, in the event an Application does not supply the | |||
| function or data, the facility still operates, and performs | |||
| whatever part of its purpose remains meaningful, or | |||
| b) under the GNU GPL, with none of the additional permissions of | |||
| this License applicable to that copy. | |||
| 3. Object Code Incorporating Material from Library Header Files. | |||
| The object code form of an Application may incorporate material from | |||
| a header file that is part of the Library. You may convey such object | |||
| code under terms of your choice, provided that, if the incorporated | |||
| material is not limited to numerical parameters, data structure | |||
| layouts and accessors, or small macros, inline functions and templates | |||
| (ten or fewer lines in length), you do both of the following: | |||
| a) Give prominent notice with each copy of the object code that the | |||
| Library is used in it and that the Library and its use are | |||
| covered by this License. | |||
| b) Accompany the object code with a copy of the GNU GPL and this license | |||
| document. | |||
| 4. Combined Works. | |||
| You may convey a Combined Work under terms of your choice that, | |||
| taken together, effectively do not restrict modification of the | |||
| portions of the Library contained in the Combined Work and reverse | |||
| engineering for debugging such modifications, if you also do each of | |||
| the following: | |||
| a) Give prominent notice with each copy of the Combined Work that | |||
| the Library is used in it and that the Library and its use are | |||
| covered by this License. | |||
| b) Accompany the Combined Work with a copy of the GNU GPL and this license | |||
| document. | |||
| c) For a Combined Work that displays copyright notices during | |||
| execution, include the copyright notice for the Library among | |||
| these notices, as well as a reference directing the user to the | |||
| copies of the GNU GPL and this license document. | |||
| d) Do one of the following: | |||
| 0) Convey the Minimal Corresponding Source under the terms of this | |||
| License, and the Corresponding Application Code in a form | |||
| suitable for, and under terms that permit, the user to | |||
| recombine or relink the Application with a modified version of | |||
| the Linked Version to produce a modified Combined Work, in the | |||
| manner specified by section 6 of the GNU GPL for conveying | |||
| Corresponding Source. | |||
| 1) Use a suitable shared library mechanism for linking with the | |||
| Library. A suitable mechanism is one that (a) uses at run time | |||
| a copy of the Library already present on the user's computer | |||
| system, and (b) will operate properly with a modified version | |||
| of the Library that is interface-compatible with the Linked | |||
| Version. | |||
| e) Provide Installation Information, but only if you would otherwise | |||
| be required to provide such information under section 6 of the | |||
| GNU GPL, and only to the extent that such information is | |||
| necessary to install and execute a modified version of the | |||
| Combined Work produced by recombining or relinking the | |||
| Application with a modified version of the Linked Version. (If | |||
| you use option 4d0, the Installation Information must accompany | |||
| the Minimal Corresponding Source and Corresponding Application | |||
| Code. If you use option 4d1, you must provide the Installation | |||
| Information in the manner specified by section 6 of the GNU GPL | |||
| for conveying Corresponding Source.) | |||
| 5. Combined Libraries. | |||
| You may place library facilities that are a work based on the | |||
| Library side by side in a single library together with other library | |||
| facilities that are not Applications and are not covered by this | |||
| License, and convey such a combined library under terms of your | |||
| choice, if you do both of the following: | |||
| a) Accompany the combined library with a copy of the same work based | |||
| on the Library, uncombined with any other library facilities, | |||
| conveyed under the terms of this License. | |||
| b) Give prominent notice with the combined library that part of it | |||
| is a work based on the Library, and explaining where to find the | |||
| accompanying uncombined form of the same work. | |||
| 6. Revised Versions of the GNU Lesser General Public License. | |||
| The Free Software Foundation may publish revised and/or new versions | |||
| of the GNU Lesser General Public License from time to time. Such new | |||
| versions will be similar in spirit to the present version, but may | |||
| differ in detail to address new problems or concerns. | |||
| Each version is given a distinguishing version number. If the | |||
| Library as you received it specifies that a certain numbered version | |||
| of the GNU Lesser General Public License "or any later version" | |||
| applies to it, you have the option of following the terms and | |||
| conditions either of that published version or of any later version | |||
| published by the Free Software Foundation. If the Library as you | |||
| received it does not specify a version number of the GNU Lesser | |||
| General Public License, you may choose any version of the GNU Lesser | |||
| General Public License ever published by the Free Software Foundation. | |||
| If the Library as you received it specifies that a proxy can decide | |||
| whether future versions of the GNU Lesser General Public License shall | |||
| apply, that proxy's public statement of acceptance of any version is | |||
| permanent authorization for you to choose that version for the | |||
| Library. | |||
| @@ -0,0 +1,149 @@ | |||
| MeekroDB -- The Simple PHP MySQL Library | |||
| ======== | |||
| Learn more: http://www.meekro.com | |||
| MeekroDB is: | |||
| * A PHP MySQL library that lets you **get more done with fewer lines of code**, and **makes SQL injection 100% impossible**. | |||
| * Google's #1 search result for "php mysql library" since 2013, with **thousands of deployments worldwide**. | |||
| * A library with a **perfect security track record**. No bugs relating to security or SQL injection have ever been discovered. | |||
| Installation | |||
| ======== | |||
| When you're ready to get started, see the [Quick Start Guide](http://www.meekro.com/quickstart.php) on our website. | |||
| ### Manual Setup | |||
| Include the `db.class.php` file into your project and set it up like this: | |||
| require_once 'db.class.php'; | |||
| DB::$user = 'my_database_user'; | |||
| DB::$password = 'my_database_password'; | |||
| DB::$dbName = 'my_database_name'; | |||
| ### Composer | |||
| Add this to your `composer.json` | |||
| { | |||
| "require": { | |||
| "sergeytsalkov/meekrodb": "*" | |||
| } | |||
| } | |||
| Code Examples | |||
| ======== | |||
| ### Grab some rows from the database and print out a field from each row. | |||
| $accounts = DB::query("SELECT * FROM accounts WHERE type = %s AND age > %i", $type, 15); | |||
| foreach ($accounts as $account) { | |||
| echo $account['username'] . "\n"; | |||
| } | |||
| ### Insert a new row. | |||
| DB::insert('mytable', array( | |||
| 'name' => $name, | |||
| 'rank' => $rank, | |||
| 'location' => $location, | |||
| 'age' => $age, | |||
| 'intelligence' => $intelligence | |||
| )); | |||
| ### Grab one row or field | |||
| $account = DB::queryFirstRow("SELECT * FROM accounts WHERE username=%s", 'Joe'); | |||
| $number_accounts = DB::queryFirstField("SELECT COUNT(*) FROM accounts"); | |||
| ### Use a list in a query | |||
| DB::query("SELECT * FROM tbl WHERE name IN %ls AND age NOT IN %li", array('John', 'Bob'), array(12, 15)); | |||
| ### Nested Transactions | |||
| DB::$nested_transactions = true; | |||
| DB::startTransaction(); // outer transaction | |||
| // .. some queries.. | |||
| $depth = DB::startTransaction(); // inner transaction | |||
| echo $depth . 'transactions are currently active'; // 2 | |||
| // .. some queries.. | |||
| DB::commit(); // commit inner transaction | |||
| // .. some queries.. | |||
| DB::commit(); // commit outer transaction | |||
| ### Lots More - See: http://www.meekro.com/docs.php | |||
| How is MeekroDB better than PDO? | |||
| ======== | |||
| ### Optional Static Class Mode | |||
| Most web apps will only ever talk to one database. This means that | |||
| passing $db objects to every function of your code just adds unnecessary clutter. | |||
| The simplest approach is to use static methods such as DB::query(), and that's how | |||
| MeekroDB works. Still, if you need database objects, MeekroDB can do that too. | |||
| ### Do more with fewer lines of code | |||
| The code below escapes your parameters for safety, runs the query, and grabs | |||
| the first row of results. Try doing that in one line with PDO. | |||
| $account = DB::queryFirstRow("SELECT * FROM accounts WHERE username=%s", 'Joe'); | |||
| ### Work with list parameters easily | |||
| Using MySQL's IN keyword should not be hard. MeekroDB smooths out the syntax for you, | |||
| PDO does not. | |||
| $accounts = DB::query("SELECT * FROM accounts WHERE username IN %ls", array('Joe', 'Frank')); | |||
| ### Simple inserts | |||
| Using MySQL's INSERT should not be more complicated than passing in an | |||
| associative array. MeekroDB also simplifies many related commands, including | |||
| the useful and bizarre INSERT .. ON DUPLICATE UPDATE command. PDO does none of this. | |||
| DB::insert('accounts', array('username' => 'John', 'password' => 'whatever')); | |||
| ### Focus on the goal, not the task | |||
| Want to do INSERT yourself rather than relying on DB::insert()? | |||
| It's dead simple. I don't even want to think about how many lines | |||
| you'd need to pull this off in PDO. | |||
| // Insert 2 rows at once | |||
| DB::query("INSERT INTO %b %lb VALUES %ll?", 'accounts', | |||
| array('username', 'password', 'last_login_timestamp'), | |||
| array( | |||
| array('Joe', 'joes_password', new DateTime('yesterday')), | |||
| array('Frank', 'franks_password', new DateTime('last Monday')) | |||
| ) | |||
| ); | |||
| ### Nested transactions | |||
| MySQL's SAVEPOINT commands lets you create nested transactions, but only | |||
| if you keep track of SAVEPOINT ids yourself. MeekroDB does this for you, | |||
| so you can have nested transactions with no complexity or learning curve. | |||
| DB::$nested_transactions = true; | |||
| DB::startTransaction(); // outer transaction | |||
| // .. some queries.. | |||
| $depth = DB::startTransaction(); // inner transaction | |||
| echo $depth . 'transactions are currently active'; // 2 | |||
| // .. some queries.. | |||
| DB::commit(); // commit inner transaction | |||
| // .. some queries.. | |||
| DB::commit(); // commit outer transaction | |||
| ### Flexible error and success handlers | |||
| Set your own custom function run on errors, or on every query that succeeds. | |||
| You can easily have separate error handling behavior for the dev and live | |||
| versions of your application. Want to count up all your queries and their | |||
| runtime? Just add a new success handler. | |||
| ### More about MeekroDB's design philosophy: http://www.meekro.com/beliefs.php | |||
| My Other Projects | |||
| ======== | |||
| A little shameless self-promotion! | |||
| * [Ark Server Hosting](https://arkservers.io) -- Ark: Survival Evolved server hosting by ArkServers.io! | |||
| * [7 Days To Die Server Hosting](https://arkservers.io/7days) -- 7 Days to Die server hosting by ArkServers.io! | |||
| * [Best Minecraft Server Hosting](https://bestminecraft.org) -- Ranking and recommendations for minecraft server hosting! | |||
| * [ChunkHost](https://chunkhost.com) -- VPS Hosting starting at $5/month! We accept bitcoin! | |||
| * [brooce](https://github.com/SergeyTsalkov/brooce) - Language-agnostic job queue written in Go! Write your jobs in any language, schedule them from any language, run them anywhere! | |||
| @@ -0,0 +1,29 @@ | |||
| { | |||
| "name": "SergeyTsalkov/meekrodb", | |||
| "description": "The Simple PHP/MySQL Library", | |||
| "homepage": "http://www.meekro.com", | |||
| "support": { | |||
| "email": "support@meekro.com" | |||
| }, | |||
| "keywords": [ | |||
| "mysql", | |||
| "database", | |||
| "mysqli", | |||
| "pdo" | |||
| ], | |||
| "license": "LGPL-3.0", | |||
| "authors": [ | |||
| { | |||
| "name": "Sergey Tsalkov", | |||
| "email": "stsalkov@gmail.com" | |||
| } | |||
| ], | |||
| "require": { | |||
| "php": ">=5.2.0" | |||
| }, | |||
| "autoload": { | |||
| "classmap": [ | |||
| "db.class.php" | |||
| ] | |||
| } | |||
| } | |||
| @@ -0,0 +1,439 @@ | |||
| <?php | |||
| class BasicTest extends SimpleTest { | |||
| function __construct() { | |||
| foreach (DB::tableList() as $table) { | |||
| DB::query("DROP TABLE %b", $table); | |||
| } | |||
| } | |||
| function test_1_create_table() { | |||
| DB::query("CREATE TABLE `accounts` ( | |||
| `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY , | |||
| `profile_id` INT NOT NULL, | |||
| `username` VARCHAR( 255 ) NOT NULL , | |||
| `password` VARCHAR( 255 ) NULL , | |||
| `age` INT NOT NULL DEFAULT '10', | |||
| `height` DOUBLE NOT NULL DEFAULT '10.0', | |||
| `favorite_word` VARCHAR( 255 ) NULL DEFAULT 'hi', | |||
| `birthday` TIMESTAMP NOT NULL | |||
| ) ENGINE = InnoDB"); | |||
| DB::query("CREATE TABLE `profile` ( | |||
| `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY , | |||
| `signature` VARCHAR( 255 ) NULL DEFAULT 'donewriting' | |||
| ) ENGINE = InnoDB"); | |||
| DB::query("CREATE TABLE `fake%s_table` ( | |||
| `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY , | |||
| `name` VARCHAR( 255 ) NULL DEFAULT 'blah' | |||
| ) ENGINE = InnoDB"); | |||
| $mysqli = DB::get(); | |||
| DB::disconnect(); | |||
| @$this->assert(!$mysqli->server_info); | |||
| } | |||
| function test_1_5_empty_table() { | |||
| $counter = DB::queryFirstField("SELECT COUNT(*) FROM accounts"); | |||
| $this->assert($counter === strval(0)); | |||
| $row = DB::queryFirstRow("SELECT * FROM accounts"); | |||
| $this->assert($row === null); | |||
| $field = DB::queryFirstField("SELECT * FROM accounts"); | |||
| $this->assert($field === null); | |||
| $field = DB::queryOneField('nothere', "SELECT * FROM accounts"); | |||
| $this->assert($field === null); | |||
| $column = DB::queryFirstColumn("SELECT * FROM accounts"); | |||
| $this->assert(is_array($column) && count($column) === 0); | |||
| $column = DB::queryOneColumn('nothere', "SELECT * FROM accounts"); //TODO: is this what we want? | |||
| $this->assert(is_array($column) && count($column) === 0); | |||
| } | |||
| function test_2_insert_row() { | |||
| $true = DB::insert('accounts', array( | |||
| 'username' => 'Abe', | |||
| 'password' => 'hello' | |||
| )); | |||
| $this->assert($true === true); | |||
| $this->assert(DB::affectedRows() === 1); | |||
| $counter = DB::queryFirstField("SELECT COUNT(*) FROM accounts"); | |||
| $this->assert($counter === strval(1)); | |||
| } | |||
| function test_3_more_inserts() { | |||
| DB::insert('`accounts`', array( | |||
| 'username' => 'Bart', | |||
| 'password' => 'hello', | |||
| 'age' => 15, | |||
| 'height' => 10.371 | |||
| )); | |||
| $dbname = DB::$dbName; | |||
| DB::insert("`$dbname`.`accounts`", array( | |||
| 'username' => 'Charlie\'s Friend', | |||
| 'password' => 'goodbye', | |||
| 'age' => 30, | |||
| 'height' => 155.23, | |||
| 'favorite_word' => null, | |||
| )); | |||
| $this->assert(DB::insertId() === 3); | |||
| $counter = DB::queryFirstField("SELECT COUNT(*) FROM accounts"); | |||
| $this->assert($counter === strval(3)); | |||
| DB::insert('`accounts`', array( | |||
| 'username' => 'Deer', | |||
| 'password' => '', | |||
| 'age' => 15, | |||
| 'height' => 10.371 | |||
| )); | |||
| $username = DB::queryFirstField("SELECT username FROM accounts WHERE password=%s0", null); | |||
| $this->assert($username === 'Deer'); | |||
| $password = DB::queryFirstField("SELECT password FROM accounts WHERE favorite_word IS NULL"); | |||
| $this->assert($password === 'goodbye'); | |||
| DB::$usenull = false; | |||
| DB::insertUpdate('accounts', array( | |||
| 'id' => 3, | |||
| 'favorite_word' => null, | |||
| )); | |||
| $password = DB::queryFirstField("SELECT password FROM accounts WHERE favorite_word=%s AND favorite_word=%s", null, ''); | |||
| $this->assert($password === 'goodbye'); | |||
| DB::$usenull = true; | |||
| DB::insertUpdate('accounts', array( | |||
| 'id' => 3, | |||
| 'favorite_word' => null, | |||
| )); | |||
| DB::$param_char = '###'; | |||
| $bart = DB::queryFirstRow("SELECT * FROM accounts WHERE age IN ###li AND height IN ###ld AND username IN ###ls", | |||
| array(15, 25), array(10.371, 150.123), array('Bart', 'Barts')); | |||
| $this->assert($bart['username'] === 'Bart'); | |||
| DB::insert('accounts', array('username' => 'f_u')); | |||
| DB::query("DELETE FROM accounts WHERE username=###s", 'f_u'); | |||
| DB::$param_char = '%'; | |||
| $charlie_password = DB::queryFirstField("SELECT password FROM accounts WHERE username IN %ls AND username = %s", | |||
| array('Charlie', 'Charlie\'s Friend'), 'Charlie\'s Friend'); | |||
| $this->assert($charlie_password === 'goodbye'); | |||
| $charlie_password = DB::queryOneField('password', "SELECT * FROM accounts WHERE username IN %ls AND username = %s", | |||
| array('Charlie', 'Charlie\'s Friend'), 'Charlie\'s Friend'); | |||
| $this->assert($charlie_password === 'goodbye'); | |||
| $passwords = DB::queryFirstColumn("SELECT password FROM accounts WHERE username=%s", 'Bart'); | |||
| $this->assert(count($passwords) === 1); | |||
| $this->assert($passwords[0] === 'hello'); | |||
| $username = $password = $age = null; | |||
| list($age, $username, $password) = DB::queryOneList("SELECT age,username,password FROM accounts WHERE username=%s", 'Bart'); | |||
| $this->assert($username === 'Bart'); | |||
| $this->assert($password === 'hello'); | |||
| $this->assert($age == 15); | |||
| $mysqli_result = DB::queryRaw("SELECT * FROM accounts WHERE favorite_word IS NULL"); | |||
| $this->assert($mysqli_result instanceof MySQLi_Result); | |||
| $row = $mysqli_result->fetch_assoc(); | |||
| $this->assert($row['password'] === 'goodbye'); | |||
| $this->assert($mysqli_result->fetch_assoc() === null); | |||
| } | |||
| function test_4_query() { | |||
| DB::update('accounts', array( | |||
| 'birthday' => new DateTime('10 September 2000 13:13:13') | |||
| ), 'username=%s', 'Charlie\'s Friend'); | |||
| $results = DB::query("SELECT * FROM accounts WHERE username=%s AND birthday IN %lt", 'Charlie\'s Friend', array('September 10 2000 13:13:13')); | |||
| $this->assert(count($results) === 1); | |||
| $this->assert($results[0]['age'] === '30' && $results[0]['password'] === 'goodbye'); | |||
| $this->assert($results[0]['birthday'] == '2000-09-10 13:13:13'); | |||
| $results = DB::query("SELECT * FROM accounts WHERE username!=%s", "Charlie's Friend"); | |||
| $this->assert(count($results) === 3); | |||
| $columnlist = DB::columnList('accounts'); | |||
| $this->assert(count($columnlist) === 8); | |||
| $this->assert($columnlist[0] === 'id'); | |||
| $this->assert($columnlist[5] === 'height'); | |||
| $tablelist = DB::tableList(); | |||
| $this->assert(count($tablelist) === 3); | |||
| $this->assert($tablelist[0] === 'accounts'); | |||
| $tablelist = null; | |||
| $tablelist = DB::tableList(DB::$dbName); | |||
| $this->assert(count($tablelist) === 3); | |||
| $this->assert($tablelist[0] === 'accounts'); | |||
| } | |||
| function test_4_1_query() { | |||
| DB::insert('accounts', array( | |||
| 'username' => 'newguy', | |||
| 'password' => DB::sqleval("REPEAT('blah', %i)", '3'), | |||
| 'age' => DB::sqleval('171+1'), | |||
| 'height' => 111.15 | |||
| )); | |||
| $row = DB::queryOneRow("SELECT * FROM accounts WHERE password=%s", 'blahblahblah'); | |||
| $this->assert($row['username'] === 'newguy'); | |||
| $this->assert($row['age'] === '172'); | |||
| $true = DB::update('accounts', array( | |||
| 'password' => DB::sqleval("REPEAT('blah', %i)", 4), | |||
| 'favorite_word' => null, | |||
| ), 'username=%s_name', array('name' => 'newguy')); | |||
| $row = null; | |||
| $row = DB::queryOneRow("SELECT * FROM accounts WHERE username=%s", 'newguy'); | |||
| $this->assert($true === true); | |||
| $this->assert($row['password'] === 'blahblahblahblah'); | |||
| $this->assert($row['favorite_word'] === null); | |||
| $row = DB::query("SELECT * FROM accounts WHERE password=%s_mypass AND (password=%s_mypass) AND username=%s_myuser", | |||
| array('myuser' => 'newguy', 'mypass' => 'blahblahblahblah') | |||
| ); | |||
| $this->assert(count($row) === 1); | |||
| $this->assert($row[0]['username'] === 'newguy'); | |||
| $this->assert($row[0]['age'] === '172'); | |||
| $row = DB::query("SELECT * FROM accounts WHERE password IN %li AND password IN %li0 AND username=%s", array('blahblahblahblah'), 'newguy'); | |||
| $this->assert(count($row) === 1); | |||
| $this->assert($row[0]['username'] === 'newguy'); | |||
| $this->assert($row[0]['age'] === '172'); | |||
| $true = DB::query("DELETE FROM accounts WHERE password=%s", 'blahblahblahblah'); | |||
| $this->assert($true === true); | |||
| $this->assert(DB::affectedRows() === 1); | |||
| } | |||
| function test_4_2_delete() { | |||
| DB::insert('accounts', array( | |||
| 'username' => 'gonesoon', | |||
| 'password' => 'something', | |||
| 'age' => 61, | |||
| 'height' => 199.194 | |||
| )); | |||
| $ct = DB::queryFirstField("SELECT COUNT(*) FROM accounts WHERE %ha", array('username' => 'gonesoon', 'height' => 199.194)); | |||
| $this->assert(intval($ct) === 1); | |||
| $ct = DB::queryFirstField("SELECT COUNT(*) FROM accounts WHERE username=%s1 AND height=%d0 AND height=%d", 199.194, 'gonesoon'); | |||
| $this->assert(intval($ct) === 1); | |||
| DB::delete('accounts', 'username=%s AND age=%i AND height=%d', 'gonesoon', '61', '199.194'); | |||
| $this->assert(DB::affectedRows() === 1); | |||
| $ct = DB::queryFirstField("SELECT COUNT(*) FROM accounts WHERE username=%s AND height=%d", 'gonesoon', '199.194'); | |||
| $this->assert(intval($ct) === 0); | |||
| } | |||
| function test_4_3_insertmany() { | |||
| $ins[] = array( | |||
| 'username' => '1ofmany', | |||
| 'password' => 'something', | |||
| 'age' => 23, | |||
| 'height' => 190.194 | |||
| ); | |||
| $ins[] = array( | |||
| 'password' => 'somethingelse', | |||
| 'username' => '2ofmany', | |||
| 'age' => 25, | |||
| 'height' => 190.194 | |||
| ); | |||
| $ins[] = array( | |||
| 'password' => NULL, | |||
| 'username' => '3ofmany', | |||
| 'age' => 15, | |||
| 'height' => 111.951 | |||
| ); | |||
| DB::insert('accounts', $ins); | |||
| $this->assert(DB::affectedRows() === 3); | |||
| $rows = DB::query("SELECT * FROM accounts WHERE height=%d ORDER BY age ASC", 190.194); | |||
| $this->assert(count($rows) === 2); | |||
| $this->assert($rows[0]['username'] === '1ofmany'); | |||
| $this->assert($rows[0]['age'] === '23'); | |||
| $this->assert($rows[1]['age'] === '25'); | |||
| $this->assert($rows[1]['password'] === 'somethingelse'); | |||
| $this->assert($rows[1]['username'] === '2ofmany'); | |||
| $nullrow = DB::queryOneRow("SELECT * FROM accounts WHERE username LIKE %ss", '3ofman'); | |||
| $this->assert($nullrow['password'] === NULL); | |||
| $this->assert($nullrow['age'] === '15'); | |||
| } | |||
| function test_5_insert_blobs() { | |||
| DB::query("CREATE TABLE `store data` ( | |||
| `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY , | |||
| `picture` BLOB | |||
| ) ENGINE = InnoDB"); | |||
| $columns = DB::columnList('store data'); | |||
| $this->assert(count($columns) === 2); | |||
| $this->assert($columns[1] === 'picture'); | |||
| $smile = file_get_contents('smile1.jpg'); | |||
| DB::insert('store data', array( | |||
| 'picture' => $smile, | |||
| )); | |||
| DB::queryOneRow("INSERT INTO %b (picture) VALUES (%s)", 'store data', $smile); | |||
| $getsmile = DB::queryFirstField("SELECT picture FROM %b WHERE id=1", 'store data'); | |||
| $getsmile2 = DB::queryFirstField("SELECT picture FROM %b WHERE id=2", 'store data'); | |||
| $this->assert($smile === $getsmile); | |||
| $this->assert($smile === $getsmile2); | |||
| } | |||
| function test_6_insert_ignore() { | |||
| DB::insertIgnore('accounts', array( | |||
| 'id' => 1, //duplicate primary key | |||
| 'username' => 'gonesoon', | |||
| 'password' => 'something', | |||
| 'age' => 61, | |||
| 'height' => 199.194 | |||
| )); | |||
| } | |||
| function test_7_insert_update() { | |||
| $true = DB::insertUpdate('accounts', array( | |||
| 'id' => 2, //duplicate primary key | |||
| 'username' => 'gonesoon', | |||
| 'password' => 'something', | |||
| 'age' => 61, | |||
| 'height' => 199.194 | |||
| ), 'age = age + %i', 1); | |||
| $this->assert($true === true); | |||
| $this->assert(DB::affectedRows() === 2); // a quirk of MySQL, even though only 1 row was updated | |||
| $result = DB::query("SELECT * FROM accounts WHERE age = %i", 16); | |||
| $this->assert(count($result) === 1); | |||
| $this->assert($result[0]['height'] === '10.371'); | |||
| DB::insertUpdate('accounts', array( | |||
| 'id' => 2, //duplicate primary key | |||
| 'username' => 'blahblahdude', | |||
| 'age' => 233, | |||
| 'height' => 199.194 | |||
| )); | |||
| $result = DB::query("SELECT * FROM accounts WHERE age = %i", 233); | |||
| $this->assert(count($result) === 1); | |||
| $this->assert($result[0]['height'] === '199.194'); | |||
| $this->assert($result[0]['username'] === 'blahblahdude'); | |||
| DB::insertUpdate('accounts', array( | |||
| 'id' => 2, //duplicate primary key | |||
| 'username' => 'gonesoon', | |||
| 'password' => 'something', | |||
| 'age' => 61, | |||
| 'height' => 199.194 | |||
| ), array( | |||
| 'age' => 74, | |||
| )); | |||
| $result = DB::query("SELECT * FROM accounts WHERE age = %i", 74); | |||
| $this->assert(count($result) === 1); | |||
| $this->assert($result[0]['height'] === '199.194'); | |||
| $this->assert($result[0]['username'] === 'blahblahdude'); | |||
| $multiples[] = array( | |||
| 'id' => 3, //duplicate primary key | |||
| 'username' => 'gonesoon', | |||
| 'password' => 'something', | |||
| 'age' => 61, | |||
| 'height' => 199.194 | |||
| ); | |||
| $multiples[] = array( | |||
| 'id' => 1, //duplicate primary key | |||
| 'username' => 'gonesoon', | |||
| 'password' => 'something', | |||
| 'age' => 61, | |||
| 'height' => 199.194 | |||
| ); | |||
| DB::insertUpdate('accounts', $multiples, array('age' => 914)); | |||
| $this->assert(DB::affectedRows() === 4); | |||
| $result = DB::query("SELECT * FROM accounts WHERE age=914 ORDER BY id ASC"); | |||
| $this->assert(count($result) === 2); | |||
| $this->assert($result[0]['username'] === 'Abe'); | |||
| $this->assert($result[1]['username'] === 'Charlie\'s Friend'); | |||
| $true = DB::query("UPDATE accounts SET age=15, username='Bart' WHERE age=%i", 74); | |||
| $this->assert($true === true); | |||
| $this->assert(DB::affectedRows() === 1); | |||
| } | |||
| function test_8_lb() { | |||
| $data = array( | |||
| 'username' => 'vookoo', | |||
| 'password' => 'dookoo', | |||
| ); | |||
| $true = DB::query("INSERT into accounts %lb VALUES %ls", array_keys($data), array_values($data)); | |||
| $result = DB::query("SELECT * FROM accounts WHERE username=%s", 'vookoo'); | |||
| $this->assert($true === true); | |||
| $this->assert(count($result) === 1); | |||
| $this->assert($result[0]['password'] === 'dookoo'); | |||
| } | |||
| function test_9_fullcolumns() { | |||
| $true = DB::insert('profile', array( | |||
| 'id' => 1, | |||
| 'signature' => 'u_suck' | |||
| )); | |||
| DB::query("UPDATE accounts SET profile_id=1 WHERE id=2"); | |||
| $r = DB::queryFullColumns("SELECT accounts.*, profile.*, 1+1 FROM accounts | |||
| INNER JOIN profile ON accounts.profile_id=profile.id"); | |||
| $this->assert($true === true); | |||
| $this->assert(count($r) === 1); | |||
| $this->assert($r[0]['accounts.id'] === '2'); | |||
| $this->assert($r[0]['profile.id'] === '1'); | |||
| $this->assert($r[0]['profile.signature'] === 'u_suck'); | |||
| $this->assert($r[0]['1+1'] === '2'); | |||
| } | |||
| function test_901_updatewithspecialchar() { | |||
| $data = 'www.mysite.com/product?s=t-%s-%%3d%%3d%i&RCAID=24322'; | |||
| DB::update('profile', array('signature' => $data), 'id=%i', 1); | |||
| $signature = DB::queryFirstField("SELECT signature FROM profile WHERE id=%i", 1); | |||
| $this->assert($signature === $data); | |||
| DB::update('profile',array('signature'=> "%li "),"id = %d",1); | |||
| $signature = DB::queryFirstField("SELECT signature FROM profile WHERE id=%i", 1); | |||
| $this->assert($signature === "%li "); | |||
| } | |||
| function test_902_faketable() { | |||
| DB::insert('fake%s_table', array('name' => 'karen')); | |||
| $count = DB::queryFirstField("SELECT COUNT(*) FROM %b", 'fake%s_table'); | |||
| $this->assert($count === '1'); | |||
| DB::update('fake%s_table', array('name' => 'haren%s'), 'name=%s_name', array('name' => 'karen')); | |||
| DB::delete('fake%s_table', 'name=%s0', 'haren%s'); | |||
| $count = DB::queryFirstField("SELECT COUNT(*) FROM %b", 'fake%s_table'); | |||
| $this->assert($count === '0'); | |||
| } | |||
| } | |||
| ?> | |||
| @@ -0,0 +1,17 @@ | |||
| <?php | |||
| class CallTest extends SimpleTest { | |||
| function test_1_create_procedure() { | |||
| DB::query("DROP PROCEDURE IF EXISTS myProc"); | |||
| DB::query("CREATE PROCEDURE myProc() | |||
| BEGIN | |||
| SELECT * FROM accounts; | |||
| END"); | |||
| } | |||
| function test_2_run_procedure() { | |||
| $r = DB::query("CALL myProc()"); | |||
| $this->assert($r[0]['username'] === 'Abe'); | |||
| $this->assert($r[2]['age'] === '914'); | |||
| } | |||
| } | |||
| @@ -0,0 +1,83 @@ | |||
| <?php | |||
| function new_error_callback($params) { | |||
| global $error_callback_worked; | |||
| if (substr_count($params['error'], 'You have an error in your SQL syntax')) $error_callback_worked = 1; | |||
| } | |||
| function my_debug_handler($params) { | |||
| global $debug_callback_worked; | |||
| if (substr_count($params['query'], 'SELECT')) $debug_callback_worked = 1; | |||
| } | |||
| class ErrorTest extends SimpleTest { | |||
| function test_1_error_handler() { | |||
| global $error_callback_worked, $static_error_callback_worked, $nonstatic_error_callback_worked; | |||
| DB::$error_handler = 'new_error_callback'; | |||
| DB::query("SELET * FROM accounts"); | |||
| $this->assert($error_callback_worked === 1); | |||
| DB::$error_handler = array('ErrorTest', 'static_error_callback'); | |||
| DB::query("SELET * FROM accounts"); | |||
| $this->assert($static_error_callback_worked === 1); | |||
| DB::$error_handler = array($this, 'nonstatic_error_callback'); | |||
| DB::query("SELET * FROM accounts"); | |||
| $this->assert($nonstatic_error_callback_worked === 1); | |||
| } | |||
| public static function static_error_callback($params) { | |||
| global $static_error_callback_worked; | |||
| if (substr_count($params['error'], 'You have an error in your SQL syntax')) $static_error_callback_worked = 1; | |||
| } | |||
| public function nonstatic_error_callback($params) { | |||
| global $nonstatic_error_callback_worked; | |||
| if (substr_count($params['error'], 'You have an error in your SQL syntax')) $nonstatic_error_callback_worked = 1; | |||
| } | |||
| function test_2_exception_catch() { | |||
| $dbname = DB::$dbName; | |||
| DB::$error_handler = ''; | |||
| DB::$throw_exception_on_error = true; | |||
| try { | |||
| DB::query("SELET * FROM accounts"); | |||
| } catch(MeekroDBException $e) { | |||
| $this->assert(substr_count($e->getMessage(), 'You have an error in your SQL syntax')); | |||
| $this->assert($e->getQuery() === 'SELET * FROM accounts'); | |||
| $exception_was_caught = 1; | |||
| } | |||
| $this->assert($exception_was_caught === 1); | |||
| try { | |||
| DB::insert("`$dbname`.`accounts`", array( | |||
| 'id' => 2, | |||
| 'username' => 'Another Dude\'s \'Mom"', | |||
| 'password' => 'asdfsdse', | |||
| 'age' => 35, | |||
| 'height' => 555.23 | |||
| )); | |||
| } catch(MeekroDBException $e) { | |||
| $this->assert(substr_count($e->getMessage(), 'Duplicate entry')); | |||
| $exception_was_caught = 2; | |||
| } | |||
| $this->assert($exception_was_caught === 2); | |||
| } | |||
| function test_3_debugmode_handler() { | |||
| global $debug_callback_worked; | |||
| DB::debugMode('my_debug_handler'); | |||
| DB::query("SELECT * FROM accounts WHERE username!=%s", "Charlie's Friend"); | |||
| $this->assert($debug_callback_worked === 1); | |||
| DB::debugMode(false); | |||
| } | |||
| } | |||
| ?> | |||
| @@ -0,0 +1,19 @@ | |||
| <?php | |||
| class ErrorTest_53 extends SimpleTest { | |||
| function test_1_error_handler() { | |||
| global $anonymous_error_callback_worked; | |||
| DB::$throw_exception_on_error = false; | |||
| DB::$error_handler = function($params) { | |||
| global $anonymous_error_callback_worked; | |||
| if (substr_count($params['error'], 'You have an error in your SQL syntax')) $anonymous_error_callback_worked = 1; | |||
| }; | |||
| DB::query("SELET * FROM accounts"); | |||
| $this->assert($anonymous_error_callback_worked === 1); | |||
| } | |||
| } | |||
| ?> | |||
| @@ -0,0 +1,51 @@ | |||
| <?php | |||
| class HelperTest extends SimpleTest { | |||
| function test_1_verticalslice() { | |||
| $all = DB::query("SELECT * FROM accounts ORDER BY id ASC"); | |||
| $names = DBHelper::verticalSlice($all, 'username'); | |||
| $this->assert(count($names) === 5); | |||
| $this->assert($names[0] === 'Abe'); | |||
| $ages = DBHelper::verticalSlice($all, 'age', 'username'); | |||
| $this->assert(count($ages) === 5); | |||
| $this->assert($ages['Abe'] === '700'); | |||
| } | |||
| function test_2_reindex() { | |||
| $all = DB::query("SELECT * FROM accounts ORDER BY id ASC"); | |||
| $names = DBHelper::reIndex($all, 'username'); | |||
| $this->assert(count($names) === 5); | |||
| $this->assert($names['Bart']['username'] === 'Bart'); | |||
| $this->assert($names['Bart']['age'] === '15'); | |||
| $names = DBHelper::reIndex($all, 'username', 'age'); | |||
| $this->assert($names['Bart']['15']['username'] === 'Bart'); | |||
| $this->assert($names['Bart']['15']['age'] === '15'); | |||
| } | |||
| function test_3_empty() { | |||
| $none = DB::query("SELECT * FROM accounts WHERE username=%s", 'doesnotexist'); | |||
| $this->assert(is_array($none) && count($none) === 0); | |||
| $names = DBHelper::verticalSlice($none, 'username', 'age'); | |||
| $this->assert(is_array($names) && count($names) === 0); | |||
| $names_other = DBHelper::reIndex($none, 'username', 'age'); | |||
| $this->assert(is_array($names_other) && count($names_other) === 0); | |||
| } | |||
| function test_4_null() { | |||
| DB::query("UPDATE accounts SET password = NULL WHERE username=%s", 'Bart'); | |||
| $all = DB::query("SELECT * FROM accounts ORDER BY id ASC"); | |||
| $ages = DBHelper::verticalSlice($all, 'age', 'password'); | |||
| $this->assert(count($ages) === 5); | |||
| $this->assert($ages[''] === '15'); | |||
| $passwords = DBHelper::reIndex($all, 'password'); | |||
| $this->assert(count($passwords) === 5); | |||
| $this->assert($passwords['']['username'] === 'Bart'); | |||
| $this->assert($passwords['']['password'] === NULL); | |||
| } | |||
| } | |||
| ?> | |||
| @@ -0,0 +1,312 @@ | |||
| <?php | |||
| class ObjectTest extends SimpleTest { | |||
| public $mdb; | |||
| function __construct() { | |||
| $this->mdb = new MeekroDB(); | |||
| foreach ($this->mdb->tableList() as $table) { | |||
| $this->mdb->query("DROP TABLE %b", $table); | |||
| } | |||
| } | |||
| function test_1_create_table() { | |||
| $this->mdb->query("CREATE TABLE `accounts` ( | |||
| `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY , | |||
| `username` VARCHAR( 255 ) NOT NULL , | |||
| `password` VARCHAR( 255 ) NULL , | |||
| `age` INT NOT NULL DEFAULT '10', | |||
| `height` DOUBLE NOT NULL DEFAULT '10.0', | |||
| `favorite_word` VARCHAR( 255 ) NULL DEFAULT 'hi' | |||
| ) ENGINE = InnoDB"); | |||
| } | |||
| function test_1_5_empty_table() { | |||
| $counter = $this->mdb->queryFirstField("SELECT COUNT(*) FROM accounts"); | |||
| $this->assert($counter === strval(0)); | |||
| $row = $this->mdb->queryFirstRow("SELECT * FROM accounts"); | |||
| $this->assert($row === null); | |||
| $field = $this->mdb->queryFirstField("SELECT * FROM accounts"); | |||
| $this->assert($field === null); | |||
| $field = $this->mdb->queryOneField('nothere', "SELECT * FROM accounts"); | |||
| $this->assert($field === null); | |||
| $column = $this->mdb->queryFirstColumn("SELECT * FROM accounts"); | |||
| $this->assert(is_array($column) && count($column) === 0); | |||
| $column = $this->mdb->queryOneColumn('nothere', "SELECT * FROM accounts"); //TODO: is this what we want? | |||
| $this->assert(is_array($column) && count($column) === 0); | |||
| } | |||
| function test_2_insert_row() { | |||
| $this->mdb->insert('accounts', array( | |||
| 'username' => 'Abe', | |||
| 'password' => 'hello' | |||
| )); | |||
| $this->assert($this->mdb->affectedRows() === 1); | |||
| $counter = $this->mdb->queryFirstField("SELECT COUNT(*) FROM accounts"); | |||
| $this->assert($counter === strval(1)); | |||
| } | |||
| function test_3_more_inserts() { | |||
| $this->mdb->insert('`accounts`', array( | |||
| 'username' => 'Bart', | |||
| 'password' => 'hello', | |||
| 'age' => 15, | |||
| 'height' => 10.371 | |||
| )); | |||
| $dbname = $this->mdb->dbName; | |||
| $this->mdb->insert("`$dbname`.`accounts`", array( | |||
| 'username' => 'Charlie\'s Friend', | |||
| 'password' => 'goodbye', | |||
| 'age' => 30, | |||
| 'height' => 155.23, | |||
| 'favorite_word' => null, | |||
| )); | |||
| $this->assert($this->mdb->insertId() === 3); | |||
| $counter = $this->mdb->queryFirstField("SELECT COUNT(*) FROM accounts"); | |||
| $this->assert($counter === strval(3)); | |||
| $password = $this->mdb->queryFirstField("SELECT password FROM accounts WHERE favorite_word IS NULL"); | |||
| $this->assert($password === 'goodbye'); | |||
| $this->mdb->param_char = '###'; | |||
| $bart = $this->mdb->queryFirstRow("SELECT * FROM accounts WHERE age IN ###li AND height IN ###ld AND username IN ###ls", | |||
| array(15, 25), array(10.371, 150.123), array('Bart', 'Barts')); | |||
| $this->assert($bart['username'] === 'Bart'); | |||
| $this->mdb->param_char = '%'; | |||
| $charlie_password = $this->mdb->queryFirstField("SELECT password FROM accounts WHERE username IN %ls AND username = %s", | |||
| array('Charlie', 'Charlie\'s Friend'), 'Charlie\'s Friend'); | |||
| $this->assert($charlie_password === 'goodbye'); | |||
| $charlie_password = $this->mdb->queryOneField('password', "SELECT * FROM accounts WHERE username IN %ls AND username = %s", | |||
| array('Charlie', 'Charlie\'s Friend'), 'Charlie\'s Friend'); | |||
| $this->assert($charlie_password === 'goodbye'); | |||
| $passwords = $this->mdb->queryFirstColumn("SELECT password FROM accounts WHERE username=%s", 'Bart'); | |||
| $this->assert(count($passwords) === 1); | |||
| $this->assert($passwords[0] === 'hello'); | |||
| $username = $password = $age = null; | |||
| list($age, $username, $password) = $this->mdb->queryOneList("SELECT age,username,password FROM accounts WHERE username=%s", 'Bart'); | |||
| $this->assert($username === 'Bart'); | |||
| $this->assert($password === 'hello'); | |||
| $this->assert($age == 15); | |||
| $mysqli_result = $this->mdb->queryRaw("SELECT * FROM accounts WHERE favorite_word IS NULL"); | |||
| $this->assert($mysqli_result instanceof MySQLi_Result); | |||
| $row = $mysqli_result->fetch_assoc(); | |||
| $this->assert($row['password'] === 'goodbye'); | |||
| $this->assert($mysqli_result->fetch_assoc() === null); | |||
| } | |||
| function test_4_query() { | |||
| $results = $this->mdb->query("SELECT * FROM accounts WHERE username=%s", 'Charlie\'s Friend'); | |||
| $this->assert(count($results) === 1); | |||
| $this->assert($results[0]['age'] == 30 && $results[0]['password'] == 'goodbye'); | |||
| $results = $this->mdb->query("SELECT * FROM accounts WHERE username!=%s", "Charlie's Friend"); | |||
| $this->assert(count($results) === 2); | |||
| $columnlist = $this->mdb->columnList('accounts'); | |||
| $this->assert(count($columnlist) === 6); | |||
| $this->assert($columnlist[0] === 'id'); | |||
| $this->assert($columnlist[4] === 'height'); | |||
| $tablelist = $this->mdb->tableList(); | |||
| $this->assert(count($tablelist) === 1); | |||
| $this->assert($tablelist[0] === 'accounts'); | |||
| $tablelist = null; | |||
| $tablelist = $this->mdb->tableList($this->mdb->dbName); | |||
| $this->assert(count($tablelist) === 1); | |||
| $this->assert($tablelist[0] === 'accounts'); | |||
| } | |||
| function test_4_1_query() { | |||
| $this->mdb->insert('accounts', array( | |||
| 'username' => 'newguy', | |||
| 'password' => $this->mdb->sqleval("REPEAT('blah', %i)", '3'), | |||
| 'age' => $this->mdb->sqleval('171+1'), | |||
| 'height' => 111.15 | |||
| )); | |||
| $row = $this->mdb->queryOneRow("SELECT * FROM accounts WHERE password=%s", 'blahblahblah'); | |||
| $this->assert($row['username'] === 'newguy'); | |||
| $this->assert($row['age'] === '172'); | |||
| $this->mdb->update('accounts', array( | |||
| 'password' => $this->mdb->sqleval("REPEAT('blah', %i)", 4), | |||
| 'favorite_word' => null, | |||
| ), 'username=%s', 'newguy'); | |||
| $row = null; | |||
| $row = $this->mdb->queryOneRow("SELECT * FROM accounts WHERE username=%s", 'newguy'); | |||
| $this->assert($row['password'] === 'blahblahblahblah'); | |||
| $this->assert($row['favorite_word'] === null); | |||
| $this->mdb->query("DELETE FROM accounts WHERE password=%s", 'blahblahblahblah'); | |||
| $this->assert($this->mdb->affectedRows() === 1); | |||
| } | |||
| function test_4_2_delete() { | |||
| $this->mdb->insert('accounts', array( | |||
| 'username' => 'gonesoon', | |||
| 'password' => 'something', | |||
| 'age' => 61, | |||
| 'height' => 199.194 | |||
| )); | |||
| $ct = $this->mdb->queryFirstField("SELECT COUNT(*) FROM accounts WHERE username=%s AND height=%d", 'gonesoon', 199.194); | |||
| $this->assert(intval($ct) === 1); | |||
| $ct = $this->mdb->queryFirstField("SELECT COUNT(*) FROM accounts WHERE username=%s1 AND height=%d0 AND height=%d", 199.194, 'gonesoon'); | |||
| $this->assert(intval($ct) === 1); | |||
| $this->mdb->delete('accounts', 'username=%s AND age=%i AND height=%d', 'gonesoon', '61', '199.194'); | |||
| $this->assert($this->mdb->affectedRows() === 1); | |||
| $ct = $this->mdb->queryFirstField("SELECT COUNT(*) FROM accounts WHERE username=%s AND height=%d", 'gonesoon', '199.194'); | |||
| $this->assert(intval($ct) === 0); | |||
| } | |||
| function test_4_3_insertmany() { | |||
| $ins[] = array( | |||
| 'username' => '1ofmany', | |||
| 'password' => 'something', | |||
| 'age' => 23, | |||
| 'height' => 190.194 | |||
| ); | |||
| $ins[] = array( | |||
| 'password' => 'somethingelse', | |||
| 'username' => '2ofmany', | |||
| 'age' => 25, | |||
| 'height' => 190.194 | |||
| ); | |||
| $this->mdb->insert('accounts', $ins); | |||
| $this->assert($this->mdb->affectedRows() === 2); | |||
| $rows = $this->mdb->query("SELECT * FROM accounts WHERE height=%d ORDER BY age ASC", 190.194); | |||
| $this->assert(count($rows) === 2); | |||
| $this->assert($rows[0]['username'] === '1ofmany'); | |||
| $this->assert($rows[0]['age'] === '23'); | |||
| $this->assert($rows[1]['age'] === '25'); | |||
| $this->assert($rows[1]['password'] === 'somethingelse'); | |||
| $this->assert($rows[1]['username'] === '2ofmany'); | |||
| } | |||
| function test_5_insert_blobs() { | |||
| $this->mdb->query("CREATE TABLE `storedata` ( | |||
| `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY , | |||
| `picture` BLOB | |||
| ) ENGINE = InnoDB"); | |||
| $smile = file_get_contents('smile1.jpg'); | |||
| $this->mdb->insert('storedata', array( | |||
| 'picture' => $smile, | |||
| )); | |||
| $this->mdb->query("INSERT INTO storedata (picture) VALUES (%s)", $smile); | |||
| $getsmile = $this->mdb->queryFirstField("SELECT picture FROM storedata WHERE id=1"); | |||
| $getsmile2 = $this->mdb->queryFirstField("SELECT picture FROM storedata WHERE id=2"); | |||
| $this->assert($smile === $getsmile); | |||
| $this->assert($smile === $getsmile2); | |||
| } | |||
| function test_6_insert_ignore() { | |||
| $this->mdb->insertIgnore('accounts', array( | |||
| 'id' => 1, //duplicate primary key | |||
| 'username' => 'gonesoon', | |||
| 'password' => 'something', | |||
| 'age' => 61, | |||
| 'height' => 199.194 | |||
| )); | |||
| } | |||
| function test_7_insert_update() { | |||
| $this->mdb->insertUpdate('accounts', array( | |||
| 'id' => 2, //duplicate primary key | |||
| 'username' => 'gonesoon', | |||
| 'password' => 'something', | |||
| 'age' => 61, | |||
| 'height' => 199.194 | |||
| ), 'age = age + %i', 1); | |||
| $this->assert($this->mdb->affectedRows() === 2); // a quirk of MySQL, even though only 1 row was updated | |||
| $result = $this->mdb->query("SELECT * FROM accounts WHERE age = %i", 16); | |||
| $this->assert(count($result) === 1); | |||
| $this->assert($result[0]['height'] === '10.371'); | |||
| $this->mdb->insertUpdate('accounts', array( | |||
| 'id' => 2, //duplicate primary key | |||
| 'username' => 'blahblahdude', | |||
| 'age' => 233, | |||
| 'height' => 199.194 | |||
| )); | |||
| $result = $this->mdb->query("SELECT * FROM accounts WHERE age = %i", 233); | |||
| $this->assert(count($result) === 1); | |||
| $this->assert($result[0]['height'] === '199.194'); | |||
| $this->assert($result[0]['username'] === 'blahblahdude'); | |||
| $this->mdb->insertUpdate('accounts', array( | |||
| 'id' => 2, //duplicate primary key | |||
| 'username' => 'gonesoon', | |||
| 'password' => 'something', | |||
| 'age' => 61, | |||
| 'height' => 199.194 | |||
| ), array( | |||
| 'age' => 74, | |||
| )); | |||
| $result = $this->mdb->query("SELECT * FROM accounts WHERE age = %i", 74); | |||
| $this->assert(count($result) === 1); | |||
| $this->assert($result[0]['height'] === '199.194'); | |||
| $this->assert($result[0]['username'] === 'blahblahdude'); | |||
| $multiples[] = array( | |||
| 'id' => 3, //duplicate primary key | |||
| 'username' => 'gonesoon', | |||
| 'password' => 'something', | |||
| 'age' => 61, | |||
| 'height' => 199.194 | |||
| ); | |||
| $multiples[] = array( | |||
| 'id' => 1, //duplicate primary key | |||
| 'username' => 'gonesoon', | |||
| 'password' => 'something', | |||
| 'age' => 61, | |||
| 'height' => 199.194 | |||
| ); | |||
| $this->mdb->insertUpdate('accounts', $multiples, array('age' => 914)); | |||
| $this->assert($this->mdb->affectedRows() === 4); | |||
| $result = $this->mdb->query("SELECT * FROM accounts WHERE age=914 ORDER BY id ASC"); | |||
| $this->assert(count($result) === 2); | |||
| $this->assert($result[0]['username'] === 'Abe'); | |||
| $this->assert($result[1]['username'] === 'Charlie\'s Friend'); | |||
| $this->mdb->query("UPDATE accounts SET age=15, username='Bart' WHERE age=%i", 74); | |||
| $this->assert($this->mdb->affectedRows() === 1); | |||
| } | |||
| } | |||
| ?> | |||
| @@ -0,0 +1,30 @@ | |||
| <?php | |||
| class TransactionTest extends SimpleTest { | |||
| function test_1_transactions() { | |||
| DB::$nested_transactions = false; | |||
| DB::query("UPDATE accounts SET age=%i WHERE username=%s", 600, 'Abe'); | |||
| $depth = DB::startTransaction(); | |||
| $this->assert($depth === 1); | |||
| DB::query("UPDATE accounts SET age=%i WHERE username=%s", 700, 'Abe'); | |||
| $depth = DB::startTransaction(); | |||
| $this->assert($depth === 1); | |||
| DB::query("UPDATE accounts SET age=%i WHERE username=%s", 800, 'Abe'); | |||
| $depth = DB::rollback(); | |||
| $this->assert($depth === 0); | |||
| $age = DB::queryFirstField("SELECT age FROM accounts WHERE username=%s", 'Abe'); | |||
| $this->assert($age == 700); | |||
| $depth = DB::rollback(); | |||
| $this->assert($depth === 0); | |||
| $age = DB::queryFirstField("SELECT age FROM accounts WHERE username=%s", 'Abe'); | |||
| $this->assert($age == 700); | |||
| } | |||
| } | |||
| ?> | |||
| @@ -0,0 +1,85 @@ | |||
| <?php | |||
| class TransactionTest_55 extends SimpleTest { | |||
| function test_1_transactions() { | |||
| DB::$nested_transactions = true; | |||
| $depth = DB::startTransaction(); | |||
| $this->assert($depth === 1); | |||
| DB::query("UPDATE accounts SET age=%i WHERE username=%s", 700, 'Abe'); | |||
| $depth = DB::startTransaction(); | |||
| $this->assert($depth === 2); | |||
| DB::query("UPDATE accounts SET age=%i WHERE username=%s", 800, 'Abe'); | |||
| $depth = DB::startTransaction(); | |||
| $this->assert($depth === 3); | |||
| $this->assert(DB::transactionDepth() === 3); | |||
| DB::query("UPDATE accounts SET age=%i WHERE username=%s", 500, 'Abe'); | |||
| $depth = DB::commit(); | |||
| $this->assert($depth === 2); | |||
| $age = DB::queryFirstField("SELECT age FROM accounts WHERE username=%s", 'Abe'); | |||
| $this->assert($age == 500); | |||
| $depth = DB::rollback(); | |||
| $this->assert($depth === 1); | |||
| $age = DB::queryFirstField("SELECT age FROM accounts WHERE username=%s", 'Abe'); | |||
| $this->assert($age == 700); | |||
| $depth = DB::commit(); | |||
| $this->assert($depth === 0); | |||
| $age = DB::queryFirstField("SELECT age FROM accounts WHERE username=%s", 'Abe'); | |||
| $this->assert($age == 700); | |||
| DB::$nested_transactions = false; | |||
| } | |||
| function test_2_transactions() { | |||
| DB::$nested_transactions = true; | |||
| DB::query("UPDATE accounts SET age=%i WHERE username=%s", 600, 'Abe'); | |||
| DB::startTransaction(); | |||
| DB::query("UPDATE accounts SET age=%i WHERE username=%s", 700, 'Abe'); | |||
| DB::startTransaction(); | |||
| DB::query("UPDATE accounts SET age=%i WHERE username=%s", 800, 'Abe'); | |||
| DB::rollback(); | |||
| $age = DB::queryFirstField("SELECT age FROM accounts WHERE username=%s", 'Abe'); | |||
| $this->assert($age == 700); | |||
| DB::rollback(); | |||
| $age = DB::queryFirstField("SELECT age FROM accounts WHERE username=%s", 'Abe'); | |||
| $this->assert($age == 600); | |||
| DB::$nested_transactions = false; | |||
| } | |||
| function test_3_transaction_rollback_all() { | |||
| DB::$nested_transactions = true; | |||
| DB::query("UPDATE accounts SET age=%i WHERE username=%s", 200, 'Abe'); | |||
| $depth = DB::startTransaction(); | |||
| $this->assert($depth === 1); | |||
| DB::query("UPDATE accounts SET age=%i WHERE username=%s", 300, 'Abe'); | |||
| $depth = DB::startTransaction(); | |||
| $this->assert($depth === 2); | |||
| DB::query("UPDATE accounts SET age=%i WHERE username=%s", 400, 'Abe'); | |||
| $depth = DB::rollback(true); | |||
| $this->assert($depth === 0); | |||
| $age = DB::queryFirstField("SELECT age FROM accounts WHERE username=%s", 'Abe'); | |||
| $this->assert($age == 200); | |||
| DB::$nested_transactions = false; | |||
| } | |||
| } | |||
| ?> | |||
| @@ -0,0 +1,83 @@ | |||
| <?php | |||
| class WhereClauseTest extends SimpleTest { | |||
| function test_1_basic_where() { | |||
| $where = new WhereClause('and'); | |||
| $where->add('username=%s', 'Bart'); | |||
| $where->add('password=%s', 'hello'); | |||
| $result = DB::query("SELECT * FROM accounts WHERE %l", $where->text()); | |||
| $this->assert(count($result) === 1); | |||
| $this->assert($result[0]['age'] === '15'); | |||
| } | |||
| function test_2_simple_grouping() { | |||
| $where = new WhereClause('and'); | |||
| $where->add('password=%s', 'hello'); | |||
| $subclause = $where->addClause('or'); | |||
| $subclause->add('age=%i', 15); | |||
| $subclause->add('age=%i', 14); | |||
| $result = DB::query("SELECT * FROM accounts WHERE %l", $where->text()); | |||
| $this->assert(count($result) === 1); | |||
| $this->assert($result[0]['age'] === '15'); | |||
| } | |||
| function test_3_negate_last() { | |||
| $where = new WhereClause('and'); | |||
| $where->add('password=%s', 'hello'); | |||
| $subclause = $where->addClause('or'); | |||
| $subclause->add('username!=%s', 'Bart'); | |||
| $subclause->negateLast(); | |||
| $result = DB::query("SELECT * FROM accounts WHERE %l", $where->text()); | |||
| $this->assert(count($result) === 1); | |||
| $this->assert($result[0]['age'] === '15'); | |||
| } | |||
| function test_4_negate_last_query() { | |||
| $where = new WhereClause('and'); | |||
| $where->add('password=%s', 'hello'); | |||
| $subclause = $where->addClause('or'); | |||
| $subclause->add('username!=%s', 'Bart'); | |||
| $where->negateLast(); | |||
| $result = DB::query("SELECT * FROM accounts WHERE %l", $where); | |||
| $this->assert(count($result) === 1); | |||
| $this->assert($result[0]['age'] === '15'); | |||
| } | |||
| function test_5_negate() { | |||
| $where = new WhereClause('and'); | |||
| $where->add('password=%s', 'hello'); | |||
| $subclause = $where->addClause('or'); | |||
| $subclause->add('username!=%s', 'Bart'); | |||
| $subclause->negate(); | |||
| $result = DB::query("SELECT * FROM accounts WHERE %l", $where); | |||
| $this->assert(count($result) === 1); | |||
| $this->assert($result[0]['age'] === '15'); | |||
| } | |||
| function test_6_negate_two() { | |||
| $where = new WhereClause('and'); | |||
| $where->add('password=%s', 'hello'); | |||
| $where->add('username=%s', 'Bart'); | |||
| $where->negate(); | |||
| $result = DB::query("SELECT * FROM accounts WHERE %l", $where); | |||
| $this->assert(count($result) === 7); | |||
| } | |||
| function test_7_or() { | |||
| $where = new WhereClause('or'); | |||
| $where->add('username=%s', 'Bart'); | |||
| $where->add('username=%s', 'Abe'); | |||
| $result = DB::query("SELECT * FROM accounts WHERE %l", $where); | |||
| $this->assert(count($result) === 2); | |||
| } | |||
| } | |||
| ?> | |||
| @@ -0,0 +1,87 @@ | |||
| #!/usr/bin/php | |||
| <?php | |||
| class SimpleTest { | |||
| public function assert($boolean) { | |||
| if (! $boolean) $this->fail(); | |||
| } | |||
| protected function fail($msg = '') { | |||
| echo "FAILURE! $msg\n"; | |||
| debug_print_backtrace(); | |||
| die; | |||
| } | |||
| } | |||
| function microtime_float() | |||
| { | |||
| list($usec, $sec) = explode(" ", microtime()); | |||
| return ((float)$usec + (float)$sec); | |||
| } | |||
| if (phpversion() >= '5.3') $is_php_53 = true; | |||
| else $is_php_53 = false; | |||
| ini_set('date.timezone', 'America/Los_Angeles'); | |||
| error_reporting(E_ALL | E_STRICT); | |||
| require_once '../db.class.php'; | |||
| include 'test_setup.php'; //test config values go here | |||
| // WARNING: ALL tables in the database will be dropped before the tests, including non-test related tables. | |||
| DB::$user = $set_db_user; | |||
| DB::$password = $set_password; | |||
| DB::$dbName = $set_db; | |||
| DB::$host = $set_host; | |||
| DB::get(); //connect to mysql | |||
| require_once 'BasicTest.php'; | |||
| require_once 'CallTest.php'; | |||
| require_once 'ObjectTest.php'; | |||
| require_once 'WhereClauseTest.php'; | |||
| require_once 'ErrorTest.php'; | |||
| require_once 'TransactionTest.php'; | |||
| require_once 'HelperTest.php'; | |||
| $classes_to_test = array( | |||
| 'BasicTest', | |||
| 'CallTest', | |||
| 'WhereClauseTest', | |||
| 'ObjectTest', | |||
| 'ErrorTest', | |||
| 'TransactionTest', | |||
| 'HelperTest', | |||
| ); | |||
| if ($is_php_53) { | |||
| require_once 'ErrorTest_53.php'; | |||
| $classes_to_test[] = 'ErrorTest_53'; | |||
| } else { | |||
| echo "PHP 5.3 not detected, skipping 5.3 tests..\n"; | |||
| } | |||
| $mysql_version = DB::serverVersion(); | |||
| if ($mysql_version >= '5.5') { | |||
| require_once 'TransactionTest_55.php'; | |||
| $classes_to_test[] = 'TransactionTest_55'; | |||
| } else { | |||
| echo "MySQL 5.5 not available (version is $mysql_version) -- skipping MySQL 5.5 tests\n"; | |||
| } | |||
| $time_start = microtime_float(); | |||
| foreach ($classes_to_test as $class) { | |||
| $object = new $class(); | |||
| foreach (get_class_methods($object) as $method) { | |||
| if (substr($method, 0, 4) != 'test') continue; | |||
| echo "Running $class::$method..\n"; | |||
| $object->$method(); | |||
| } | |||
| } | |||
| $time_end = microtime_float(); | |||
| $time = round($time_end - $time_start, 2); | |||
| echo "Completed in $time seconds\n"; | |||
| ?> | |||