| <?xml version="1.0" encoding="UTF-8"?> | |||||
| <buildpath> | |||||
| <buildpathentry kind="src" path=""/> | |||||
| <buildpathentry kind="con" path="org.eclipse.php.core.LANGUAGE"/> | |||||
| </buildpath> |
| <?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> |
| eclipse.preferences.version=1 | |||||
| include_path=0;/dedicatedip | |||||
| use_asp_tags_as_php=false |
| { | |||||
| "require": { | |||||
| "sergeytsalkov/meekrodb": "2.3.*" | |||||
| } | |||||
| } |
| { | |||||
| "_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" | |||||
| } |
| <?php | |||||
| $dbhost = "localhost"; | |||||
| $dbuser = "license"; | |||||
| $dbpass = "Nbc3PhYCn3Fn0a7"; | |||||
| $dbname = "license"; |
| ----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 --- | |||||
| ------ |
| <?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; | |||||
| } | |||||
| ?> |
| 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 |
| <?php | |||||
| // autoload.php @generated by Composer | |||||
| require_once __DIR__ . '/composer/autoload_real.php'; | |||||
| return ComposerAutoloaderInit9e6487acd796bef3591a49601b8f5a50::getLoader(); |
| <?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; | |||||
| } |
| <?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; | |||||
| } | |||||
| } |
| 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. | |||||
| <?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', | |||||
| ); |
| <?php | |||||
| // autoload_namespaces.php @generated by Composer | |||||
| $vendorDir = dirname(dirname(__FILE__)); | |||||
| $baseDir = dirname($vendorDir); | |||||
| return array( | |||||
| ); |
| <?php | |||||
| // autoload_psr4.php @generated by Composer | |||||
| $vendorDir = dirname(dirname(__FILE__)); | |||||
| $baseDir = dirname($vendorDir); | |||||
| return array( | |||||
| ); |
| <?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; | |||||
| } | |||||
| } |
| <?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); | |||||
| } | |||||
| } |
| { | |||||
| "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": [] | |||||
| } |
| <?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', | |||||
| ), | |||||
| ), | |||||
| ); |
| <?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 | |||||
| ); | |||||
| } |
| simpletest/test_setup.php |
| 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. |
| 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! |
| { | |||||
| "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" | |||||
| ] | |||||
| } | |||||
| } |
| <?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'); | |||||
| } | |||||
| } | |||||
| ?> |
| <?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'); | |||||
| } | |||||
| } |
| <?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); | |||||
| } | |||||
| } | |||||
| ?> |
| <?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); | |||||
| } | |||||
| } | |||||
| ?> |
| <?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); | |||||
| } | |||||
| } | |||||
| ?> |
| <?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); | |||||
| } | |||||
| } | |||||
| ?> |
| <?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); | |||||
| } | |||||
| } | |||||
| ?> |
| <?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; | |||||
| } | |||||
| } | |||||
| ?> |
| <?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); | |||||
| } | |||||
| } | |||||
| ?> |
| #!/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"; | |||||
| ?> |