├── .github └── workflows │ └── main.yml ├── .gitignore ├── CREDITS ├── EXPERIMENTAL ├── LICENSE ├── README.md ├── config.m4 ├── config.w32 ├── doc └── leveldb │ ├── book.xml │ ├── configure.xml │ ├── constants.xml │ ├── examples.xml │ ├── leveldb.xml │ ├── leveldb │ ├── close.xml │ ├── compactrange.xml │ ├── construct.xml │ ├── delete.xml │ ├── destroy.xml │ ├── get.xml │ ├── getapproximatesizes.xml │ ├── getproperty.xml │ ├── put.xml │ ├── repair.xml │ ├── set.xml │ └── write.xml │ ├── leveldbexception.xml │ ├── leveldbiterator.xml │ ├── leveldbiterator │ ├── construct.xml │ ├── current.xml │ ├── destroy.xml │ ├── geterror.xml │ ├── key.xml │ ├── last.xml │ ├── next.xml │ ├── prev.xml │ ├── rewind.xml │ ├── seek.xml │ └── valid.xml │ ├── leveldbwritebatch.xml │ ├── leveldbwritebatch │ ├── clear.xml │ ├── construct.xml │ ├── delete.xml │ ├── put.xml │ └── set.xml │ ├── reference.xml │ ├── setup.xml │ └── versions.xml ├── leveldb.c ├── package.xml ├── php_leveldb.h ├── stub.php └── tests ├── 001-basic.phpt ├── 002-db-management.phpt ├── 003-openbasedir.phpt ├── 004-write-batch.phpt ├── 005-iterator.phpt ├── 006-iterator-foreach.phpt ├── 007-db-close.phpt ├── 008-options.phpt ├── 009-comparator.phpt ├── 010-compression.phpt ├── 011-getApproximateSizes.phpt ├── 012-getProperty.phpt ├── 013-compactRange.phpt ├── 014-iterator-destroy.phpt ├── 015-double-iterator.phpt ├── 016-different-iterators-should-differ.phpt ├── 017-db-getIterator.phpt ├── 018-snapshot.phpt ├── 019-null-comparator.phpt ├── 020-null-snapshot.phpt ├── leveldb.inc └── skipif.inc /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | pull_request: 6 | workflow_dispatch: 7 | 8 | jobs: 9 | build: 10 | name: PHP ${{ matrix.php }}, ZTS ${{ matrix.zts }} 11 | runs-on: ubuntu-22.04 12 | if: "!contains(github.event.head_commit.message, '[ci skip]')" 13 | 14 | strategy: 15 | fail-fast: false 16 | matrix: 17 | php: 18 | - 7.0.33 19 | - 7.1.33 20 | - 7.2.34 21 | - 7.3.33 22 | - 7.4.29 23 | - 8.0.27 24 | - 8.1.27 25 | - 8.2.14 26 | - 8.3.1 27 | leveldb: [1.23] 28 | zts: [enable, disable] 29 | 30 | env: 31 | CFLAGS: "-march=x86-64 -DZEND_TRACK_ARENA_ALLOC=1" 32 | CXXFLAGS: "-march=x86-64" 33 | steps: 34 | - uses: actions/checkout@v4 35 | 36 | - name: Install build dependencies 37 | run: sudo apt-get update && sudo apt-get install re2c valgrind 38 | 39 | - name: Restore LevelDB build cache 40 | id: leveldb-build-cache 41 | uses: actions/cache@v4 42 | with: 43 | path: ${{ github.workspace }}/leveldb 44 | key: leveldb-${{ matrix.leveldb }}-${{ hashFiles('.github/workflows/main.yml') }} 45 | 46 | - name: Compile LevelDB 47 | if: steps.leveldb-build-cache.outputs.cache-hit != 'true' 48 | run: | 49 | sudo apt update && sudo apt install cmake 50 | curl -sSL https://github.com/google/leveldb/archive/${{ matrix.leveldb }}.tar.gz | tar -xz 51 | cd leveldb-${{ matrix.leveldb }} 52 | cmake \ 53 | -DCMAKE_INSTALL_PREFIX="${{ github.workspace }}/leveldb" \ 54 | -DCMAKE_PREFIX_PATH="${{ github.workspace }}/leveldb" \ 55 | -DCMAKE_INSTALL_LIBDIR=lib \ 56 | -DLEVELDB_BUILD_TESTS=OFF \ 57 | -DLEVELDB_BUILD_BENCHMARKS=OFF \ 58 | -DLEVELDB_SNAPPY=OFF \ 59 | -DLEVELDB_ZSTD=OFF \ 60 | -DLEVELDB_TCMALLOC=OFF \ 61 | -DCMAKE_BUILD_TYPE=Release \ 62 | -DBUILD_SHARED_LIBS=ON . 63 | make -j8 install 64 | 65 | - name: Restore PHP build cache 66 | uses: actions/cache@v4 67 | id: php-build-cache 68 | with: 69 | path: ${{ github.workspace }}/php 70 | key: php-debug-${{ matrix.php }}-zts-${{ matrix.zts }}-ubuntu2204 71 | 72 | - name: Get number of CPU cores 73 | if: steps.php-build-cache.outputs.cache-hit != 'true' 74 | uses: SimenB/github-actions-cpu-cores@v2 75 | id: cpu-cores 76 | 77 | - name: Download PHP 78 | if: steps.php-build-cache.outputs.cache-hit != 'true' 79 | run: curl -L https://github.com/php/php-src/archive/refs/tags/php-${{ matrix.php }}.tar.gz | tar -xz 80 | 81 | - name: Install Bison 3.0.5 for older PHP versions 82 | if: steps.php-build-cache.outputs.cache-hit != 'true' && (matrix.php == '7.0.33' || matrix.php == '7.1.33' || matrix.php == '7.2.34' || matrix.php == '7.3.33') 83 | run: | 84 | echo "Installing Bison 3.0.5 for PHP ${{ matrix.php }}..." 85 | sudo apt-get update 86 | sudo apt-get install -y m4 build-essential 87 | sudo apt-get remove --purge -y bison 88 | curl -L https://ftp.gnu.org/gnu/bison/bison-3.0.5.tar.gz -o bison-3.0.5.tar.gz 89 | tar -xzf bison-3.0.5.tar.gz 90 | cd bison-3.0.5 91 | ./configure --prefix=/usr/local 92 | make 93 | sudo make install 94 | echo "Bison version after install:" 95 | bison --version 96 | cd .. 97 | 98 | - name: Compile PHP 99 | if: steps.php-build-cache.outputs.cache-hit != 'true' 100 | working-directory: php-src-php-${{ matrix.php }} 101 | run: | 102 | ./buildconf --force 103 | ./configure \ 104 | --disable-all \ 105 | --enable-cli \ 106 | --with-valgrind \ 107 | --enable-debug \ 108 | --${{ matrix.zts }}-zts \ 109 | --${{ matrix.zts }}-maintainer-zts \ 110 | --prefix="${{ github.workspace }}/php" 111 | make -j ${{ steps.cpu-cores.outputs.count }} install 112 | 113 | - name: Dump PHP info 114 | run: $GITHUB_WORKSPACE/php/bin/php -i 115 | 116 | - name: Build extension 117 | run: | 118 | $GITHUB_WORKSPACE/php/bin/phpize 119 | ./configure --with-php-config=$GITHUB_WORKSPACE/php/bin/php-config --with-leveldb=${{ github.workspace }}/leveldb 120 | make install 121 | 122 | - name: Run .phpt tests 123 | run: REPORT_EXIT_STATUS=1 NO_INTERACTION=1 TEST_PHP_ARGS="-m --show-diff" make test 124 | 125 | - name: Upload test results 126 | if: failure() 127 | uses: actions/upload-artifact@v4 128 | with: 129 | name: test-results-${{ matrix.php }}-zts-${{ matrix.zts }}-leveldb-${{ matrix.leveldb }} 130 | path: | 131 | ${{ github.workspace }}/tests/* 132 | !${{ github.workspace }}/tests/*.phpt 133 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # General Ignores 2 | tests/*.test-db 3 | *~ 4 | .#* 5 | *. 6 | *.slo 7 | *.mk 8 | *.mem 9 | *.gcda 10 | *.gcno 11 | *.la 12 | *.lo 13 | *.o 14 | *.a 15 | *.ncb 16 | *.opt 17 | *.plg 18 | *swp 19 | *.patch 20 | *.tgz 21 | *.tar.gz 22 | *.tar.bz2 23 | .FBCIndex 24 | .FBCLockFolder 25 | .deps 26 | .libs 27 | 28 | Makefile 29 | Makefile.fragments 30 | Makefile.objects 31 | 32 | acconfig.h 33 | aclocal.m4 34 | autom4te.cache 35 | bsd_converted 36 | buildconf.stamp 37 | buildmk.stamp 38 | confdefs.h 39 | config.h 40 | config.guess 41 | config.cache 42 | config.h.in 43 | config.log 44 | config.nice 45 | config.nice.bat 46 | config.status 47 | config.sub 48 | config_vars.mk 49 | configure 50 | configure.bat 51 | configure.js 52 | conftest 53 | conftest.c 54 | debug.log 55 | diff 56 | generated_lists 57 | include 58 | install-sh 59 | internal_functions.c 60 | lcov_data 61 | lcov_html 62 | libs 63 | libtool 64 | meta_cc 65 | meta_ccld 66 | missing 67 | mkinstalldirs 68 | modules 69 | 70 | # Test specific Ignores 71 | tests/*.diff 72 | tests/*.out 73 | tests/*.php 74 | tests/*.exp 75 | tests/*.log 76 | tests/*.sh -------------------------------------------------------------------------------- /CREDITS: -------------------------------------------------------------------------------- 1 | leveldb 2 | Reeze Xia 3 | Dylan K. Taylor 4 | -------------------------------------------------------------------------------- /EXPERIMENTAL: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reeze/php-leveldb/70ecae7103dbfe0817740f1c2aeaed551e2f67f6/EXPERIMENTAL -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------- 2 | The PHP License, version 3.01 3 | Copyright (c) 1999 - 2012 The PHP Group. All rights reserved. 4 | -------------------------------------------------------------------- 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, is permitted provided that the following conditions 8 | are met: 9 | 10 | 1. Redistributions of source code must retain the above copyright 11 | notice, this list of conditions and the following disclaimer. 12 | 13 | 2. Redistributions in binary form must reproduce the above copyright 14 | notice, this list of conditions and the following disclaimer in 15 | the documentation and/or other materials provided with the 16 | distribution. 17 | 18 | 3. The name "PHP" must not be used to endorse or promote products 19 | derived from this software without prior written permission. For 20 | written permission, please contact group@php.net. 21 | 22 | 4. Products derived from this software may not be called "PHP", nor 23 | may "PHP" appear in their name, without prior written permission 24 | from group@php.net. You may indicate that your software works in 25 | conjunction with PHP by saying "Foo for PHP" instead of calling 26 | it "PHP Foo" or "phpfoo" 27 | 28 | 5. The PHP Group may publish revised and/or new versions of the 29 | license from time to time. Each version will be given a 30 | distinguishing version number. 31 | Once covered code has been published under a particular version 32 | of the license, you may always continue to use it under the terms 33 | of that version. You may also choose to use such covered code 34 | under the terms of any subsequent version of the license 35 | published by the PHP Group. No one other than the PHP Group has 36 | the right to modify the terms applicable to covered code created 37 | under this License. 38 | 39 | 6. Redistributions of any form whatsoever must retain the following 40 | acknowledgment: 41 | "This product includes PHP software, freely available from 42 | ". 43 | 44 | THIS SOFTWARE IS PROVIDED BY THE PHP DEVELOPMENT TEAM ``AS IS'' AND 45 | ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 46 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 47 | PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PHP 48 | DEVELOPMENT TEAM OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 49 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 50 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 51 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 52 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 53 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 54 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 55 | OF THE POSSIBILITY OF SUCH DAMAGE. 56 | 57 | -------------------------------------------------------------------- 58 | 59 | This software consists of voluntary contributions made by many 60 | individuals on behalf of the PHP Group. 61 | 62 | The PHP Group can be contacted via Email at group@php.net. 63 | 64 | For more information on the PHP Group and the PHP project, 65 | please see . 66 | 67 | PHP includes the Zend Engine, freely available at 68 | . -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PHP-LevelDB: The PHP Binding for LevelDB 2 | 3 | Build Status: [![CI](https://github.com/reeze/php-leveldb/workflows/CI/badge.svg)](https://github.com/reeze/php-leveldb/actions?query=workflow%3ACI) 4 | 5 | LevelDB is a fast key-value storage library written at Google that provides an ordered mapping from string keys to string values. 6 | 7 | This extension is a binding for LevelDB 8 | 9 | Please send Feature Request or Bug report with [GitHub Issue](https://github.com/reeze/php-leveldb/issues). 10 | 11 | ## Requirements 12 | - PHP >= 7 13 | - LevelDB >= 1.7 14 | 15 | You can install leveldb from your os distribution: 16 | 17 | $ sudo apt-get install libleveldb-dev 18 | 19 | 20 | Or you could get leveldb from: 21 | 22 | $ git clone https://github.com/google/leveldb.git 23 | $ cd leveldb 24 | $ cmake . 25 | $ make 26 | 27 | ## Installation 28 | 29 | $ git clone https://github.com/reeze/php-leveldb.git 30 | $ cd php-leveldb 31 | $ phpize 32 | $ ./configure --with-leveldb=/path/to/your/leveldb-1.*.* 33 | $ make 34 | $ make install 35 | 36 | 1. Install from PECL 37 | 38 | 39 | 40 | ## API Reference 41 | 42 | API Reference could be found here: 43 | 44 | ## Usage 45 | Since PHP-LevelDB is a binding for LevelDB, most of the interfaces are the same as 46 | LevelDB's: 47 | 48 | ### Open options 49 | When opening a leveldb database you could specify options to override default values: 50 | 51 | ````php 52 | true, // if the specified database didn't exist will create a new one 56 | 'error_if_exists' => false, // if the opened database exsits will throw exception 57 | 'paranoid_checks' => false, 58 | 'block_cache_size' => 8 * (2 << 20), 59 | 'write_buffer_size' => 4<<20, 60 | 'block_size' => 4096, 61 | 'max_open_files' => 1000, 62 | 'block_restart_interval' => 16, 63 | 'compression' => LEVELDB_SNAPPY_COMPRESSION, 64 | 'comparator' => NULL, // any callable parameter which returns 0, -1, 1 65 | ); 66 | /* default readoptions */ 67 | $readoptions = array( 68 | 'verify_check_sum' => false, 69 | 'fill_cache' => true, 70 | 'snapshot' => null 71 | ); 72 | 73 | /* default write options */ 74 | $writeoptions = array( 75 | 'sync' => false 76 | ); 77 | 78 | $db = new LevelDB("/path/to/db", $options, $readoptions, $writeoptions); 79 | ```` 80 | 81 | >**NOTE** The readoptions and writeoptions will take effect when operating on 82 | >the db afterward, but you could override it by specify read/write options when 83 | >accessing 84 | 85 | ### Using custom comparator 86 | You could write your own comparator, the comparator can be anything callable in php the same as usort()'s compare function: , and the comparator 87 | could be: 88 | 89 | ````php 90 | 'cmp')); 93 | function cmp($a, $b) 94 | { 95 | return strcmp($a, $b); 96 | } 97 | ```` 98 | 99 | >**NOTE** 100 | >If you create a database with custom comparator, you can only open it again 101 | >with the same comparator. 102 | 103 | ### Basic operations: get(), put(), delete() 104 | LevelDB is a key-value database, you could do those basic operations on it: 105 | 106 | ````php 107 | put("Key", "Value"); 115 | $db->set("Key2", "Value2"); // set() is an alias of put() 116 | $db->get("Key"); 117 | $db->delete("Key"); 118 | ```` 119 | 120 | >**NOTE** 121 | >Some key-value db use set instead of put to set value, so if like set(), 122 | >you could use set() to save value. 123 | 124 | ### Write in a batch 125 | If you want to do a sequence of updates and want to make it atomically, 126 | then writebatch will be your friend. 127 | 128 | >The WriteBatch holds a sequence of edits to be made to the database, 129 | >and these edits within the batch are applied in order. 130 | > 131 | >Apart from its atomicity benefits, WriteBatch may also be used to speed up 132 | >bulk updates by placing lots of individual mutations into the same batch. 133 | 134 | ````php 135 | put("key2", "batch value"); 141 | $batch->put("key3", "batch value"); 142 | $batch->set("key4", "a bounch of values"); // set() is an alias of put() 143 | $batch->delete("some key"); 144 | 145 | // Write once 146 | $db->write($batch); 147 | ```` 148 | 149 | ### Iterate through db 150 | 151 | You can iterate through the whole database by iteration: 152 | 153 | ````php 154 | getIterator(); 158 | 159 | // Loop in iterator style 160 | while($it->valid()) { 161 | var_dump($it->key() . " => " . $it->current() . "\n"); 162 | } 163 | 164 | // Or loop in foreach 165 | foreach($it as $key => $value) { 166 | echo "{$key} => {$value}\n"; 167 | } 168 | ```` 169 | 170 | If you want to iterate by reverse order, you could: 171 | 172 | ````php 173 | last(); $it->valid(); $it->prev()) { 179 | echo "{$key} => {$value}\n"; 180 | } 181 | 182 | /* 183 | * And you could seek with: rewind(), next(), prev(), seek() 184 | */ 185 | ```` 186 | 187 | >**NOTE** In LevelDB LevelDB::seek() will success even when the key doesn't exist. 188 | >It will seek to the latest key: 189 | >`db-with-key('a', 'b', 'd', 'e'); $db->seek('c');` iterator will point to `key 'd'` 190 | 191 | ### Snapshots 192 | Snapshots provide consistent read-only views over the entire state of the key-value store. 193 | `$read_options['snapshot']` may be non-NULL to indicate that a read should operate on a 194 | particular version of the DB state. If `$read_options['snapshot']` is NULL, the read will 195 | operate on an implicit snapshot of the current state. 196 | 197 | Snapshots are created by the LevelDB::getSnapshot() method: 198 | 199 | ````php 200 | put("key1", "value1"); 204 | $db->put("key2", "value2"); 205 | 206 | $snapshot = $db->getSnapshot(); 207 | 208 | $db->put("key3", "value3"); 209 | 210 | $read_options = array("snapshot" => $snapshot); 211 | $db->get("key3", $read_options); // false but not "value3" 212 | $db->get("key3"); // "value3" since not read from snapshot 213 | 214 | 215 | $it = $db->getIterator($read_options); 216 | foreach($it as $k => $v) { 217 | printf("$k => $v\n"); 218 | } 219 | /* 220 | Output: 221 | key1 => value1 222 | key2 => value2 223 | 224 | key3 was not found because we are reading from snapshot 225 | */ 226 | 227 | ?> 228 | ```` 229 | 230 | ## Operations on database 231 | 232 | ### LevelDB::close() 233 | Since leveldb can only accessed by a single proccess one time, you may want to 234 | close it when you aren't using it anymore. 235 | 236 | ````php 237 | close(); 242 | $it->next(); // noop you can't do that, exception thrown 243 | $db->set("key", "value"); // you can't do this either 244 | ```` 245 | 246 | after database been closed, you can't do anything on it. 247 | 248 | ### LevelDB::destroy() 249 | If you want to destroy a database, you could delete the whole database by hand: 250 | `rm -rf /path/to/db` or you could use `LevelDB::destroy('/path/to/db')`. 251 | 252 | Be careful with this. 253 | 254 | >**NOTE** 255 | >Before you destroy a database, please make sure it was closed. or 256 | >an exception will thrown. (LevelDB >= 1.7.0) 257 | 258 | ### LevelDB::repair() 259 | If you can't open a database, neither been locked or other error, if it's corrupted, 260 | you could use `LevelDB::repair('/path/to/db')` to repair it. It will try to recover 261 | as much data as possible. 262 | 263 | ## Known limitations 264 | 265 | LevelDB was designed to be thread-safe but not process-safe, so if you 266 | use php in multi-process mode (eg, php-fpm) you might not able to open 267 | the single db concurrently. 268 | 269 | > If you app is not designed to serve massive requests, you could try 270 | > to catch fail to open exception and try to open it again. 271 | 272 | ## Thanks 273 | 274 | Thanks Arpad for his original implementation: 275 | and his generous. 276 | 277 | ## Reference 278 | More info could be found at: 279 | 280 | - LevelDB project home: 281 | - LevelDB document: 282 | - A LevelDB internals analysis in Chinese 283 | 284 | ## License 285 | PHP-LevelDB is licensed under the PHP License 286 | -------------------------------------------------------------------------------- /config.m4: -------------------------------------------------------------------------------- 1 | dnl $Id$ 2 | dnl config.m4 for extension leveldb 3 | 4 | PHP_ARG_WITH(leveldb, for leveldb support, 5 | [ --with-leveldb[=Path] Include leveldb support]) 6 | 7 | if test "$PHP_LEVELDB" != "no"; then 8 | 9 | # --with-leveldb -> check with-path 10 | SEARCH_PATH="/usr/local /usr" 11 | SEARCH_FOR="include/leveldb/c.h" 12 | SEARCH_LIB="libleveldb" 13 | 14 | dnl search leveldb 15 | AC_MSG_CHECKING([for leveldb location]) 16 | for i in $PHP_LEVELDB $SEARCH_PATH ; do 17 | if test -r $i/$SEARCH_FOR; then 18 | LEVELDB_INCLUDE_DIR=$i 19 | AC_MSG_RESULT(leveldb headers found in $i) 20 | fi 21 | 22 | if test -r $i/$PHP_LIBDIR/$SEARCH_LIB.a || test -r $i/$PHP_LIBDIR/$SEARCH_LIB.$SHLIB_SUFFIX_NAME; then 23 | LEVELDB_LIB_DIR=$i/$PHP_LIBDIR 24 | AC_MSG_RESULT(leveldb lib found in $i/lib) 25 | fi 26 | 27 | dnl from Leveldb build dir 28 | if test -r $i/$SEARCH_LIB.a || test -r $i/$SEARCH_LIB.$SHLIB_SUFFIX_NAME; then 29 | LEVELDB_LIB_DIR=$i 30 | AC_MSG_RESULT(leveldb lib found in $i) 31 | fi 32 | 33 | if test -z "$LEVELDB_LIB_DIR"; then 34 | for j in "lib/x86_64-linux-gnu" "lib/x86_64-linux-gnu"; do 35 | echo find "--$i/$j" 36 | if test -r $i/$j/$SEARCH_LIB.a || test -r $i/$j/$SEARCH_LIB.$SHLIB_SUFFIX_NAME; then 37 | LEVELDB_LIB_DIR=$i/$j 38 | AC_MSG_RESULT(leveldb lib found in $i/$j) 39 | fi 40 | done 41 | fi 42 | done 43 | 44 | if test -z "$LEVELDB_INCLUDE_DIR" || test -z "$LEVELDB_LIB_DIR"; then 45 | AC_MSG_RESULT([leveldb not found]) 46 | AC_MSG_ERROR([Please reinstall the leveldb distribution]) 47 | fi 48 | 49 | # --with-leveldb -> add include path 50 | PHP_ADD_INCLUDE($LEVELDB_INCLUDE_DIR/include) 51 | 52 | # --with-leveldb -> check for lib and symbol presence 53 | LIBNAME=leveldb 54 | PHP_ADD_LIBRARY_WITH_PATH($LIBNAME, $LEVELDB_LIB_DIR, LEVELDB_SHARED_LIBADD) 55 | 56 | PHP_SUBST(LEVELDB_SHARED_LIBADD) 57 | 58 | PHP_NEW_EXTENSION(leveldb, leveldb.c, $ext_shared) 59 | fi 60 | -------------------------------------------------------------------------------- /config.w32: -------------------------------------------------------------------------------- 1 | // $Id$ 2 | // vim:ft=javascript 3 | 4 | ARG_WITH("leveldb", "leveldb support", "no"); 5 | 6 | if (PHP_LEVELDB != "no") { 7 | if (CHECK_LIB("leveldb.lib", "leveldb", PHP_LEVELDB) && 8 | CHECK_HEADER_ADD_INCLUDE("c.h", "CFLAGS_LEVELDB", PHP_LEVELDB+ ";" + PHP_PHP_BUILD + "\\include\\leveldb")) { 9 | EXTENSION("leveldb", "leveldb.c", PHP_LEVELDB_SHARED, ""); 10 | } else { 11 | WARNING("leveldb not enabled; libraries and headers not found"); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /doc/leveldb/book.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Leveldb 6 | Leveldb 7 | 8 | 9 | &reftitle.intro; 10 | 11 | This extension enables you to use Level DB By Using PHP. 12 | 13 | 14 | 15 | 16 | 17 | &reference.leveldb.setup; 18 | &reference.leveldb.constants; 19 | &reference.leveldb.examples; 20 | &reference.leveldb.leveldbiterator; 21 | &reference.leveldb.leveldbwritebatch; 22 | &reference.leveldb.leveldb; 23 | 24 | 25 | 26 | 46 | -------------------------------------------------------------------------------- /doc/leveldb/configure.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 | &reftitle.install; 6 | 7 | 8 | &pecl.info; 9 | &url.pecl.package;leveldb 10 | 11 | 12 | 13 |
14 | 15 | 16 | 36 | -------------------------------------------------------------------------------- /doc/leveldb/constants.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | &reftitle.constants; 6 | &extension.constants; 7 | 8 | 9 | 10 | 11 | LEVELDB_NO_COMPRESSION 12 | (integer) 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | LEVELDB_SNAPPY_COMPRESSION 22 | (integer) 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 53 | -------------------------------------------------------------------------------- /doc/leveldb/examples.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | &reftitle.examples; 6 | 7 | Leveldb Example 8 | 9 | 15 | ]]> 16 | 17 | &example.outputs.similar; 18 | 19 | 22 | 23 | 24 | 25 | 26 | 46 | -------------------------------------------------------------------------------- /doc/leveldb/leveldb.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | The LevelDB class 7 | LevelDB 8 | 9 | 10 | 11 | 12 |
13 | &reftitle.intro; 14 | 15 | 16 | 17 |
18 | 19 | 20 |
21 | &reftitle.classsynopsis; 22 | 23 | 24 | 25 | LevelDB 26 | 27 | 28 | 29 | 30 | LevelDB 31 | 32 | 33 | 34 | 35 | &Methods; 36 | 37 | 38 | 39 | 40 |
41 | 42 |
43 | 44 | &reference.leveldb.entities.leveldb; 45 | 46 |
47 | 48 | 68 | -------------------------------------------------------------------------------- /doc/leveldb/leveldb/close.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | LevelDB::close 7 | Close this database 8 | 9 | 10 | 11 | &reftitle.description; 12 | 13 | public voidLevelDB::close 14 | 15 | 16 | 17 | This closes the database currently being opend. 18 | 19 | 20 | 21 | 22 | 23 | &reftitle.parameters; 24 | &no.function.parameters; 25 | 26 | 27 | 28 | &reftitle.returnvalues; 29 | 30 | 31 | 32 | 33 | 34 | 35 | &reftitle.examples; 36 | 37 | <function>LevelDB::close</function> example 38 | 39 | 'cmp')); 43 | function cmp($a, $b) { 44 | return strcmp($a, $b); 45 | } 46 | var_dump($db->close()); 47 | 48 | ?> 49 | ]]> 50 | 51 | &example.outputs.similar; 52 | 53 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 83 | -------------------------------------------------------------------------------- /doc/leveldb/leveldb/compactrange.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | LevelDB::compactRange 7 | The compactRange purpose 8 | 9 | 10 | 11 | &reftitle.description; 12 | 13 | public voidLevelDB::compactRange 14 | stringstart 15 | stringlimit 16 | 17 | 18 | 19 | 20 | 21 | &warn.undocumented.func; 22 | 23 | 24 | 25 | 26 | &reftitle.parameters; 27 | 28 | 29 | start 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | limit 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | &reftitle.returnvalues; 49 | 50 | 51 | 52 | 53 | 54 | 55 | &reftitle.examples; 56 | 57 | <function>LevelDB::compactRange</function> example 58 | 59 | 65 | ]]> 66 | 67 | &example.outputs.similar; 68 | 69 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 99 | -------------------------------------------------------------------------------- /doc/leveldb/leveldb/construct.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | LevelDB::__construct 7 | Construct a new LevelDb object 8 | 9 | 10 | 11 | &reftitle.description; 12 | 13 | public LevelDB::__construct 14 | stringname 15 | stringoptions 16 | stringread_options 17 | stringwrite_options 18 | 19 | 20 | Instantiates a LevelDB object and opens the give database. 21 | 22 | 23 | 24 | 25 | 26 | 27 | &reftitle.parameters; 28 | 29 | 30 | name 31 | 32 | 33 | The name parameter corresponds to a file system directory. 34 | All of the contents of database are stored in this directory. 35 | 36 | 37 | 38 | 39 | options 40 | 41 | 42 | The open options. Default: 43 | 44 | true, // if the specified database didn't exist will create a new one 49 | 'error_if_exists' => false, // if the opened database exsits will throw exception 50 | 'paranoid_checks' => false, 51 | 'block_cache_size' => 8 * (2 << 20), 52 | 'write_buffer_size' => 4<<20, 53 | 'block_size' => 4096, 54 | 'max_open_files' => 1000, 55 | 'block_restart_interval' => 16, 56 | 'compression' => LEVELDB_SNAPPY_COMPRESSION, 57 | 'comparator' => NULL, // any callable parameter return 0, -1, 1 58 | ); 59 | 60 | 61 | ?> 62 | ]]> 63 | 64 | 65 | If you create a database with custom comparator, you can only open it again with the same comparator. 66 | 67 | 68 | 69 | 70 | read_options 71 | 72 | 73 | 74 | The read options. Default: 75 | 76 | false, 81 | 'fill_cache' => true, 82 | ); 83 | 84 | ?> 85 | ]]> 86 | 87 | 88 | read_options['verify_checksums'] may be set to true to force checksum verification of all data that is read from the file system on behalf of a particular read. By default, no such verification is done. 89 | When preforming a bulk read, the application mya be set the read_options['fill_cache'] to false to disable the caching so that the data processed by the bulk read does not end up displacing most of the cached contents. 90 | 91 | 92 | 93 | 94 | write_options 95 | 96 | 97 | The write options. Default: 98 | 99 | false 105 | ); 106 | 107 | ?> 108 | ]]> 109 | 110 | 111 | Only one element nameed sync in the write option array. By default, each write to leveldb is asynchronous. 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | &reftitle.returnvalues; 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | &reftitle.examples; 129 | 130 | <function>LevelDB::__construct</function> example 131 | 132 | 'cmp')); 135 | function cmp($a, $b) { 136 | return strcmp($a, $b); 137 | } 138 | ?> 139 | ]]> 140 | 141 | &example.outputs.similar; 142 | 143 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 173 | -------------------------------------------------------------------------------- /doc/leveldb/leveldb/delete.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | LevelDB::delete 7 | Remove a record 8 | 9 | 10 | 11 | &reftitle.description; 12 | 13 | public voidLevelDB::delete 14 | stringkey 15 | stringwrite_options 16 | 17 | 18 | Remove the database entry for key 19 | 20 | 21 | 22 | 23 | 24 | &reftitle.parameters; 25 | 26 | 27 | key 28 | 29 | 30 | A string 31 | 32 | 33 | 34 | 35 | 36 | write_options 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | &reftitle.returnvalues; 48 | 49 | Returns TRUE on success or FALSE on failure. 50 | 51 | 52 | 53 | 54 | &reftitle.examples; 55 | 56 | <function>LevelDB::delete</function> example 57 | 58 | 'cmp')); 62 | function cmp($a, $b) { 63 | return strcmp($a, $b); 64 | } 65 | $db->put("key", "test value"); 66 | var_dump($db->delete("key")); 67 | var_dump($db->get("key")); 68 | 69 | $db->close(); 70 | 71 | ?> 72 | ]]> 73 | 74 | &example.outputs.similar; 75 | 76 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 107 | -------------------------------------------------------------------------------- /doc/leveldb/leveldb/destroy.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | LevelDB::destroy 7 | The destroy purpose 8 | 9 | 10 | 11 | &reftitle.description; 12 | 13 | public static voidLevelDB::destroy 14 | stringname 15 | stringoptions 16 | 17 | 18 | 19 | 20 | 21 | &warn.undocumented.func; 22 | 23 | 24 | 25 | 26 | &reftitle.parameters; 27 | 28 | 29 | name 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | options 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | &reftitle.returnvalues; 49 | 50 | 51 | 52 | 53 | 54 | 55 | &reftitle.examples; 56 | 57 | <function>LevelDB::destroy</function> example 58 | 59 | 65 | ]]> 66 | 67 | &example.outputs.similar; 68 | 69 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 99 | -------------------------------------------------------------------------------- /doc/leveldb/leveldb/get.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | LevelDB::get 7 | The get purpose 8 | 9 | 10 | 11 | &reftitle.description; 12 | 13 | public voidLevelDB::get 14 | stringkey 15 | stringread_options 16 | 17 | 18 | This method is used to return a value. This method accepts a string key. 19 | 20 | 21 | 22 | 23 | 24 | 25 | &reftitle.parameters; 26 | 27 | 28 | key 29 | 30 | 31 | A string 32 | 33 | 34 | 35 | 36 | read_options 37 | 38 | 39 | A array contains two elements name verify_checksums and fill_cache. 40 | read_options['verify_checksums'] may be set to true to force checksum verification of all data that is read from the file system on behalf of a particular read. By default, no such verification is done. 41 | When preforming a bulk read, the application mya be set the read_options['fill_cache'] to false to disable the caching so that the data processed by the bulk read does not end up displacing most of the cached contents. 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | &reftitle.returnvalues; 51 | 52 | Returns a string. 53 | If the key is not found, it return false. 54 | 55 | 56 | 57 | 58 | 59 | &reftitle.examples; 60 | 61 | 62 | <function>LevelDB::get</function> example 63 | 64 | 'cmp')); 69 | function cmp($a, $b) { 70 | return strcmp($a, $b); 71 | } 72 | 73 | $db->put("Key", "Value"); 74 | $db->set("Key2", "Value2"); // set() is an alias of put() 75 | var_dump($db->get("Key")); 76 | var_dump($db->get("Key2")); 77 | 78 | 79 | ?> 80 | ]]> 81 | 82 | &example.outputs.similar; 83 | 84 | 88 | 89 | 90 | 91 | 92 | &reftitle.seealso; 93 | 94 | 95 | LevelDB::set 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 124 | -------------------------------------------------------------------------------- /doc/leveldb/leveldb/getapproximatesizes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | LevelDB::getApproximateSizes 7 | The getApproximateSizes purpose 8 | 9 | 10 | 11 | &reftitle.description; 12 | 13 | public voidLevelDB::getApproximateSizes 14 | stringstart 15 | stringlimit 16 | 17 | 18 | 19 | 20 | 21 | &warn.undocumented.func; 22 | 23 | 24 | 25 | 26 | &reftitle.parameters; 27 | 28 | 29 | start 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | limit 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | &reftitle.returnvalues; 49 | 50 | 51 | 52 | 53 | 54 | 55 | &reftitle.examples; 56 | 57 | <function>LevelDB::getApproximateSizes</function> example 58 | 59 | 65 | ]]> 66 | 67 | &example.outputs.similar; 68 | 69 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 99 | -------------------------------------------------------------------------------- /doc/leveldb/leveldb/getproperty.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | LevelDB::getProperty 7 | get the property of db 8 | 9 | 10 | 11 | &reftitle.description; 12 | 13 | public voidLevelDB::getProperty 14 | stringname 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | &reftitle.parameters; 24 | 25 | 26 | name 27 | 28 | 29 | The name parameter specifies the name of database property you require to get. It must begin to leveldbIt may be any of the following: 30 | 31 | 32 | A list of possible names for <function>getProperty</function> 33 | using <parameter>name</parameter> 34 | 35 | 36 | 37 | 38 | name 39 | Description 40 | 41 | 42 | 43 | 44 | leveldb.stats 45 | 46 | returns the status of the entire db 47 | 48 | 49 | 50 | leveldb.num-files-at-level 51 | 52 | return the number of files for each level. For example, you can use leveldb.num-files-at-level0 the number of files for zero level. 53 | 54 | 55 | 56 | leveldb.sstables 57 | 58 | return current status of sstables 59 | 60 | 61 | 62 | 63 |
64 |
65 |
66 |
67 |
68 |
69 | 70 | 71 | &reftitle.returnvalues; 72 | 73 | 74 | 75 | 76 | 77 | 78 | &reftitle.examples; 79 | 80 | <function>LevelDB::getProperty</function> example 81 | 82 | 'cmp')); 85 | 86 | function cmp($a, $b) { 87 | return strcmp($a, $b); 88 | } 89 | 90 | $db->put('key', 'value'); 91 | $db->put('key2', 'value2'); 92 | 93 | var_dump($db->getProperty('leveldb.stats')); 94 | var_dump($db->getProperty('leveldb.num-files-at-level0')); 95 | var_dump($db->getProperty('leveldb.sstables')); 96 | 97 | $db->close(); 98 | 99 | ?> 100 | ]]> 101 | 102 | &example.outputs.similar; 103 | 104 | 121 | 122 | 123 | 124 | 125 | 126 |
127 | 128 | 148 | -------------------------------------------------------------------------------- /doc/leveldb/leveldb/put.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | LevelDB::put 7 | The put purpose 8 | 9 | 10 | 11 | &reftitle.description; 12 | 13 | public voidLevelDB::put 14 | stringkey 15 | stringvalue 16 | stringwrite_options 17 | 18 | 19 | Puts a key-value pair into the database. If the key exists the value will be replaced with the new value. 20 | 21 | 22 | 23 | 24 | &reftitle.parameters; 25 | 26 | 27 | key 28 | 29 | 30 | A string key of key-value pair. The key is case-sensitive. 31 | 32 | 33 | 34 | 35 | value 36 | 37 | 38 | A string value of key-value pair 39 | 40 | 41 | 42 | 43 | write_options 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | &reftitle.returnvalues; 55 | 56 | 57 | 58 | 59 | 60 | 61 | &reftitle.examples; 62 | 63 | <function>LevelDB::put</function> example 64 | 65 | 'cmp')); 69 | function cmp($a, $b) { 70 | return strcmp($a, $b); 71 | } 72 | 73 | var_dump($db->put("KEY", "aa")); 74 | var_dump($db->put("key", "bb")); 75 | var_dump($db->get("KEY")); 76 | $db->close(); 77 | 78 | ?> 79 | ]]> 80 | 81 | &example.outputs.similar; 82 | 83 | 88 | 89 | 90 | 91 | 92 | 93 | &reftitle.seealso; 94 | 95 | 96 | LevelDB::set 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 125 | -------------------------------------------------------------------------------- /doc/leveldb/leveldb/repair.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | LevelDB::repair 7 | Repair this database 8 | 9 | 10 | 11 | &reftitle.description; 12 | 13 | public static voidLevelDB::repair 14 | stringname 15 | stringoptions 16 | 17 | 18 | If a database cannot be opened, you may attempt to call this method to resurrect as much of the contents of the database as possible. Some data may be lost, so be careful when calling this function on a database that contains important information. 19 | 20 | 21 | 22 | 23 | &reftitle.parameters; 24 | 25 | 26 | name 27 | 28 | 29 | Database name that corresponds to a file system directory. 30 | 31 | 32 | 33 | 34 | options 35 | 36 | 37 | The open options. 38 | see LevelDB::__construct 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | &reftitle.returnvalues; 47 | 48 | 49 | 50 | 51 | 52 | 53 | &reftitle.examples; 54 | 55 | <function>LevelDB::repair</function> example 56 | 57 | 'cmp'))); 64 | 65 | ?> 66 | ]]> 67 | 68 | &example.outputs.similar; 69 | 70 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 100 | -------------------------------------------------------------------------------- /doc/leveldb/leveldb/set.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | LevelDB::set 7 | Alias of LevelDB::put 8 | 9 | 10 | 11 | &reftitle.description; 12 | 13 | public voidLevelDB::set 14 | stringkey 15 | stringvalue 16 | stringwrite_options 17 | 18 | 19 | This function is an alias of: LevelDB::put 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 49 | -------------------------------------------------------------------------------- /doc/leveldb/leveldb/write.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | LevelDB::write 7 | 8 | Executes all of the operations added in the write batch. 9 | 10 | 11 | 12 | 13 | &reftitle.description; 14 | 15 | public voidLevelDB::write 16 | LevelDBWriteBatchbatch 17 | stringwrite_options 18 | 19 | 20 | Use the write method can batch execute the operations for the LevelDBWriteBatch object, for example, put, set, or delete, etc. It improves the throughput of the database, and it is atomic. 21 | 22 | 23 | 24 | 25 | &reftitle.parameters; 26 | 27 | 28 | batch 29 | 30 | 31 | A LevelDBWriteBatch object 32 | 33 | 34 | 35 | 36 | write_options 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | &reftitle.returnvalues; 48 | 49 | 50 | 51 | 52 | 53 | 54 | &reftitle.examples; 55 | 56 | <function>LevelDB::write</function> example 57 | 58 | 'cmp')); 64 | function cmp($a, $b) { 65 | return strcmp($a, $b); 66 | } 67 | 68 | $batch = new LevelDBWriteBatch(); 69 | $batch->put("key2", "batch value"); 70 | $batch->put("key3", "batch value"); 71 | $batch->set("key4", "a bounch of values"); // set() is an alias of put() 72 | $batch->delete("key3"); 73 | 74 | $db->write($batch); 75 | var_dump($db->get("key2")); 76 | var_dump($db->get("key3")); 77 | var_dump($db->get("key4")); 78 | 79 | $db->close(); 80 | 81 | ?> 82 | ]]> 83 | 84 | &example.outputs.similar; 85 | 86 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 118 | -------------------------------------------------------------------------------- /doc/leveldb/leveldbexception.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | The LevelDBException class 7 | LevelDBException 8 | 9 | 10 | 11 | 12 |
13 | &reftitle.intro; 14 | 15 | 16 | 17 |
18 | 19 | 20 |
21 | &reftitle.classsynopsis; 22 | 23 | 24 | 25 | LevelDBException 26 | 27 | 28 | 29 | 30 | LevelDBException 31 | 32 | 33 | 34 | extends 35 | Exception 36 | 37 | 38 | 39 | &Properties; 40 | 41 | 42 | &Methods; 43 | 44 | 45 | &InheritedMethods; 46 | 47 | 48 | 49 | 50 | 51 |
52 | 53 | 54 | 55 |
56 | &reftitle.properties; 57 | 58 | 59 | message 60 | 61 | 62 | 63 | 64 | 65 | code 66 | 67 | 68 | 69 | 70 | 71 | file 72 | 73 | 74 | 75 | 76 | 77 | line 78 | 79 | 80 | 81 | 82 | 83 |
84 | 85 | 86 | 87 |
88 | 89 | &reference.leveldb.entities.leveldbexception; 90 | 91 |
92 | 93 | 113 | -------------------------------------------------------------------------------- /doc/leveldb/leveldbiterator.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | The LevelDBIterator class 7 | LevelDBIterator 8 | 9 | 10 | 11 | 12 |
13 | &reftitle.intro; 14 | 15 | 16 | 17 |
18 | 19 | 20 |
21 | &reftitle.classsynopsis; 22 | 23 | 24 | 25 | LevelDBIterator 26 | 27 | 28 | 29 | 30 | LevelDBIterator 31 | 32 | 33 | 34 | 35 | &Methods; 36 | 37 | 38 | 39 | 40 |
41 | 42 |
43 | 44 | &reference.leveldb.entities.leveldbiterator; 45 | 46 |
47 | 48 | 68 | -------------------------------------------------------------------------------- /doc/leveldb/leveldbiterator/construct.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | LevelDBIterator::__construct 7 | The __construct purpose 8 | 9 | 10 | 11 | &reftitle.description; 12 | 13 | public LevelDBIterator::__construct 14 | stringdb 15 | stringread_options 16 | 17 | 18 | 19 | 20 | 21 | &warn.undocumented.func; 22 | 23 | 24 | 25 | 26 | &reftitle.parameters; 27 | 28 | 29 | db 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | read_options 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | &reftitle.returnvalues; 49 | 50 | 51 | 52 | 53 | 54 | 55 | &reftitle.examples; 56 | 57 | <function>LevelDBIterator::__construct</function> example 58 | 59 | 65 | ]]> 66 | 67 | &example.outputs.similar; 68 | 69 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 99 | -------------------------------------------------------------------------------- /doc/leveldb/leveldbiterator/current.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | LevelDBIterator::current 7 | The current purpose 8 | 9 | 10 | 11 | &reftitle.description; 12 | 13 | public voidLevelDBIterator::current 14 | 15 | 16 | 17 | 18 | 19 | 20 | &warn.undocumented.func; 21 | 22 | 23 | 24 | 25 | &reftitle.parameters; 26 | &no.function.parameters; 27 | 28 | 29 | 30 | &reftitle.returnvalues; 31 | 32 | 33 | 34 | 35 | 36 | 37 | &reftitle.examples; 38 | 39 | <function>LevelDBIterator::current</function> example 40 | 41 | 47 | ]]> 48 | 49 | &example.outputs.similar; 50 | 51 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 81 | -------------------------------------------------------------------------------- /doc/leveldb/leveldbiterator/destroy.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | LevelDBIterator::destroy 7 | The destroy purpose 8 | 9 | 10 | 11 | &reftitle.description; 12 | 13 | public voidLevelDBIterator::destroy 14 | 15 | 16 | 17 | 18 | 19 | 20 | &warn.undocumented.func; 21 | 22 | 23 | 24 | 25 | &reftitle.parameters; 26 | &no.function.parameters; 27 | 28 | 29 | 30 | &reftitle.returnvalues; 31 | 32 | 33 | 34 | 35 | 36 | 37 | &reftitle.examples; 38 | 39 | <function>LevelDBIterator::destroy</function> example 40 | 41 | 47 | ]]> 48 | 49 | &example.outputs.similar; 50 | 51 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 81 | -------------------------------------------------------------------------------- /doc/leveldb/leveldbiterator/geterror.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | LevelDBIterator::getError 7 | The getError purpose 8 | 9 | 10 | 11 | &reftitle.description; 12 | 13 | public voidLevelDBIterator::getError 14 | 15 | 16 | 17 | 18 | 19 | 20 | &warn.undocumented.func; 21 | 22 | 23 | 24 | 25 | &reftitle.parameters; 26 | &no.function.parameters; 27 | 28 | 29 | 30 | &reftitle.returnvalues; 31 | 32 | 33 | 34 | 35 | 36 | 37 | &reftitle.examples; 38 | 39 | <function>LevelDBIterator::getError</function> example 40 | 41 | 47 | ]]> 48 | 49 | &example.outputs.similar; 50 | 51 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 81 | -------------------------------------------------------------------------------- /doc/leveldb/leveldbiterator/key.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | LevelDBIterator::key 7 | The key purpose 8 | 9 | 10 | 11 | &reftitle.description; 12 | 13 | public voidLevelDBIterator::key 14 | 15 | 16 | 17 | 18 | 19 | 20 | &warn.undocumented.func; 21 | 22 | 23 | 24 | 25 | &reftitle.parameters; 26 | &no.function.parameters; 27 | 28 | 29 | 30 | &reftitle.returnvalues; 31 | 32 | 33 | 34 | 35 | 36 | 37 | &reftitle.examples; 38 | 39 | <function>LevelDBIterator::key</function> example 40 | 41 | 47 | ]]> 48 | 49 | &example.outputs.similar; 50 | 51 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 81 | -------------------------------------------------------------------------------- /doc/leveldb/leveldbiterator/last.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | LevelDBIterator::last 7 | The last purpose 8 | 9 | 10 | 11 | &reftitle.description; 12 | 13 | public voidLevelDBIterator::last 14 | 15 | 16 | 17 | 18 | 19 | 20 | &warn.undocumented.func; 21 | 22 | 23 | 24 | 25 | &reftitle.parameters; 26 | &no.function.parameters; 27 | 28 | 29 | 30 | &reftitle.returnvalues; 31 | 32 | 33 | 34 | 35 | 36 | 37 | &reftitle.examples; 38 | 39 | <function>LevelDBIterator::last</function> example 40 | 41 | 47 | ]]> 48 | 49 | &example.outputs.similar; 50 | 51 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 81 | -------------------------------------------------------------------------------- /doc/leveldb/leveldbiterator/next.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | LevelDBIterator::next 7 | The next purpose 8 | 9 | 10 | 11 | &reftitle.description; 12 | 13 | public voidLevelDBIterator::next 14 | 15 | 16 | 17 | 18 | 19 | 20 | &warn.undocumented.func; 21 | 22 | 23 | 24 | 25 | &reftitle.parameters; 26 | &no.function.parameters; 27 | 28 | 29 | 30 | &reftitle.returnvalues; 31 | 32 | 33 | 34 | 35 | 36 | 37 | &reftitle.examples; 38 | 39 | <function>LevelDBIterator::next</function> example 40 | 41 | 47 | ]]> 48 | 49 | &example.outputs.similar; 50 | 51 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 81 | -------------------------------------------------------------------------------- /doc/leveldb/leveldbiterator/prev.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | LevelDBIterator::prev 7 | The prev purpose 8 | 9 | 10 | 11 | &reftitle.description; 12 | 13 | public voidLevelDBIterator::prev 14 | 15 | 16 | 17 | 18 | 19 | 20 | &warn.undocumented.func; 21 | 22 | 23 | 24 | 25 | &reftitle.parameters; 26 | &no.function.parameters; 27 | 28 | 29 | 30 | &reftitle.returnvalues; 31 | 32 | 33 | 34 | 35 | 36 | 37 | &reftitle.examples; 38 | 39 | <function>LevelDBIterator::prev</function> example 40 | 41 | 47 | ]]> 48 | 49 | &example.outputs.similar; 50 | 51 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 81 | -------------------------------------------------------------------------------- /doc/leveldb/leveldbiterator/rewind.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | LevelDBIterator::rewind 7 | The rewind purpose 8 | 9 | 10 | 11 | &reftitle.description; 12 | 13 | public voidLevelDBIterator::rewind 14 | 15 | 16 | 17 | 18 | 19 | 20 | &warn.undocumented.func; 21 | 22 | 23 | 24 | 25 | &reftitle.parameters; 26 | &no.function.parameters; 27 | 28 | 29 | 30 | &reftitle.returnvalues; 31 | 32 | 33 | 34 | 35 | 36 | 37 | &reftitle.examples; 38 | 39 | <function>LevelDBIterator::rewind</function> example 40 | 41 | 47 | ]]> 48 | 49 | &example.outputs.similar; 50 | 51 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 81 | -------------------------------------------------------------------------------- /doc/leveldb/leveldbiterator/seek.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | LevelDBIterator::seek 7 | The seek purpose 8 | 9 | 10 | 11 | &reftitle.description; 12 | 13 | public voidLevelDBIterator::seek 14 | stringkey 15 | 16 | 17 | 18 | 19 | 20 | &warn.undocumented.func; 21 | 22 | 23 | 24 | 25 | &reftitle.parameters; 26 | 27 | 28 | key 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | &reftitle.returnvalues; 40 | 41 | 42 | 43 | 44 | 45 | 46 | &reftitle.examples; 47 | 48 | <function>LevelDBIterator::seek</function> example 49 | 50 | 56 | ]]> 57 | 58 | &example.outputs.similar; 59 | 60 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 90 | -------------------------------------------------------------------------------- /doc/leveldb/leveldbiterator/valid.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | LevelDBIterator::valid 7 | The valid purpose 8 | 9 | 10 | 11 | &reftitle.description; 12 | 13 | public voidLevelDBIterator::valid 14 | 15 | 16 | 17 | 18 | 19 | 20 | &warn.undocumented.func; 21 | 22 | 23 | 24 | 25 | &reftitle.parameters; 26 | &no.function.parameters; 27 | 28 | 29 | 30 | &reftitle.returnvalues; 31 | 32 | 33 | 34 | 35 | 36 | 37 | &reftitle.examples; 38 | 39 | <function>LevelDBIterator::valid</function> example 40 | 41 | 47 | ]]> 48 | 49 | &example.outputs.similar; 50 | 51 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 81 | -------------------------------------------------------------------------------- /doc/leveldb/leveldbwritebatch.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | The LevelDBWriteBatch class 7 | LevelDBWriteBatch 8 | 9 | 10 | 11 | 12 |
13 | &reftitle.intro; 14 | 15 | 16 | 17 |
18 | 19 | 20 |
21 | &reftitle.classsynopsis; 22 | 23 | 24 | 25 | LevelDBWriteBatch 26 | 27 | 28 | 29 | 30 | LevelDBWriteBatch 31 | 32 | 33 | 34 | 35 | &Methods; 36 | 37 | 38 | 39 | 40 |
41 | 42 |
43 | 44 | &reference.leveldb.entities.leveldbwritebatch; 45 | 46 |
47 | 48 | 68 | -------------------------------------------------------------------------------- /doc/leveldb/leveldbwritebatch/clear.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | LevelDBWriteBatch::clear 7 | The clear purpose 8 | 9 | 10 | 11 | &reftitle.description; 12 | 13 | public voidLevelDBWriteBatch::clear 14 | 15 | 16 | 17 | 18 | 19 | 20 | &warn.undocumented.func; 21 | 22 | 23 | 24 | 25 | &reftitle.parameters; 26 | &no.function.parameters; 27 | 28 | 29 | 30 | &reftitle.returnvalues; 31 | 32 | 33 | 34 | 35 | 36 | 37 | &reftitle.examples; 38 | 39 | <function>LevelDBWriteBatch::clear</function> example 40 | 41 | 47 | ]]> 48 | 49 | &example.outputs.similar; 50 | 51 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 81 | -------------------------------------------------------------------------------- /doc/leveldb/leveldbwritebatch/construct.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | LevelDBWriteBatch::__construct 7 | The __construct purpose 8 | 9 | 10 | 11 | &reftitle.description; 12 | 13 | public LevelDBWriteBatch::__construct 14 | stringname 15 | stringoptions 16 | stringread_options 17 | stringwrite_options 18 | 19 | 20 | 21 | 22 | 23 | &warn.undocumented.func; 24 | 25 | 26 | 27 | 28 | &reftitle.parameters; 29 | 30 | 31 | name 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | options 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | read_options 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | write_options 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | &reftitle.returnvalues; 67 | 68 | 69 | 70 | 71 | 72 | 73 | &reftitle.examples; 74 | 75 | <function>LevelDBWriteBatch::__construct</function> example 76 | 77 | 83 | ]]> 84 | 85 | &example.outputs.similar; 86 | 87 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 117 | -------------------------------------------------------------------------------- /doc/leveldb/leveldbwritebatch/delete.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | LevelDBWriteBatch::delete 7 | The delete purpose 8 | 9 | 10 | 11 | &reftitle.description; 12 | 13 | public voidLevelDBWriteBatch::delete 14 | stringkey 15 | stringwrite_options 16 | 17 | 18 | 19 | 20 | 21 | &warn.undocumented.func; 22 | 23 | 24 | 25 | 26 | &reftitle.parameters; 27 | 28 | 29 | key 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | write_options 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | &reftitle.returnvalues; 49 | 50 | 51 | 52 | 53 | 54 | 55 | &reftitle.examples; 56 | 57 | <function>LevelDBWriteBatch::delete</function> example 58 | 59 | 65 | ]]> 66 | 67 | &example.outputs.similar; 68 | 69 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 99 | -------------------------------------------------------------------------------- /doc/leveldb/leveldbwritebatch/put.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | LevelDBWriteBatch::put 7 | The put purpose 8 | 9 | 10 | 11 | &reftitle.description; 12 | 13 | public voidLevelDBWriteBatch::put 14 | stringkey 15 | stringvalue 16 | stringwrite_options 17 | 18 | 19 | 20 | 21 | 22 | &warn.undocumented.func; 23 | 24 | 25 | 26 | 27 | &reftitle.parameters; 28 | 29 | 30 | key 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | value 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | write_options 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | &reftitle.returnvalues; 58 | 59 | 60 | 61 | 62 | 63 | 64 | &reftitle.examples; 65 | 66 | <function>LevelDBWriteBatch::put</function> example 67 | 68 | 74 | ]]> 75 | 76 | &example.outputs.similar; 77 | 78 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 108 | -------------------------------------------------------------------------------- /doc/leveldb/leveldbwritebatch/set.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | LevelDBWriteBatch::set 7 | The set purpose 8 | 9 | 10 | 11 | &reftitle.description; 12 | 13 | public voidLevelDBWriteBatch::set 14 | stringkey 15 | stringvalue 16 | stringwrite_options 17 | 18 | 19 | 20 | 21 | 22 | &warn.undocumented.func; 23 | 24 | 25 | 26 | 27 | &reftitle.parameters; 28 | 29 | 30 | key 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | value 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | write_options 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | &reftitle.returnvalues; 58 | 59 | 60 | 61 | 62 | 63 | 64 | &reftitle.examples; 65 | 66 | <function>LevelDBWriteBatch::set</function> example 67 | 68 | 74 | ]]> 75 | 76 | &example.outputs.similar; 77 | 78 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 108 | -------------------------------------------------------------------------------- /doc/leveldb/reference.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Leveldb &Functions; 6 | 7 | &reference.leveldb.entities.functions; 8 | 9 | 10 | 11 | 31 | -------------------------------------------------------------------------------- /doc/leveldb/setup.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | &reftitle.setup; 6 | 7 |
8 | &reftitle.required; 9 | 10 | 11 | 12 |
13 | 14 |
15 | &reftitle.install; 16 | &no.install; 17 |
18 | 19 |
20 | &reftitle.runtime; 21 | &no.config; 22 |
23 | 24 |
25 | &reftitle.resources; 26 | 27 | 28 | 29 |
30 | 31 |
32 | 33 | 53 | -------------------------------------------------------------------------------- /doc/leveldb/versions.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 69 | -------------------------------------------------------------------------------- /leveldb.c: -------------------------------------------------------------------------------- 1 | /* 2 | +----------------------------------------------------------------------+ 3 | | PHP Version 5 | 4 | +----------------------------------------------------------------------+ 5 | | Copyright (c) 1997-2016 The PHP Group | 6 | +----------------------------------------------------------------------+ 7 | | This source file is subject to version 3.01 of the PHP license, | 8 | | that is bundled with this package in the file LICENSE, and is | 9 | | available through the world-wide-web at the following url: | 10 | | http://www.php.net/license/3_01.txt | 11 | | If you did not receive a copy of the PHP license and are unable to | 12 | | obtain it through the world-wide-web, please send a note to | 13 | | license@php.net so we can mail you a copy immediately. | 14 | +----------------------------------------------------------------------+ 15 | | Author: Reeze Xia | 16 | +----------------------------------------------------------------------+ 17 | */ 18 | 19 | /* $Id$ */ 20 | 21 | #ifdef HAVE_CONFIG_H 22 | #include "config.h" 23 | #endif 24 | 25 | #include "php.h" 26 | #include "ext/standard/info.h" 27 | #include "Zend/zend_exceptions.h" 28 | #include "Zend/zend_interfaces.h" 29 | #include "php_leveldb.h" 30 | 31 | #include 32 | 33 | #define LEVELDB_CHECK_OPEN_BASEDIR(file) \ 34 | if (php_check_open_basedir((file))){ \ 35 | RETURN_FALSE; \ 36 | } 37 | 38 | #define PHP_LEVELDB_ERROR_DB_CLOSED 1 39 | #define PHP_LEVELDB_ERROR_ITERATOR_CLOSED 2 40 | 41 | #define LEVELDB_CHECK_DB_NOT_CLOSED(db_object) \ 42 | if ((db_object)->db == NULL) { \ 43 | zend_throw_exception(php_leveldb_ce_LevelDBException, "Can not operate on closed db", PHP_LEVELDB_ERROR_DB_CLOSED); \ 44 | return; \ 45 | } 46 | 47 | /* PHP-LevelDB MAGIC identifier don't change this */ 48 | #define PHP_LEVELDB_CUSTOM_COMPARATOR_NAME "php_leveldb.custom_comparator" 49 | 50 | #define php_leveldb_obj_new(class_type, ce) \ 51 | class_type *intern; \ 52 | \ 53 | intern = (class_type *)ecalloc(1, sizeof(class_type) + zend_object_properties_size(ce)); \ 54 | \ 55 | zend_object_std_init(&intern->std, ce); \ 56 | object_properties_init(&intern->std, ce); \ 57 | \ 58 | intern->std.handlers = & class_type##_handlers; \ 59 | \ 60 | return &intern->std; 61 | 62 | #define LEVELDB_CHECK_ERROR(err) \ 63 | if ((err) != NULL) { \ 64 | zend_throw_exception(php_leveldb_ce_LevelDBException, err, 0); \ 65 | leveldb_free(err); \ 66 | return; \ 67 | } 68 | 69 | /* {{{ leveldb_functions[] 70 | */ 71 | const zend_function_entry leveldb_functions[] = { 72 | PHP_FE_END /* Must be the last line in leveldb_functions[] */ 73 | }; 74 | /* }}} */ 75 | 76 | /* {{{ leveldb_module_entry 77 | */ 78 | zend_module_entry leveldb_module_entry = { 79 | STANDARD_MODULE_HEADER, 80 | "leveldb", 81 | leveldb_functions, 82 | PHP_MINIT(leveldb), 83 | PHP_MSHUTDOWN(leveldb), 84 | NULL, 85 | NULL, 86 | PHP_MINFO(leveldb), 87 | PHP_LEVELDB_VERSION, 88 | STANDARD_MODULE_PROPERTIES 89 | }; 90 | /* }}} */ 91 | 92 | #ifdef COMPILE_DL_LEVELDB 93 | ZEND_GET_MODULE(leveldb) 94 | #endif 95 | 96 | /* Handlers */ 97 | static zend_object_handlers leveldb_object_handlers; 98 | static zend_object_handlers leveldb_snapshot_object_handlers; 99 | static zend_object_handlers leveldb_write_batch_object_handlers; 100 | static zend_object_handlers leveldb_iterator_object_handlers; 101 | 102 | /* Class entries */ 103 | zend_class_entry *php_leveldb_ce_LevelDBException; 104 | zend_class_entry *php_leveldb_class_entry; 105 | zend_class_entry *php_leveldb_write_batch_class_entry; 106 | zend_class_entry *php_leveldb_iterator_class_entry; 107 | zend_class_entry *php_leveldb_snapshot_class_entry; 108 | 109 | /* Objects */ 110 | typedef struct { 111 | leveldb_t *db; 112 | /* default read options */ 113 | unsigned char verify_check_sum; 114 | unsigned char fill_cache; 115 | /* default write options */ 116 | unsigned char sync; 117 | 118 | /* custom comparator */ 119 | leveldb_comparator_t *comparator; 120 | zend_string *callable_name; 121 | zend_object std; 122 | } leveldb_object; 123 | 124 | typedef struct { 125 | leveldb_writebatch_t *batch; 126 | zend_object std; 127 | } leveldb_write_batch_object; 128 | 129 | typedef struct { 130 | leveldb_iterator_t *iterator; 131 | leveldb_object *db; 132 | zval zdb; 133 | zend_object std; 134 | } leveldb_iterator_object; 135 | 136 | /* define an overloaded iterator structure */ 137 | typedef struct { 138 | zend_object_iterator intern; 139 | leveldb_iterator_object *iterator_obj; 140 | zval *current; 141 | } leveldb_iterator_iterator; 142 | 143 | 144 | typedef struct { 145 | leveldb_object *db; 146 | zval zdb; 147 | leveldb_snapshot_t *snapshot; 148 | zend_object std; 149 | } leveldb_snapshot_object; 150 | 151 | #define LEVELDB_INTERNAL_OBJ_FROM_ZOBJ(class_name, obj) ((class_name *)((char *)(obj) - XtOffsetOf(class_name, std))) 152 | #define LEVELDB_INTERNAL_OBJ_FROM_ZV(obj_name, zv) LEVELDB_INTERNAL_OBJ_FROM_ZOBJ(obj_name, Z_OBJ_P(zv)) 153 | 154 | #define LEVELDB_OBJ_FROM_ZV(zv) LEVELDB_INTERNAL_OBJ_FROM_ZV(leveldb_object, zv) 155 | #define LEVELDB_SNAPSHOT_OBJ_FROM_ZV(zv) LEVELDB_INTERNAL_OBJ_FROM_ZV(leveldb_snapshot_object, zv) 156 | #define LEVELDB_WRITE_BATCH_OBJ_FROM_ZV(zv) LEVELDB_INTERNAL_OBJ_FROM_ZV(leveldb_write_batch_object, zv) 157 | #define LEVELDB_ITERATOR_OBJ_FROM_ZV(zv) LEVELDB_INTERNAL_OBJ_FROM_ZV(leveldb_iterator_object, zv) 158 | 159 | #define LEVELDB_OBJ_FROM_ZOBJ(obj) LEVELDB_INTERNAL_OBJ_FROM_ZOBJ(leveldb_object, obj) 160 | #define LEVELDB_SNAPSHOT_OBJ_FROM_ZOBJ(obj) LEVELDB_INTERNAL_OBJ_FROM_ZOBJ(leveldb_snapshot_object, obj) 161 | #define LEVELDB_WRITE_BATCH_OBJ_FROM_ZOBJ(obj) LEVELDB_INTERNAL_OBJ_FROM_ZOBJ(leveldb_write_batch_object, obj) 162 | #define LEVELDB_ITERATOR_OBJ_FROM_ZOBJ(obj) LEVELDB_INTERNAL_OBJ_FROM_ZOBJ(leveldb_iterator_object, obj) 163 | 164 | void php_leveldb_object_free(zend_object *std) 165 | { 166 | leveldb_object *obj = LEVELDB_OBJ_FROM_ZOBJ(std); 167 | 168 | if (obj->db) { 169 | leveldb_close(obj->db); 170 | } 171 | 172 | if (obj->comparator) { 173 | leveldb_comparator_destroy(obj->comparator); 174 | zend_string_release(obj->callable_name); 175 | } 176 | 177 | zend_object_std_dtor(std); 178 | } 179 | 180 | static zend_object* php_leveldb_object_new(zend_class_entry *class_type) 181 | { 182 | php_leveldb_obj_new(leveldb_object, class_type); 183 | } 184 | 185 | /* Write batch object operate */ 186 | void php_leveldb_write_batch_object_free(zend_object *std) 187 | { 188 | leveldb_write_batch_object *obj = LEVELDB_WRITE_BATCH_OBJ_FROM_ZOBJ(std); 189 | 190 | if (obj->batch) { 191 | leveldb_writebatch_destroy(obj->batch); 192 | } 193 | 194 | zend_object_std_dtor(std); 195 | } 196 | 197 | static zend_object* php_leveldb_write_batch_object_new(zend_class_entry *class_type) 198 | { 199 | php_leveldb_obj_new(leveldb_write_batch_object, class_type); 200 | } 201 | 202 | 203 | 204 | /* Iterator object operate */ 205 | void php_leveldb_iterator_object_free(zend_object *std) 206 | { 207 | leveldb_iterator_object *obj = LEVELDB_ITERATOR_OBJ_FROM_ZOBJ(std); 208 | 209 | if (obj->db && obj->db->db && obj->iterator) { 210 | leveldb_iter_destroy(obj->iterator); 211 | /* decr. obj counter */ 212 | zval_ptr_dtor(&obj->zdb); 213 | } 214 | 215 | zend_object_std_dtor(std); 216 | } 217 | 218 | static zend_object* php_leveldb_iterator_object_new(zend_class_entry *class_type) 219 | { 220 | php_leveldb_obj_new(leveldb_iterator_object, class_type); 221 | } 222 | 223 | /* Snapshot object operate */ 224 | void php_leveldb_snapshot_object_free(zend_object *std) 225 | { 226 | leveldb_t *db; 227 | leveldb_snapshot_object *obj = LEVELDB_SNAPSHOT_OBJ_FROM_ZOBJ(std); 228 | 229 | if (obj->snapshot && obj->db) { 230 | if((db = obj->db->db) != NULL) { 231 | leveldb_release_snapshot(db, obj->snapshot); 232 | } 233 | /* decr. obj counter */ 234 | zval_ptr_dtor(&obj->zdb); 235 | } 236 | 237 | zend_object_std_dtor(std); 238 | } 239 | 240 | static zend_object* php_leveldb_snapshot_object_new(zend_class_entry *class_type) 241 | { 242 | php_leveldb_obj_new(leveldb_snapshot_object, class_type); 243 | } 244 | 245 | /* arg info */ 246 | ZEND_BEGIN_ARG_INFO_EX(arginfo_leveldb_void, 0, 0, 0) 247 | ZEND_END_ARG_INFO() 248 | 249 | ZEND_BEGIN_ARG_INFO_EX(arginfo_leveldb_construct, 0, 0, 1) 250 | ZEND_ARG_TYPE_INFO(0, name, IS_STRING, 0) 251 | ZEND_ARG_ARRAY_INFO(0, options, 0) 252 | ZEND_ARG_ARRAY_INFO(0, read_options, 0) 253 | ZEND_ARG_ARRAY_INFO(0, write_options, 0) 254 | ZEND_END_ARG_INFO() 255 | 256 | ZEND_BEGIN_ARG_INFO_EX(arginfo_leveldb_get, 0, 0, 1) 257 | ZEND_ARG_TYPE_INFO(0, key, IS_STRING, 0) 258 | ZEND_ARG_ARRAY_INFO(0, read_options, 0) 259 | ZEND_END_ARG_INFO() 260 | 261 | ZEND_BEGIN_ARG_INFO_EX(arginfo_leveldb_set, 0, 0, 2) 262 | ZEND_ARG_TYPE_INFO(0, key, IS_STRING, 0) 263 | ZEND_ARG_TYPE_INFO(0, value, IS_STRING, 0) 264 | ZEND_ARG_ARRAY_INFO(0, write_options, 0) 265 | ZEND_END_ARG_INFO() 266 | 267 | ZEND_BEGIN_ARG_INFO_EX(arginfo_leveldb_delete, 0, 0, 1) 268 | ZEND_ARG_TYPE_INFO(0, key, IS_STRING, 0) 269 | ZEND_ARG_ARRAY_INFO(0, write_options, 0) 270 | ZEND_END_ARG_INFO() 271 | 272 | ZEND_BEGIN_ARG_INFO_EX(arginfo_leveldb_write, 0, 0, 1) 273 | ZEND_ARG_OBJ_INFO(0, batch, LevelDBWriteBatch, 0) 274 | ZEND_ARG_ARRAY_INFO(0, write_options, 0) 275 | ZEND_END_ARG_INFO() 276 | 277 | ZEND_BEGIN_ARG_INFO_EX(arginfo_leveldb_getProperty, 0, 0, 1) 278 | ZEND_ARG_TYPE_INFO(0, name, IS_STRING, 0) 279 | ZEND_END_ARG_INFO() 280 | 281 | ZEND_BEGIN_ARG_INFO_EX(arginfo_leveldb_getApproximateSizes, 0, 0, 2) 282 | ZEND_ARG_ARRAY_INFO(0, start, 0) 283 | ZEND_ARG_ARRAY_INFO(0, limit, 0) 284 | ZEND_END_ARG_INFO() 285 | 286 | ZEND_BEGIN_ARG_INFO_EX(arginfo_leveldb_compactRange, 0, 0, 2) 287 | ZEND_ARG_TYPE_INFO(0, start, IS_STRING, 0) 288 | ZEND_ARG_TYPE_INFO(0, limit, IS_STRING, 0) 289 | ZEND_END_ARG_INFO() 290 | 291 | ZEND_BEGIN_ARG_INFO_EX(arginfo_leveldb_get_iterator, 0, 0, 0) 292 | ZEND_ARG_ARRAY_INFO(0, options, 0) 293 | ZEND_END_ARG_INFO() 294 | 295 | ZEND_BEGIN_ARG_INFO_EX(arginfo_leveldb_destroy, 0, 0, 1) 296 | ZEND_ARG_TYPE_INFO(0, name, IS_STRING, 0) 297 | ZEND_ARG_ARRAY_INFO(0, options, 0) 298 | ZEND_END_ARG_INFO() 299 | 300 | ZEND_BEGIN_ARG_INFO_EX(arginfo_leveldb_repair, 0, 0, 1) 301 | ZEND_ARG_TYPE_INFO(0, name, IS_STRING, 0) 302 | ZEND_ARG_ARRAY_INFO(0, options, 0) 303 | ZEND_END_ARG_INFO() 304 | 305 | ZEND_BEGIN_ARG_INFO_EX(arginfo_leveldb_iterator_construct, 0, 0, 1) 306 | ZEND_ARG_OBJ_INFO(0, db, LevelDB, 0) 307 | ZEND_ARG_ARRAY_INFO(0, read_options, 0) 308 | ZEND_END_ARG_INFO() 309 | 310 | ZEND_BEGIN_ARG_INFO_EX(arginfo_leveldb_iterator_seek, 0, 0, 1) 311 | ZEND_ARG_TYPE_INFO(0, key, IS_STRING, 0) 312 | ZEND_END_ARG_INFO() 313 | 314 | ZEND_BEGIN_ARG_INFO_EX(arginfo_leveldb_snapshot_construct, 0, 0, 1) 315 | ZEND_ARG_OBJ_INFO(0, db, LevelDB, 0) 316 | ZEND_END_ARG_INFO() 317 | 318 | /* Methods */ 319 | /* {{{ php_leveldb_class_methods */ 320 | static zend_function_entry php_leveldb_class_methods[] = { 321 | PHP_ME(LevelDB, __construct, arginfo_leveldb_construct, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR) 322 | PHP_ME(LevelDB, get, arginfo_leveldb_get, ZEND_ACC_PUBLIC) 323 | PHP_ME(LevelDB, set, arginfo_leveldb_set, ZEND_ACC_PUBLIC) 324 | /* make put an alias of set, since leveldb use put */ 325 | PHP_MALIAS(LevelDB, put, set, arginfo_leveldb_set, ZEND_ACC_PUBLIC) 326 | PHP_ME(LevelDB, delete, arginfo_leveldb_delete, ZEND_ACC_PUBLIC) 327 | PHP_ME(LevelDB, write, arginfo_leveldb_write, ZEND_ACC_PUBLIC) 328 | PHP_ME(LevelDB, getProperty, arginfo_leveldb_getProperty, ZEND_ACC_PUBLIC) 329 | PHP_ME(LevelDB, getApproximateSizes, arginfo_leveldb_getApproximateSizes, ZEND_ACC_PUBLIC) 330 | PHP_ME(LevelDB, compactRange, arginfo_leveldb_compactRange, ZEND_ACC_PUBLIC) 331 | PHP_ME(LevelDB, close, arginfo_leveldb_void, ZEND_ACC_PUBLIC | ZEND_ACC_DEPRECATED) 332 | PHP_ME(LevelDB, getIterator, arginfo_leveldb_get_iterator, ZEND_ACC_PUBLIC) 333 | PHP_ME(LevelDB, getSnapshot, arginfo_leveldb_void, ZEND_ACC_PUBLIC) 334 | PHP_ME(LevelDB, destroy, arginfo_leveldb_destroy, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) 335 | PHP_ME(LevelDB, repair, arginfo_leveldb_repair, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) 336 | PHP_FE_END 337 | }; 338 | /* }}} */ 339 | 340 | /* {{{ php_leveldb_write_batch_class_methods */ 341 | static zend_function_entry php_leveldb_write_batch_class_methods[] = { 342 | PHP_ME(LevelDBWriteBatch, __construct, arginfo_leveldb_void, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR) 343 | PHP_ME(LevelDBWriteBatch, set, arginfo_leveldb_set, ZEND_ACC_PUBLIC) 344 | /* make put an alias of set, since leveldb use put */ 345 | PHP_MALIAS(LevelDBWriteBatch, put, set, arginfo_leveldb_set, ZEND_ACC_PUBLIC) 346 | PHP_ME(LevelDBWriteBatch, delete, arginfo_leveldb_delete, ZEND_ACC_PUBLIC) 347 | PHP_ME(LevelDBWriteBatch, clear, arginfo_leveldb_void, ZEND_ACC_PUBLIC) 348 | PHP_FE_END 349 | }; 350 | /* }}} */ 351 | 352 | /* {{{ php_leveldb_iterator_class_methods */ 353 | static zend_function_entry php_leveldb_iterator_class_methods[] = { 354 | PHP_ME(LevelDBIterator, __construct, arginfo_leveldb_iterator_construct, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR) 355 | PHP_ME(LevelDBIterator, valid, arginfo_leveldb_void, ZEND_ACC_PUBLIC) 356 | PHP_ME(LevelDBIterator, rewind, arginfo_leveldb_void, ZEND_ACC_PUBLIC) 357 | PHP_ME(LevelDBIterator, last, arginfo_leveldb_void, ZEND_ACC_PUBLIC) 358 | PHP_ME(LevelDBIterator, seek, arginfo_leveldb_iterator_seek, ZEND_ACC_PUBLIC) 359 | PHP_ME(LevelDBIterator, next, arginfo_leveldb_void, ZEND_ACC_PUBLIC) 360 | PHP_ME(LevelDBIterator, prev, arginfo_leveldb_void, ZEND_ACC_PUBLIC) 361 | PHP_ME(LevelDBIterator, key, arginfo_leveldb_void, ZEND_ACC_PUBLIC) 362 | PHP_ME(LevelDBIterator, current, arginfo_leveldb_void, ZEND_ACC_PUBLIC) 363 | PHP_ME(LevelDBIterator, getError, arginfo_leveldb_void, ZEND_ACC_PUBLIC) 364 | PHP_ME(LevelDBIterator, destroy, arginfo_leveldb_void, ZEND_ACC_PUBLIC) 365 | PHP_FE_END 366 | }; 367 | /* }}} */ 368 | 369 | /* {{{ php_leveldb_iterator_class_methods */ 370 | static zend_function_entry php_leveldb_snapshot_class_methods[] = { 371 | PHP_ME(LevelDBSnapshot, __construct, arginfo_leveldb_snapshot_construct, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR) 372 | PHP_ME(LevelDBSnapshot, release, arginfo_leveldb_void, ZEND_ACC_PUBLIC) 373 | PHP_FE_END 374 | }; 375 | /* }}} */ 376 | 377 | static void leveldb_custom_comparator_destructor(void *stat) 378 | { 379 | zval *callable = (zval *)stat; 380 | zval_ptr_dtor(callable); 381 | efree(callable); 382 | } 383 | 384 | static int leveldb_custom_comparator_compare(void *stat, const char *a, size_t alen, const char *b, size_t blen) 385 | { 386 | zval *callable = (zval *)stat; 387 | zval params[2], result; 388 | int ret; 389 | 390 | ZVAL_STRINGL(¶ms[0], (char *)a, alen); 391 | ZVAL_STRINGL(¶ms[1], (char *)b, blen); 392 | ZVAL_NULL(&result); 393 | 394 | assert(!ZVAL_IS_NULL(callable)); 395 | 396 | if (call_user_function(EG(function_table), NULL, callable, &result, 2, params) == SUCCESS && !Z_ISUNDEF(result)) { 397 | convert_to_long(&result); 398 | ret = Z_LVAL(result); 399 | }else{ 400 | ret = 0; 401 | } 402 | 403 | zval_ptr_dtor(¶ms[0]); 404 | zval_ptr_dtor(¶ms[1]); 405 | zval_ptr_dtor(&result); 406 | 407 | return ret; 408 | } 409 | 410 | static const char* leveldb_custom_comparator_name(void *stat) 411 | { 412 | return PHP_LEVELDB_CUSTOM_COMPARATOR_NAME; 413 | } 414 | 415 | static inline leveldb_options_t* php_leveldb_get_open_options(zval *options_zv, leveldb_comparator_t **out_comparator, zend_string **callable_name) 416 | { 417 | zval *value; 418 | HashTable *ht; 419 | leveldb_options_t *options = leveldb_options_create(); 420 | 421 | /* default true */ 422 | leveldb_options_set_create_if_missing(options, 1); 423 | 424 | if (options_zv == NULL) { 425 | return options; 426 | } 427 | 428 | ht = Z_ARRVAL_P(options_zv); 429 | 430 | if ((value = zend_hash_str_find(ht, ZEND_STRL("create_if_missing"))) != NULL) { 431 | leveldb_options_set_create_if_missing(options, zend_is_true(value)); 432 | } 433 | 434 | if ((value = zend_hash_str_find(ht, ZEND_STRL("error_if_exists"))) != NULL) { 435 | leveldb_options_set_error_if_exists(options, zend_is_true(value)); 436 | } 437 | 438 | if ((value = zend_hash_str_find(ht, ZEND_STRL("paranoid_checks"))) != NULL) { 439 | leveldb_options_set_paranoid_checks(options, zend_is_true(value)); 440 | } 441 | 442 | if ((value = zend_hash_str_find(ht, ZEND_STRL("write_buffer_size"))) != NULL) { 443 | convert_to_long(value); 444 | leveldb_options_set_write_buffer_size(options, Z_LVAL_P(value)); 445 | } 446 | 447 | if ((value = zend_hash_str_find(ht, ZEND_STRL("max_open_files"))) != NULL) { 448 | convert_to_long(value); 449 | leveldb_options_set_max_open_files(options, Z_LVAL_P(value)); 450 | } 451 | 452 | if ((value = zend_hash_str_find(ht, ZEND_STRL("block_size"))) != NULL) { 453 | convert_to_long(value); 454 | leveldb_options_set_block_size(options, Z_LVAL_P(value)); 455 | } 456 | 457 | if ((value = zend_hash_str_find(ht, ZEND_STRL("block_cache_size"))) != NULL) { 458 | convert_to_long(value); 459 | leveldb_options_set_cache(options, leveldb_cache_create_lru(Z_LVAL_P(value))); 460 | } 461 | 462 | if ((value = zend_hash_str_find(ht, ZEND_STRL("block_restart_interval"))) != NULL) { 463 | convert_to_long(value); 464 | leveldb_options_set_block_restart_interval(options, Z_LVAL_P(value)); 465 | } 466 | 467 | if ((value = zend_hash_str_find(ht, ZEND_STRL("compression"))) != NULL) { 468 | convert_to_long(value); 469 | 470 | switch (Z_LVAL_P(value)) 471 | { 472 | case leveldb_no_compression: 473 | case leveldb_snappy_compression: 474 | #ifdef MOJANG_LEVELDB 475 | case leveldb_zlib_compression: 476 | case leveldb_zlib_raw_compression: 477 | #endif 478 | leveldb_options_set_compression(options, Z_LVAL_P(value)); 479 | break; 480 | default: 481 | php_error_docref(NULL, E_WARNING, "Unsupported compression type"); 482 | break; 483 | } 484 | } 485 | 486 | if ((value = zend_hash_str_find(ht, ZEND_STRL("comparator"))) != NULL 487 | && !ZVAL_IS_NULL(value)) { 488 | leveldb_comparator_t *comparator; 489 | if (!zend_is_callable(value, 0, callable_name)) { 490 | zend_throw_exception_ex(php_leveldb_ce_LevelDBException, 0, 491 | "Invalid open option: comparator, %s() is not callable", ZSTR_VAL(*callable_name)); 492 | 493 | zend_string_release(*callable_name); 494 | *callable_name = NULL; 495 | 496 | leveldb_options_destroy(options); 497 | 498 | return NULL; 499 | } 500 | 501 | zval *z2 = (zval *)emalloc(sizeof(zval)); 502 | ZVAL_COPY(z2, value); 503 | 504 | comparator = leveldb_comparator_create((void *)(z2), 505 | leveldb_custom_comparator_destructor, leveldb_custom_comparator_compare, 506 | leveldb_custom_comparator_name); 507 | 508 | if (comparator) { 509 | *out_comparator = comparator; 510 | } 511 | 512 | leveldb_options_set_comparator(options, comparator); 513 | } 514 | 515 | return options; 516 | } 517 | 518 | static inline leveldb_readoptions_t *php_leveldb_get_readoptions(leveldb_object *intern, zval *options_zv) 519 | { 520 | zval *value; 521 | HashTable *ht; 522 | leveldb_readoptions_t *readoptions = leveldb_readoptions_create(); 523 | 524 | if (options_zv == NULL) { 525 | return readoptions; 526 | } 527 | 528 | ht = Z_ARRVAL_P(options_zv); 529 | 530 | if ((value = zend_hash_str_find(ht, ZEND_STRL("verify_check_sum"))) != NULL) { 531 | leveldb_readoptions_set_verify_checksums(readoptions, zend_is_true(value)); 532 | } else { 533 | leveldb_readoptions_set_verify_checksums(readoptions, intern->verify_check_sum); 534 | } 535 | 536 | if ((value = zend_hash_str_find(ht, ZEND_STRL("fill_cache"))) != NULL) { 537 | leveldb_readoptions_set_fill_cache(readoptions, zend_is_true(value)); 538 | } else { 539 | leveldb_readoptions_set_fill_cache(readoptions, intern->fill_cache); 540 | } 541 | 542 | if ((value = zend_hash_str_find(ht, ZEND_STRL("snapshot"))) != NULL 543 | && !ZVAL_IS_NULL(value)) { 544 | if (Z_TYPE_P(value) == IS_OBJECT && Z_OBJCE_P(value) == php_leveldb_snapshot_class_entry) { 545 | leveldb_snapshot_object *obj = LEVELDB_SNAPSHOT_OBJ_FROM_ZV(value); 546 | if (obj->snapshot == NULL) { 547 | zend_throw_exception_ex(php_leveldb_ce_LevelDBException, 0, 548 | "Invalid snapshot parameter, it has been released"); 549 | 550 | leveldb_readoptions_destroy(readoptions); 551 | return NULL; 552 | } 553 | 554 | leveldb_readoptions_set_snapshot(readoptions, obj->snapshot); 555 | } else { 556 | zend_throw_exception_ex(php_leveldb_ce_LevelDBException, 0, 557 | "Invalid snapshot parameter, it must be an instance of LevelDBSnapshot"); 558 | 559 | leveldb_readoptions_destroy(readoptions); 560 | return NULL; 561 | } 562 | } 563 | 564 | return readoptions; 565 | } 566 | 567 | static inline void php_leveldb_set_readoptions(leveldb_object *intern, zval *options_zv) 568 | { 569 | zval *value; 570 | HashTable *ht; 571 | 572 | if (options_zv == NULL) { 573 | return; 574 | } 575 | 576 | ht = Z_ARRVAL_P(options_zv); 577 | 578 | if ((value = zend_hash_str_find(ht, ZEND_STRL("verify_check_sum"))) != NULL) { 579 | intern->verify_check_sum = zend_is_true(value); 580 | } 581 | 582 | if ((value = zend_hash_str_find(ht, ZEND_STRL("fill_cache"))) != NULL) { 583 | intern->fill_cache = zend_is_true(value); 584 | } 585 | } 586 | 587 | static inline leveldb_writeoptions_t *php_leveldb_get_writeoptions(leveldb_object *intern, zval *options_zv) 588 | { 589 | zval *value; 590 | HashTable *ht; 591 | leveldb_writeoptions_t *writeoptions = leveldb_writeoptions_create(); 592 | 593 | if (options_zv == NULL) { 594 | return writeoptions; 595 | } 596 | 597 | ht = Z_ARRVAL_P(options_zv); 598 | 599 | if ((value = zend_hash_str_find(ht, ZEND_STRL("sync"))) != NULL) { 600 | leveldb_writeoptions_set_sync(writeoptions, zend_is_true(value)); 601 | } else { 602 | leveldb_writeoptions_set_sync(writeoptions, intern->sync); 603 | } 604 | 605 | return writeoptions; 606 | } 607 | 608 | static inline void php_leveldb_set_writeoptions(leveldb_object *intern, zval *options_zv) 609 | { 610 | zval *value; 611 | 612 | if (options_zv == NULL) { 613 | return; 614 | } 615 | 616 | if ((value = zend_hash_str_find(Z_ARRVAL_P(options_zv), ZEND_STRL("sync"))) != NULL) { 617 | intern->sync = zend_is_true(value); 618 | } 619 | } 620 | 621 | /* {{{ proto LevelDB LevelDB::__construct(string $name [, array $options [, array $readoptions [, array $writeoptions]]]) 622 | Instantiates a LevelDB object and opens the give database */ 623 | PHP_METHOD(LevelDB, __construct) 624 | { 625 | char *name; 626 | size_t name_len; 627 | zval *options_zv = NULL, *readoptions_zv = NULL, *writeoptions_zv = NULL; 628 | 629 | char *err = NULL; 630 | leveldb_t *db = NULL; 631 | leveldb_options_t *openoptions; 632 | leveldb_object *intern; 633 | 634 | if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|a!a!a!", 635 | &name, &name_len, &options_zv, &readoptions_zv, &writeoptions_zv) == FAILURE) { 636 | return; 637 | } 638 | 639 | LEVELDB_CHECK_OPEN_BASEDIR(name); 640 | 641 | intern = LEVELDB_OBJ_FROM_ZV(getThis()); 642 | 643 | if (intern->db) { 644 | leveldb_close(intern->db); 645 | } 646 | 647 | openoptions = php_leveldb_get_open_options(options_zv, &intern->comparator, &intern->callable_name); 648 | 649 | if (!openoptions) { 650 | return; 651 | } 652 | 653 | php_leveldb_set_readoptions(intern, readoptions_zv); 654 | php_leveldb_set_writeoptions(intern, writeoptions_zv); 655 | 656 | db = leveldb_open(openoptions, (const char *)name, &err); 657 | 658 | leveldb_options_destroy(openoptions); 659 | 660 | LEVELDB_CHECK_ERROR(err); 661 | 662 | intern->db = db; 663 | } 664 | /* }}} */ 665 | 666 | /* {{{ proto mixed LevelDB::get(string $key [, array $read_options]) 667 | Returns the value for the given key or false */ 668 | PHP_METHOD(LevelDB, get) 669 | { 670 | char *key, *value; 671 | size_t key_len; 672 | size_t value_len; 673 | zval *readoptions_zv = NULL; 674 | 675 | char *err = NULL; 676 | leveldb_readoptions_t *readoptions; 677 | leveldb_object *intern; 678 | 679 | if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|z", 680 | &key, &key_len, &readoptions_zv) == FAILURE) { 681 | return; 682 | } 683 | 684 | intern = LEVELDB_OBJ_FROM_ZV(getThis()); 685 | LEVELDB_CHECK_DB_NOT_CLOSED(intern); 686 | 687 | readoptions = php_leveldb_get_readoptions(intern, readoptions_zv); 688 | value = leveldb_get(intern->db, readoptions, key, key_len, &value_len, &err); 689 | leveldb_readoptions_destroy(readoptions); 690 | 691 | LEVELDB_CHECK_ERROR(err); 692 | 693 | if (value == NULL) { 694 | RETURN_FALSE; 695 | } 696 | 697 | RETVAL_STRINGL(value, value_len); 698 | leveldb_free(value); 699 | } 700 | /* }}} */ 701 | 702 | /* {{{ proto bool LevelDB::set(string $key, string $value [, array $write_options]) 703 | An alias method for LevelDB::put() */ 704 | /* proto bool LevelDB::put(string $key, string $value [, array $write_options]) 705 | Puts the value for the given key */ 706 | PHP_METHOD(LevelDB, set) 707 | { 708 | char *key, *value; 709 | size_t key_len, value_len; 710 | zval *writeoptions_zv = NULL; 711 | 712 | char *err = NULL; 713 | leveldb_writeoptions_t *writeoptions; 714 | leveldb_object *intern; 715 | 716 | if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss|z", 717 | &key, &key_len, &value, &value_len, &writeoptions_zv) == FAILURE) { 718 | return; 719 | } 720 | 721 | intern = LEVELDB_OBJ_FROM_ZV(getThis()); 722 | LEVELDB_CHECK_DB_NOT_CLOSED(intern); 723 | 724 | writeoptions = php_leveldb_get_writeoptions(intern, writeoptions_zv); 725 | leveldb_put(intern->db, writeoptions, key, key_len, value, value_len, &err); 726 | leveldb_writeoptions_destroy(writeoptions); 727 | 728 | LEVELDB_CHECK_ERROR(err); 729 | 730 | RETURN_TRUE; 731 | } 732 | /* }}} */ 733 | 734 | /* {{{ proto bool LevelDB::delete(string $key [, array $write_options]) 735 | Deletes the given key */ 736 | PHP_METHOD(LevelDB, delete) 737 | { 738 | char *key; 739 | size_t key_len; 740 | zval *writeoptions_zv = NULL; 741 | 742 | char *err = NULL; 743 | leveldb_writeoptions_t *writeoptions; 744 | leveldb_object *intern; 745 | 746 | if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|z", 747 | &key, &key_len, &writeoptions_zv) == FAILURE) { 748 | return; 749 | } 750 | 751 | intern = LEVELDB_OBJ_FROM_ZV(getThis()); 752 | LEVELDB_CHECK_DB_NOT_CLOSED(intern); 753 | 754 | writeoptions = php_leveldb_get_writeoptions(intern, writeoptions_zv); 755 | leveldb_delete(intern->db, writeoptions, key, key_len, &err); 756 | leveldb_writeoptions_destroy(writeoptions); 757 | 758 | LEVELDB_CHECK_ERROR(err); 759 | 760 | if (err != NULL) { 761 | RETURN_FALSE; 762 | } 763 | 764 | RETURN_TRUE; 765 | } 766 | /* }}} */ 767 | 768 | /* {{{ proto bool LevelDB::write(LevelDBWriteBatch $batch [, array $write_options]) 769 | Executes all of the operations added in the write batch */ 770 | PHP_METHOD(LevelDB, write) 771 | { 772 | zval *writeoptions_zv = NULL; 773 | zval *write_batch; 774 | 775 | char *err = NULL; 776 | leveldb_object *intern; 777 | leveldb_writeoptions_t *writeoptions; 778 | leveldb_write_batch_object *write_batch_object; 779 | 780 | if (zend_parse_parameters(ZEND_NUM_ARGS(), "O|z", 781 | &write_batch, php_leveldb_write_batch_class_entry, &writeoptions_zv) == FAILURE) { 782 | return; 783 | } 784 | 785 | intern = LEVELDB_OBJ_FROM_ZV(getThis()); 786 | LEVELDB_CHECK_DB_NOT_CLOSED(intern); 787 | 788 | writeoptions = php_leveldb_get_writeoptions(intern, writeoptions_zv); 789 | write_batch_object = LEVELDB_WRITE_BATCH_OBJ_FROM_ZV(write_batch); 790 | 791 | leveldb_write(intern->db, writeoptions, write_batch_object->batch, &err); 792 | leveldb_writeoptions_destroy(writeoptions); 793 | 794 | LEVELDB_CHECK_ERROR(err); 795 | 796 | RETURN_TRUE; 797 | } 798 | /* }}} */ 799 | 800 | /* {{{ proto mixed LevelDB::getProperty(string $name) 801 | Returns the property of the db */ 802 | PHP_METHOD(LevelDB, getProperty) 803 | { 804 | char *name, *property; 805 | size_t name_len; 806 | leveldb_object *intern; 807 | 808 | if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &name, &name_len) == FAILURE) { 809 | return; 810 | } 811 | 812 | intern = LEVELDB_OBJ_FROM_ZV(getThis()); 813 | LEVELDB_CHECK_DB_NOT_CLOSED(intern); 814 | 815 | property = leveldb_property_value(intern->db, (const char *)name); 816 | 817 | if (property == NULL) { 818 | RETURN_FALSE; 819 | } 820 | 821 | RETVAL_STRING(property); 822 | leveldb_free(property); 823 | } 824 | /* }}} */ 825 | 826 | /* {{{ proto void LevelDB::compactRange(string $start, string $limit) 827 | Compact the range between the specified */ 828 | PHP_METHOD(LevelDB, compactRange) 829 | { 830 | char *start, *limit; 831 | size_t start_len, limit_len; 832 | leveldb_object *intern; 833 | 834 | if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss", &start, &start_len, &limit, &limit_len) == FAILURE) { 835 | return; 836 | } 837 | 838 | intern = LEVELDB_OBJ_FROM_ZV(getThis()); 839 | LEVELDB_CHECK_DB_NOT_CLOSED(intern); 840 | 841 | leveldb_compact_range(intern->db, (const char *)start, (size_t)start_len, (const char *)limit, (size_t)limit_len); 842 | } 843 | /* }}} */ 844 | 845 | /* {{{ proto mixed LevelDB::getApproximateSizes(array $start, array $limit) 846 | Get the approximate number of bytes of file system space used by one or more key ranges 847 | or return false on failure */ 848 | PHP_METHOD(LevelDB, getApproximateSizes) 849 | { 850 | leveldb_object *intern; 851 | zval *start, *limit, *start_val, *limit_val; 852 | char **start_key, **limit_key; 853 | size_t *start_len, *limit_len; 854 | unsigned int num_ranges, i = 0; 855 | HashPosition pos_start, pos_limit; 856 | uint64_t *sizes; 857 | 858 | if (zend_parse_parameters(ZEND_NUM_ARGS(), "aa", &start, &limit) == FAILURE) { 859 | return; 860 | } 861 | 862 | intern = LEVELDB_OBJ_FROM_ZV(getThis()); 863 | LEVELDB_CHECK_DB_NOT_CLOSED(intern); 864 | 865 | num_ranges = zend_hash_num_elements(Z_ARRVAL_P(start)); 866 | 867 | if (num_ranges != zend_hash_num_elements(Z_ARRVAL_P(limit))) { 868 | php_error_docref(NULL, E_WARNING, "The num of start keys and limit keys didn't match"); 869 | RETURN_FALSE; 870 | } 871 | 872 | array_init(return_value); 873 | 874 | start_key = emalloc(num_ranges * sizeof(char *)); 875 | limit_key = emalloc(num_ranges * sizeof(char *)); 876 | start_len = emalloc(num_ranges * sizeof(size_t)); 877 | limit_len = emalloc(num_ranges * sizeof(size_t)); 878 | sizes = emalloc(num_ranges * sizeof(uint64_t)); 879 | 880 | zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(start), &pos_start); 881 | zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(limit), &pos_limit); 882 | 883 | while ((start_val = zend_hash_get_current_data_ex(Z_ARRVAL_P(start), &pos_start)) != NULL && 884 | (limit_val = zend_hash_get_current_data_ex(Z_ARRVAL_P(limit), &pos_limit)) != NULL) { 885 | 886 | start_key[i] = Z_STRVAL_P(start_val); 887 | start_len[i] = Z_STRLEN_P(start_val); 888 | limit_key[i] = Z_STRVAL_P(limit_val); 889 | limit_len[i] = Z_STRLEN_P(limit_val); 890 | 891 | zend_hash_move_forward_ex(Z_ARRVAL_P(start), &pos_start); 892 | zend_hash_move_forward_ex(Z_ARRVAL_P(limit), &pos_limit); 893 | 894 | ++i; 895 | } 896 | 897 | leveldb_approximate_sizes(intern->db, num_ranges, 898 | (const char* const *)start_key, (const size_t *)start_len, 899 | (const char* const *)limit_key, (const size_t *)limit_len, sizes); 900 | 901 | for (i = 0; i < num_ranges; ++i) { 902 | add_next_index_long(return_value, sizes[i]); 903 | } 904 | 905 | efree(start_key); 906 | efree(start_len); 907 | efree(limit_key); 908 | efree(limit_len); 909 | efree(sizes); 910 | } 911 | /* }}} */ 912 | 913 | /* {{{ proto bool LevelDB::close() 914 | Close the opened db */ 915 | PHP_METHOD(LevelDB, close) 916 | { 917 | if (zend_parse_parameters_none() == FAILURE) { 918 | return; 919 | } 920 | /* NOOP and deprecated function */ 921 | 922 | RETURN_TRUE; 923 | } 924 | /* }}} */ 925 | 926 | /* {{{ proto LevelDBIterator LevelDB::getIterator([array $read_options]) 927 | Gets a new iterator for the db */ 928 | PHP_METHOD(LevelDB, getIterator) 929 | { 930 | zval *readoptions_zv = NULL; 931 | 932 | if (zend_parse_parameters(ZEND_NUM_ARGS(), "|a", &readoptions_zv) == FAILURE) { 933 | return; 934 | } 935 | 936 | object_init_ex(return_value, php_leveldb_iterator_class_entry); 937 | 938 | #if PHP_VERSION_ID < 80000 939 | zend_call_method(return_value, php_leveldb_iterator_class_entry, 940 | #else 941 | zend_call_method(Z_OBJ_P(return_value), php_leveldb_iterator_class_entry, 942 | #endif 943 | &php_leveldb_iterator_class_entry->constructor, "__construct", sizeof("__construct") - 1, 944 | NULL, (readoptions_zv == NULL ? 1 : 2), getThis(), readoptions_zv); 945 | } 946 | /* }}} */ 947 | 948 | /* {{{ proto LevelDBSnapshot LevelDB::getSnapshot() 949 | Gets a new snapshot for the db */ 950 | PHP_METHOD(LevelDB, getSnapshot) 951 | { 952 | if (zend_parse_parameters_none() == FAILURE) { 953 | return; 954 | } 955 | 956 | object_init_ex(return_value, php_leveldb_snapshot_class_entry); 957 | 958 | #if PHP_VERSION_ID < 80000 959 | zend_call_method_with_1_params(return_value, php_leveldb_snapshot_class_entry, 960 | &php_leveldb_snapshot_class_entry->constructor, "__construct", NULL, getThis()); 961 | #else 962 | zend_call_method_with_1_params(Z_OBJ_P(return_value), php_leveldb_snapshot_class_entry, 963 | &php_leveldb_snapshot_class_entry->constructor, "__construct", NULL, getThis()); 964 | #endif 965 | 966 | } 967 | /* }}} */ 968 | 969 | /* {{{ proto bool LevelDB::destroy(string $name [, array $options]) 970 | Destroy the contents of the specified database */ 971 | PHP_METHOD(LevelDB, destroy) 972 | { 973 | char *name; 974 | size_t name_len; 975 | zval *options_zv = NULL; 976 | 977 | char *err = NULL; 978 | zend_string *callable_name = NULL; 979 | leveldb_options_t *options; 980 | leveldb_comparator_t *comparator = NULL; 981 | 982 | if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|z", 983 | &name, &name_len, &options_zv) == FAILURE) { 984 | return; 985 | } 986 | 987 | LEVELDB_CHECK_OPEN_BASEDIR(name); 988 | 989 | options = php_leveldb_get_open_options(options_zv, &comparator, &callable_name); 990 | 991 | if (!options) { 992 | return; 993 | } 994 | 995 | leveldb_destroy_db(options, name, &err); 996 | 997 | if (comparator) { 998 | leveldb_comparator_destroy(comparator); 999 | zend_string_release(callable_name); 1000 | } 1001 | 1002 | leveldb_options_destroy(options); 1003 | 1004 | LEVELDB_CHECK_ERROR(err); 1005 | 1006 | RETURN_TRUE; 1007 | } 1008 | /* }}} */ 1009 | 1010 | /* {{{ proto bool LevelDB::repair(string $name [, array $options]) 1011 | Repairs the given database */ 1012 | PHP_METHOD(LevelDB, repair) 1013 | { 1014 | char *name; 1015 | size_t name_len; 1016 | zval *options_zv; 1017 | 1018 | char *err = NULL; 1019 | zend_string *callable_name = NULL; 1020 | leveldb_options_t *options; 1021 | leveldb_comparator_t *comparator = NULL; 1022 | 1023 | if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|z", 1024 | &name, &name_len, &options_zv) == FAILURE) { 1025 | return; 1026 | } 1027 | 1028 | LEVELDB_CHECK_OPEN_BASEDIR(name); 1029 | 1030 | options = php_leveldb_get_open_options(options_zv, &comparator, &callable_name); 1031 | 1032 | if (!options) { 1033 | return; 1034 | } 1035 | 1036 | leveldb_repair_db(options, name, &err); 1037 | 1038 | if (comparator) { 1039 | leveldb_comparator_destroy(comparator); 1040 | zend_string_release(callable_name); 1041 | } 1042 | 1043 | leveldb_options_destroy(options); 1044 | 1045 | LEVELDB_CHECK_ERROR(err); 1046 | 1047 | RETURN_TRUE; 1048 | } 1049 | /* }}} */ 1050 | 1051 | /* {{{ proto LevelDBWriteBatch LevelDBWriteBatch::__construct() 1052 | Instantiates a LevelDBWriteBatch object */ 1053 | PHP_METHOD(LevelDBWriteBatch, __construct) 1054 | { 1055 | leveldb_write_batch_object *intern; 1056 | leveldb_writebatch_t *batch; 1057 | 1058 | if (zend_parse_parameters_none() == FAILURE) { 1059 | return; 1060 | } 1061 | 1062 | intern = LEVELDB_WRITE_BATCH_OBJ_FROM_ZV(getThis()); 1063 | batch = leveldb_writebatch_create(); 1064 | 1065 | intern->batch = batch; 1066 | } 1067 | /* }}} */ 1068 | 1069 | /* {{{ proto bool LevelDBWriteBatch::set(string $key, string $value) 1070 | An alias for LevelDBWriteBatch::put() */ 1071 | /* proto bool LevelDBWriteBatch::put(string $key, string $value) 1072 | Adds a put operation for the given key and value to the write batch. */ 1073 | PHP_METHOD(LevelDBWriteBatch, set) 1074 | { 1075 | char *key, *value; 1076 | size_t key_len, value_len; 1077 | 1078 | leveldb_write_batch_object *intern; 1079 | 1080 | if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss", 1081 | &key, &key_len, &value, &value_len) == FAILURE) { 1082 | return; 1083 | } 1084 | 1085 | intern = LEVELDB_WRITE_BATCH_OBJ_FROM_ZV(getThis()); 1086 | leveldb_writebatch_put(intern->batch, key, key_len, value, value_len); 1087 | 1088 | RETURN_TRUE; 1089 | } 1090 | /* }}} */ 1091 | 1092 | /* {{{ proto bool LevelDBWriteBatch::delete(string $key) 1093 | Adds a deletion operation for the given key to the write batch */ 1094 | PHP_METHOD(LevelDBWriteBatch, delete) 1095 | { 1096 | char *key; 1097 | size_t key_len; 1098 | 1099 | leveldb_write_batch_object *intern; 1100 | 1101 | if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &key, &key_len) == FAILURE) { 1102 | return; 1103 | } 1104 | 1105 | intern = LEVELDB_WRITE_BATCH_OBJ_FROM_ZV(getThis()); 1106 | leveldb_writebatch_delete(intern->batch, key, key_len); 1107 | 1108 | RETURN_TRUE; 1109 | } 1110 | /* }}} */ 1111 | 1112 | /* {{{ proto bool LevelDBWriteBatch::clear() 1113 | Clears all of operations in the write batch */ 1114 | PHP_METHOD(LevelDBWriteBatch, clear) 1115 | { 1116 | leveldb_write_batch_object *intern; 1117 | 1118 | if (zend_parse_parameters_none() == FAILURE) { 1119 | return; 1120 | } 1121 | 1122 | intern = LEVELDB_WRITE_BATCH_OBJ_FROM_ZV(getThis()); 1123 | leveldb_writebatch_clear(intern->batch); 1124 | 1125 | RETURN_TRUE; 1126 | 1127 | } 1128 | /* }}} */ 1129 | 1130 | /* {{{ forward declarations to the iterator handlers */ 1131 | static void leveldb_iterator_dtor(zend_object_iterator *iter); 1132 | static int leveldb_iterator_valid(zend_object_iterator *iter); 1133 | static zval* leveldb_iterator_current_data(zend_object_iterator *iter); 1134 | 1135 | static void leveldb_iterator_current_key(zend_object_iterator *iter, zval *key); 1136 | static void leveldb_iterator_move_forward(zend_object_iterator *iter); 1137 | static void leveldb_iterator_rewind(zend_object_iterator *iter); 1138 | 1139 | static int php_leveldb_check_iter_db_not_closed(leveldb_iterator_object *intern) { 1140 | if (intern->iterator == NULL) { 1141 | zend_throw_exception(php_leveldb_ce_LevelDBException, "Iterator has been destroyed", PHP_LEVELDB_ERROR_ITERATOR_CLOSED); 1142 | return FAILURE; 1143 | } 1144 | if (intern->db->db == NULL) { 1145 | intern->iterator = NULL; 1146 | zend_throw_exception(php_leveldb_ce_LevelDBException, "Can not iterate on closed db", PHP_LEVELDB_ERROR_DB_CLOSED); 1147 | return FAILURE; 1148 | } 1149 | 1150 | return SUCCESS; 1151 | } 1152 | 1153 | #define LEVELDB_CHECK_ITER_DB_NOT_CLOSED(intern) \ 1154 | if(php_leveldb_check_iter_db_not_closed(intern) != SUCCESS){ \ 1155 | return; \ 1156 | } 1157 | 1158 | /* iterator handler table */ 1159 | zend_object_iterator_funcs leveldb_iterator_funcs = { 1160 | leveldb_iterator_dtor, 1161 | leveldb_iterator_valid, 1162 | leveldb_iterator_current_data, 1163 | leveldb_iterator_current_key, 1164 | leveldb_iterator_move_forward, 1165 | leveldb_iterator_rewind, 1166 | NULL 1167 | }; 1168 | /* }}} */ 1169 | 1170 | /* {{{ leveldb_iterator_get_iterator */ 1171 | zend_object_iterator *leveldb_iterator_get_iterator(zend_class_entry *ce, zval *object, int by_ref) 1172 | { 1173 | leveldb_iterator_iterator *iterator; 1174 | leveldb_iterator_object *it_object; 1175 | 1176 | if (by_ref) { 1177 | zend_error(E_ERROR, "An iterator cannot be used with foreach by reference"); 1178 | } 1179 | 1180 | it_object = LEVELDB_ITERATOR_OBJ_FROM_ZV(object); 1181 | iterator = emalloc(sizeof(leveldb_iterator_iterator)); 1182 | 1183 | zend_iterator_init((zend_object_iterator*)iterator); 1184 | 1185 | iterator->intern.funcs = &leveldb_iterator_funcs; 1186 | ZVAL_COPY(&iterator->intern.data, object); 1187 | iterator->iterator_obj = it_object; 1188 | iterator->current = NULL; 1189 | 1190 | return (zend_object_iterator*)iterator; 1191 | } 1192 | /* }}} */ 1193 | 1194 | /* {{{ leveldb_iterator_dtor */ 1195 | static void leveldb_iterator_dtor(zend_object_iterator *iter) 1196 | { 1197 | leveldb_iterator_iterator *iterator = (leveldb_iterator_iterator *)iter; 1198 | 1199 | zval *object = &iterator->intern.data; 1200 | zval_ptr_dtor(object); 1201 | 1202 | if (iterator->current) { 1203 | zval_ptr_dtor(iterator->current); 1204 | efree(iterator->current); 1205 | } 1206 | 1207 | iterator->iterator_obj = NULL; 1208 | } 1209 | /* }}} */ 1210 | 1211 | /* {{{ leveldb_iterator_valid */ 1212 | static int leveldb_iterator_valid(zend_object_iterator *iter) 1213 | { 1214 | leveldb_iterator_object *iterator_obj = ((leveldb_iterator_iterator *)iter)->iterator_obj; 1215 | 1216 | if (php_leveldb_check_iter_db_not_closed(iterator_obj) != SUCCESS) { 1217 | return FAILURE; 1218 | } 1219 | 1220 | return leveldb_iter_valid(iterator_obj->iterator) ? SUCCESS : FAILURE; 1221 | } 1222 | /* }}} */ 1223 | 1224 | /* {{{ leveldb_iterator_current_data */ 1225 | static zval* leveldb_iterator_current_data(zend_object_iterator *iter) 1226 | { 1227 | char *value; 1228 | size_t value_len; 1229 | zval *current; 1230 | 1231 | leveldb_iterator_iterator *iterator = (leveldb_iterator_iterator *)iter; 1232 | 1233 | leveldb_iterator_object *iterator_obj = iterator->iterator_obj; 1234 | 1235 | current = (zval *)emalloc(sizeof(zval)); 1236 | 1237 | if (php_leveldb_check_iter_db_not_closed(iterator_obj) != SUCCESS) { 1238 | ZVAL_NULL(current); 1239 | } else { 1240 | if (iterator->current) { 1241 | zval_ptr_dtor(iterator->current); 1242 | efree(iterator->current); 1243 | } 1244 | 1245 | value = (char *)leveldb_iter_value(iterator_obj->iterator, &value_len); 1246 | 1247 | ZVAL_STRINGL(current, value, value_len); 1248 | } 1249 | 1250 | iterator->current = current; 1251 | 1252 | return current; 1253 | } 1254 | /* }}} */ 1255 | 1256 | /* {{{ leveldb_iterator_current_key */ 1257 | static void leveldb_iterator_current_key(zend_object_iterator *iter, zval *key) 1258 | { 1259 | char *cur_key; 1260 | size_t cur_key_len = 0; 1261 | leveldb_iterator_object *iterator_obj = ((leveldb_iterator_iterator *)iter)->iterator_obj; 1262 | LEVELDB_CHECK_ITER_DB_NOT_CLOSED(iterator_obj); 1263 | 1264 | cur_key = (char *)leveldb_iter_key(iterator_obj->iterator, &cur_key_len); 1265 | ZVAL_STRINGL(key, cur_key, cur_key_len); 1266 | } 1267 | /* }}} */ 1268 | 1269 | /* {{{ leveldb_iterator_move_forward */ 1270 | static void leveldb_iterator_move_forward(zend_object_iterator *iter) 1271 | { 1272 | leveldb_iterator_object *iterator_obj = ((leveldb_iterator_iterator *)iter)->iterator_obj; 1273 | LEVELDB_CHECK_ITER_DB_NOT_CLOSED(iterator_obj); 1274 | 1275 | leveldb_iter_next(iterator_obj->iterator); 1276 | } 1277 | /* }}} */ 1278 | 1279 | /* {{{ leveldb_iterator_rewind */ 1280 | static void leveldb_iterator_rewind(zend_object_iterator *iter) 1281 | { 1282 | leveldb_iterator_object *iterator_obj = ((leveldb_iterator_iterator *)iter)->iterator_obj; 1283 | LEVELDB_CHECK_ITER_DB_NOT_CLOSED(iterator_obj); 1284 | 1285 | leveldb_iter_seek_to_first(iterator_obj->iterator); 1286 | } 1287 | /* }}} */ 1288 | 1289 | /* {{{ proto LevelDBIterator LevelDBIterator::__construct(LevelDB $db [, array $read_options]) 1290 | Instantiates a LevelDBIterator object. */ 1291 | PHP_METHOD(LevelDBIterator, __construct) 1292 | { 1293 | zval *db_zv = NULL; 1294 | leveldb_object *db_obj; 1295 | zval *readoptions_zv = NULL; 1296 | 1297 | leveldb_iterator_object *intern; 1298 | leveldb_readoptions_t *readoptions; 1299 | 1300 | if (zend_parse_parameters(ZEND_NUM_ARGS(), "O|z", 1301 | &db_zv, php_leveldb_class_entry, &readoptions_zv) == FAILURE) { 1302 | return; 1303 | } 1304 | 1305 | intern = LEVELDB_ITERATOR_OBJ_FROM_ZV(getThis()); 1306 | db_obj = LEVELDB_OBJ_FROM_ZV(db_zv); 1307 | LEVELDB_CHECK_DB_NOT_CLOSED(db_obj); 1308 | 1309 | readoptions = php_leveldb_get_readoptions(db_obj, readoptions_zv); 1310 | 1311 | if (!readoptions) { 1312 | return; 1313 | } 1314 | 1315 | intern->iterator = leveldb_create_iterator(db_obj->db, readoptions); 1316 | 1317 | leveldb_readoptions_destroy(readoptions); 1318 | 1319 | intern->db = db_obj; 1320 | /* Incr. obj counter */ 1321 | ZVAL_COPY(&intern->zdb, db_zv); 1322 | 1323 | leveldb_iter_seek_to_first(intern->iterator); 1324 | } 1325 | /* }}} */ 1326 | 1327 | /* {{{ proto bool LevelDBIterator::destroy() 1328 | Destroy the iterator */ 1329 | PHP_METHOD(LevelDBIterator, destroy) 1330 | { 1331 | leveldb_iterator_object *intern; 1332 | 1333 | if (zend_parse_parameters_none() == FAILURE) { 1334 | return; 1335 | } 1336 | 1337 | intern = LEVELDB_ITERATOR_OBJ_FROM_ZV(getThis()); 1338 | if (intern->iterator) { 1339 | leveldb_iter_destroy(intern->iterator); 1340 | intern->iterator = NULL; 1341 | } 1342 | 1343 | RETURN_TRUE; 1344 | } 1345 | /* }}} */ 1346 | 1347 | /* {{{ proto string LevelDBIterator::getError() 1348 | Return last iterator error */ 1349 | PHP_METHOD(LevelDBIterator, getError) 1350 | { 1351 | char *err = NULL; 1352 | leveldb_iterator_object *intern; 1353 | 1354 | if (zend_parse_parameters_none() == FAILURE) { 1355 | return; 1356 | } 1357 | 1358 | intern = LEVELDB_ITERATOR_OBJ_FROM_ZV(getThis()); 1359 | LEVELDB_CHECK_ITER_DB_NOT_CLOSED(intern); 1360 | 1361 | leveldb_iter_get_error(intern->iterator, &err); 1362 | 1363 | if (err == NULL) { 1364 | RETURN_FALSE; 1365 | } 1366 | 1367 | RETVAL_STRING(err); 1368 | leveldb_free(err); 1369 | } 1370 | /* }}} */ 1371 | 1372 | /* {{{ proto string LevelDBIterator::current() 1373 | Return current element */ 1374 | PHP_METHOD(LevelDBIterator, current) 1375 | { 1376 | char *value = NULL; 1377 | size_t value_len; 1378 | leveldb_iterator_object *intern; 1379 | 1380 | if (zend_parse_parameters_none() == FAILURE) { 1381 | return; 1382 | } 1383 | 1384 | intern = LEVELDB_ITERATOR_OBJ_FROM_ZV(getThis()); 1385 | LEVELDB_CHECK_ITER_DB_NOT_CLOSED(intern); 1386 | 1387 | if (!leveldb_iter_valid(intern->iterator) || 1388 | !(value = (char *)leveldb_iter_value(intern->iterator, &value_len))) { 1389 | RETURN_FALSE; 1390 | } 1391 | 1392 | RETURN_STRINGL(value, value_len); 1393 | } 1394 | /* }}} */ 1395 | 1396 | /* {{{ proto string LevelDBIterator::key() 1397 | Returns the key of current element */ 1398 | PHP_METHOD(LevelDBIterator, key) 1399 | { 1400 | char *key = NULL; 1401 | size_t key_len; 1402 | leveldb_iterator_object *intern; 1403 | 1404 | if (zend_parse_parameters_none() == FAILURE) { 1405 | return; 1406 | } 1407 | 1408 | intern = LEVELDB_ITERATOR_OBJ_FROM_ZV(getThis()); 1409 | LEVELDB_CHECK_ITER_DB_NOT_CLOSED(intern); 1410 | 1411 | if (!leveldb_iter_valid(intern->iterator) || 1412 | !(key = (char *)leveldb_iter_key(intern->iterator, &key_len))) { 1413 | RETURN_FALSE; 1414 | } 1415 | 1416 | RETURN_STRINGL(key, key_len); 1417 | } 1418 | /* }}} */ 1419 | 1420 | /* {{{ proto void LevelDBIterator::next() 1421 | Moves forward to the next element */ 1422 | PHP_METHOD(LevelDBIterator, next) 1423 | { 1424 | leveldb_iterator_object *intern; 1425 | 1426 | if (zend_parse_parameters_none() == FAILURE) { 1427 | return; 1428 | } 1429 | 1430 | intern = LEVELDB_ITERATOR_OBJ_FROM_ZV(getThis()); 1431 | LEVELDB_CHECK_ITER_DB_NOT_CLOSED(intern); 1432 | 1433 | if (leveldb_iter_valid(intern->iterator)) { 1434 | leveldb_iter_next(intern->iterator); 1435 | } 1436 | } 1437 | /* }}} */ 1438 | 1439 | /* {{{ proto void LevelDBIterator::prev() 1440 | Moves backward to the previous element */ 1441 | PHP_METHOD(LevelDBIterator, prev) 1442 | { 1443 | leveldb_iterator_object *intern; 1444 | 1445 | if (zend_parse_parameters_none() == FAILURE) { 1446 | return; 1447 | } 1448 | 1449 | intern = LEVELDB_ITERATOR_OBJ_FROM_ZV(getThis()); 1450 | LEVELDB_CHECK_ITER_DB_NOT_CLOSED(intern); 1451 | 1452 | if (leveldb_iter_valid(intern->iterator)) { 1453 | leveldb_iter_prev(intern->iterator); 1454 | } 1455 | } 1456 | /* }}} */ 1457 | 1458 | /* {{{ proto void LevelDBIterator::rewind() 1459 | Rewinds back to the first element of the Iterator */ 1460 | PHP_METHOD(LevelDBIterator, rewind) 1461 | { 1462 | leveldb_iterator_object *intern; 1463 | 1464 | if (zend_parse_parameters_none() == FAILURE) { 1465 | return; 1466 | } 1467 | 1468 | intern = LEVELDB_ITERATOR_OBJ_FROM_ZV(getThis()); 1469 | LEVELDB_CHECK_ITER_DB_NOT_CLOSED(intern); 1470 | 1471 | leveldb_iter_seek_to_first(intern->iterator); 1472 | } 1473 | /* }}} */ 1474 | 1475 | /* {{{ proto void LevelDBIterator::last() 1476 | Moves to the last element of the Iterator */ 1477 | PHP_METHOD(LevelDBIterator, last) 1478 | { 1479 | leveldb_iterator_object *intern; 1480 | 1481 | if (zend_parse_parameters_none() == FAILURE) { 1482 | return; 1483 | } 1484 | 1485 | intern = LEVELDB_ITERATOR_OBJ_FROM_ZV(getThis()); 1486 | LEVELDB_CHECK_ITER_DB_NOT_CLOSED(intern); 1487 | 1488 | leveldb_iter_seek_to_last(intern->iterator); 1489 | } 1490 | /* }}} */ 1491 | 1492 | /* {{{ proto void LevelDBIterator::seek(string $key) 1493 | Seeks to a given key in the Iterator if no such key it will point to nearest key */ 1494 | PHP_METHOD(LevelDBIterator, seek) 1495 | { 1496 | char *key; 1497 | size_t key_len; 1498 | leveldb_iterator_object *intern; 1499 | 1500 | if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &key, &key_len ) == FAILURE) { 1501 | return; 1502 | } 1503 | 1504 | intern = LEVELDB_ITERATOR_OBJ_FROM_ZV(getThis()); 1505 | LEVELDB_CHECK_ITER_DB_NOT_CLOSED(intern); 1506 | 1507 | leveldb_iter_seek(intern->iterator, key, (size_t)key_len); 1508 | } 1509 | /* }}} */ 1510 | 1511 | /* {{{ proto bool LevelDBIterator::valid() 1512 | Checks if current position is valid */ 1513 | PHP_METHOD(LevelDBIterator, valid) 1514 | { 1515 | leveldb_iterator_object *intern; 1516 | 1517 | if (zend_parse_parameters_none() == FAILURE) { 1518 | return; 1519 | } 1520 | 1521 | intern = LEVELDB_ITERATOR_OBJ_FROM_ZV(getThis()); 1522 | LEVELDB_CHECK_ITER_DB_NOT_CLOSED(intern); 1523 | 1524 | RETURN_BOOL(leveldb_iter_valid(intern->iterator)); 1525 | } 1526 | /* }}} */ 1527 | 1528 | /* {{{ proto LevelDBSnapshot LevelDBSnapshot::__construct(LevelDB $db) 1529 | Instantiates a LevelDBSnapshot object */ 1530 | PHP_METHOD(LevelDBSnapshot, __construct) 1531 | { 1532 | zval *db_zv = NULL; 1533 | leveldb_object *db_obj; 1534 | leveldb_snapshot_object *intern; 1535 | 1536 | if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", 1537 | &db_zv, php_leveldb_class_entry) == FAILURE) { 1538 | return; 1539 | } 1540 | 1541 | intern = LEVELDB_SNAPSHOT_OBJ_FROM_ZV(getThis()); 1542 | db_obj = LEVELDB_OBJ_FROM_ZV(db_zv); 1543 | LEVELDB_CHECK_DB_NOT_CLOSED(db_obj); 1544 | 1545 | intern->snapshot = (leveldb_snapshot_t *)leveldb_create_snapshot(db_obj->db); 1546 | 1547 | intern->db = db_obj; 1548 | /* Incr. obj counter */ 1549 | ZVAL_COPY(&intern->zdb, db_zv); 1550 | } 1551 | /* }}} */ 1552 | 1553 | /* {{{ proto void LevelDBSnapshot::release() 1554 | Release the LevelDBSnapshot object */ 1555 | PHP_METHOD(LevelDBSnapshot, release) 1556 | { 1557 | leveldb_snapshot_object *intern; 1558 | 1559 | if (zend_parse_parameters_none() == FAILURE) { 1560 | return; 1561 | } 1562 | 1563 | intern = LEVELDB_SNAPSHOT_OBJ_FROM_ZV(getThis()); 1564 | 1565 | if (intern->db == NULL || intern->snapshot == NULL) { 1566 | return; 1567 | } 1568 | 1569 | leveldb_object *db = intern->db; 1570 | leveldb_release_snapshot(db->db, intern->snapshot); 1571 | intern->snapshot = NULL; 1572 | intern->db = NULL; 1573 | } 1574 | /* }}} */ 1575 | 1576 | /* {{{ PHP_MINIT_FUNCTION 1577 | */ 1578 | PHP_MINIT_FUNCTION(leveldb) 1579 | { 1580 | zend_class_entry ce; 1581 | zend_class_entry *exception_ce = zend_exception_get_default(); 1582 | 1583 | #define DECLARE_OBJ_HANDLERS(class_type) \ 1584 | memcpy(& class_type##_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); \ 1585 | class_type##_handlers.offset = XtOffsetOf(class_type, std); \ 1586 | class_type##_handlers.dtor_obj = zend_objects_destroy_object;\ 1587 | class_type##_handlers.free_obj = php_##class_type##_free; 1588 | 1589 | DECLARE_OBJ_HANDLERS(leveldb_object); 1590 | DECLARE_OBJ_HANDLERS(leveldb_snapshot_object); 1591 | DECLARE_OBJ_HANDLERS(leveldb_write_batch_object); 1592 | DECLARE_OBJ_HANDLERS(leveldb_iterator_object); 1593 | 1594 | /* Register LevelDB Class */ 1595 | INIT_CLASS_ENTRY(ce, "LevelDB", php_leveldb_class_methods); 1596 | ce.create_object = php_leveldb_object_new; 1597 | php_leveldb_class_entry = zend_register_internal_class(&ce); 1598 | 1599 | /* Register LevelDBWriteBatch Class */ 1600 | INIT_CLASS_ENTRY(ce, "LevelDBWriteBatch", php_leveldb_write_batch_class_methods); 1601 | ce.create_object = php_leveldb_write_batch_object_new; 1602 | php_leveldb_write_batch_class_entry = zend_register_internal_class(&ce); 1603 | 1604 | /* Register LevelDBIterator Class */ 1605 | INIT_CLASS_ENTRY(ce, "LevelDBIterator", php_leveldb_iterator_class_methods); 1606 | ce.create_object = php_leveldb_iterator_object_new; 1607 | php_leveldb_iterator_class_entry = zend_register_internal_class(&ce); 1608 | php_leveldb_iterator_class_entry->get_iterator = leveldb_iterator_get_iterator; 1609 | 1610 | 1611 | /* Register LevelDBSnapshot Class */ 1612 | INIT_CLASS_ENTRY(ce, "LevelDBSnapshot", php_leveldb_snapshot_class_methods); 1613 | ce.create_object = php_leveldb_snapshot_object_new; 1614 | php_leveldb_snapshot_class_entry = zend_register_internal_class(&ce); 1615 | 1616 | /* Register LevelDBException class */ 1617 | INIT_CLASS_ENTRY(ce, "LevelDBException", NULL); 1618 | ce.create_object = exception_ce->create_object; 1619 | php_leveldb_ce_LevelDBException = zend_register_internal_class_ex(&ce, exception_ce); 1620 | 1621 | /* Register constants */ 1622 | REGISTER_LONG_CONSTANT("LEVELDB_NO_COMPRESSION", leveldb_no_compression, CONST_CS | CONST_PERSISTENT); 1623 | REGISTER_LONG_CONSTANT("LEVELDB_SNAPPY_COMPRESSION", leveldb_snappy_compression, CONST_CS | CONST_PERSISTENT); 1624 | 1625 | #ifdef MOJANG_LEVELDB 1626 | REGISTER_LONG_CONSTANT("LEVELDB_ZLIB_COMPRESSION", leveldb_zlib_compression, CONST_CS | CONST_PERSISTENT); 1627 | REGISTER_LONG_CONSTANT("LEVELDB_ZLIB_RAW_COMPRESSION", leveldb_zlib_raw_compression, CONST_CS | CONST_PERSISTENT); 1628 | #endif // MOJANG_LEVELDB 1629 | 1630 | return SUCCESS; 1631 | } 1632 | /* }}} */ 1633 | 1634 | /* {{{ PHP_MSHUTDOWN_FUNCTION 1635 | */ 1636 | PHP_MSHUTDOWN_FUNCTION(leveldb) 1637 | { 1638 | return SUCCESS; 1639 | } 1640 | /* }}} */ 1641 | 1642 | /* {{{ PHP_MINFO_FUNCTION 1643 | */ 1644 | PHP_MINFO_FUNCTION(leveldb) 1645 | { 1646 | char tmp[32]; 1647 | snprintf(tmp, 32, "%d.%d", leveldb_major_version(), leveldb_minor_version()); 1648 | 1649 | php_info_print_table_start(); 1650 | php_info_print_table_header(2, "leveldb support", "enabled"); 1651 | php_info_print_table_row(2, "leveldb extension version", PHP_LEVELDB_VERSION); 1652 | php_info_print_table_row(2, "leveldb library version", tmp); 1653 | php_info_print_table_end(); 1654 | } 1655 | /* }}} */ 1656 | 1657 | /* 1658 | * Local variables: 1659 | * tab-width: 4 1660 | * c-basic-offset: 4 1661 | * End: 1662 | * vim600: noet sw=4 ts=4 fdm=marker 1663 | * vim<600: noet sw=4 ts=4 1664 | */ 1665 | -------------------------------------------------------------------------------- /package.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | leveldb 7 | pecl.php.net 8 | LevelDB PHP bindings 9 | 10 | This extension is a PHP binding for Google LevelDB 11 | 12 | 13 | Reeze Xia 14 | reeze 15 | reeze@php.net 16 | yes 17 | 18 | 19 | Dylan K. Taylor 20 | dktapps 21 | dktapps@pmmp.io 22 | yes 23 | 24 | 25 | Arpad Ray 26 | arpad 27 | arpad@php.net 28 | yes 29 | 30 | 2021-02-18 31 | 32 | 0.3.0 33 | 0.3.0 34 | 35 | 36 | beta 37 | beta 38 | 39 | PHP 40 | 41 | - Add support for PHP 7.3, 7.4 and 8.0 42 | - Fixed assert failures and possible faults involving comparators 43 | - Deprecate LevelDB->close() (use unset($db) instead, allows more consistent behaviour of iterators and snapshots, and fixes leveldb asserts) 44 | - Fix wrong arginfo of LevelDBWriteBatch 45 | - Fix memory errors when google/leveldb was compiled with different compiler options than php-leveldb 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 7.0.0 86 | 87 | 88 | 1.4.0b1 89 | 90 | 91 | 92 | leveldb 93 | 94 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /php_leveldb.h: -------------------------------------------------------------------------------- 1 | /* 2 | +----------------------------------------------------------------------+ 3 | | PHP Version 5 | 4 | +----------------------------------------------------------------------+ 5 | | Copyright (c) 1997-2015 The PHP Group | 6 | +----------------------------------------------------------------------+ 7 | | This source file is subject to version 3.01 of the PHP license, | 8 | | that is bundled with this package in the file LICENSE, and is | 9 | | available through the world-wide-web at the following url: | 10 | | http://www.php.net/license/3_01.txt | 11 | | If you did not receive a copy of the PHP license and are unable to | 12 | | obtain it through the world-wide-web, please send a note to | 13 | | license@php.net so we can mail you a copy immediately. | 14 | +----------------------------------------------------------------------+ 15 | | Author: Reeze Xia | 16 | +----------------------------------------------------------------------+ 17 | */ 18 | 19 | /* $Id$ */ 20 | 21 | #ifndef PHP_LEVELDB_H 22 | #define PHP_LEVELDB_H 23 | 24 | #define PHP_LEVELDB_VERSION "0.3.0" 25 | 26 | extern zend_module_entry leveldb_module_entry; 27 | #define phpext_leveldb_ptr &leveldb_module_entry 28 | 29 | #ifdef PHP_WIN32 30 | # define PHP_LEVELDB_API __declspec(dllexport) 31 | #elif defined(__GNUC__) && __GNUC__ >= 4 32 | # define PHP_LEVELDB_API __attribute__ ((visibility("default"))) 33 | #else 34 | # define PHP_LEVELDB_API 35 | #endif 36 | 37 | #define DLLX 38 | 39 | #ifdef ZTS 40 | #include "TSRM.h" 41 | #endif 42 | 43 | PHP_METHOD(LevelDB, __construct); 44 | PHP_METHOD(LevelDB, get); 45 | PHP_METHOD(LevelDB, set); 46 | PHP_METHOD(LevelDB, put); 47 | PHP_METHOD(LevelDB, delete); 48 | PHP_METHOD(LevelDB, write); 49 | PHP_METHOD(LevelDB, getProperty); 50 | PHP_METHOD(LevelDB, close); 51 | PHP_METHOD(LevelDB, getApproximateSizes); 52 | PHP_METHOD(LevelDB, compactRange); 53 | PHP_METHOD(LevelDB, getIterator); 54 | PHP_METHOD(LevelDB, getSnapshot); 55 | PHP_METHOD(LevelDB, destroy); 56 | PHP_METHOD(LevelDB, repair); 57 | 58 | PHP_MINIT_FUNCTION(leveldb); 59 | PHP_MSHUTDOWN_FUNCTION(leveldb); 60 | PHP_RINIT_FUNCTION(leveldb); 61 | PHP_RSHUTDOWN_FUNCTION(leveldb); 62 | PHP_MINFO_FUNCTION(leveldb); 63 | 64 | PHP_METHOD(LevelDBWriteBatch, __construct); 65 | PHP_METHOD(LevelDBWriteBatch, set); 66 | PHP_METHOD(LevelDBWriteBatch, put); 67 | PHP_METHOD(LevelDBWriteBatch, delete); 68 | PHP_METHOD(LevelDBWriteBatch, clear); 69 | 70 | PHP_METHOD(LevelDBIterator, __construct); 71 | PHP_METHOD(LevelDBIterator, valid); 72 | PHP_METHOD(LevelDBIterator, rewind); 73 | PHP_METHOD(LevelDBIterator, last); 74 | PHP_METHOD(LevelDBIterator, seek); 75 | PHP_METHOD(LevelDBIterator, next); 76 | PHP_METHOD(LevelDBIterator, prev); 77 | PHP_METHOD(LevelDBIterator, key); 78 | PHP_METHOD(LevelDBIterator, current); 79 | PHP_METHOD(LevelDBIterator, getError); 80 | PHP_METHOD(LevelDBIterator, destroy); 81 | 82 | PHP_METHOD(LevelDBSnapshot, __construct); 83 | PHP_METHOD(LevelDBSnapshot, release); 84 | 85 | #ifdef ZTS 86 | #define LDB_G(v) TSRMG(leveldb_globals_id, zend_leveldb_globals *, v) 87 | #else 88 | #define LDB_G(v) (leveldb_globals.v) 89 | #endif 90 | 91 | #endif /* PHP_LEVELDB_H */ 92 | 93 | 94 | /* 95 | * Local variables: 96 | * tab-width: 4 97 | * c-basic-offset: 4 98 | * End: 99 | * vim600: noet sw=4 ts=4 fdm=marker 100 | * vim<600: noet sw=4 ts=4 101 | */ 102 | -------------------------------------------------------------------------------- /stub.php: -------------------------------------------------------------------------------- 1 | true, // if the specified database does not exist will create a new one 25 | 'error_if_exists' => false, // if the opened database exists will throw exception 26 | 'paranoid_checks' => false, 27 | 'block_cache_size' => 8 * (2 << 20), 28 | 'write_buffer_size' => 4<<20, 29 | 'block_size' => 4096, 30 | 'max_open_files' => 1000, 31 | 'block_restart_interval' => 16, 32 | 'compression' => LEVELDB_SNAPPY_COMPRESSION, 33 | 'comparator' => NULL, // any callable parameter return 0, -1, 1 34 | ], array $read_options = [ 35 | 'verify_check_sum' => false, //may be set to true to force checksum verification of all data that is read from the file system on behalf of a particular read. By default, no such verification is done. 36 | 'fill_cache' => true, //When performing a bulk read, the application may set this to false to disable the caching so that the data processed by the bulk read does not end up displacing most of the cached contents. 37 | ], array $write_options = [ 38 | //Only one element named sync in the write option array. By default, each write to leveldb is asynchronous. 39 | 'sync' => false 40 | ]){} 41 | 42 | /** 43 | * @param string $key 44 | * @param array $read_options 45 | * 46 | * @return string|bool 47 | */ 48 | public function get($key, array $read_options = []){} 49 | 50 | /** 51 | * Alias of LevelDB::put() 52 | * 53 | * @param string $key 54 | * @param string $value 55 | * @param array $write_options 56 | */ 57 | public function set($key, $value, array $write_options = []){} 58 | 59 | /** 60 | * @param string $key 61 | * @param string $value 62 | * @param array $write_options 63 | */ 64 | public function put($key, $value, array $write_options = []){} 65 | 66 | /** 67 | * @param string $key 68 | * @param array $write_options 69 | * 70 | * @return bool 71 | */ 72 | public function delete($key, array $write_options = []){} 73 | 74 | /** 75 | * Executes all of the operations added in the write batch. 76 | * 77 | * @param LevelDBWriteBatch $batch 78 | * @param array $write_options 79 | */ 80 | public function write(LevelDBWriteBatch $batch, array $write_options = []){} 81 | 82 | /** 83 | * Valid properties: 84 | * - leveldb.stats: returns the status of the entire db 85 | * - leveldb.num-files-at-level: returns the number of files for each level. For example, you can use leveldb.num-files-at-level0 the number of files for zero level. 86 | * - leveldb.sstables: returns current status of sstables 87 | * 88 | * @param string $name 89 | * 90 | * @return mixed 91 | */ 92 | public function getProperty($name){} 93 | 94 | public function getApproximateSizes($start, $limit){} 95 | 96 | public function compactRange($start, $limit){} 97 | 98 | public function close(){} 99 | 100 | /** 101 | * @param array $options 102 | * 103 | * @return LevelDBIterator 104 | */ 105 | public function getIterator(array $options = []){} 106 | 107 | /** 108 | * @return LevelDBSnapshot 109 | */ 110 | public function getSnapshot(){} 111 | 112 | static public function destroy($name, array $options = []){} 113 | 114 | static public function repair($name, array $options = []){} 115 | } 116 | 117 | class LevelDBIterator implements Iterator{ 118 | 119 | public function __construct(LevelDB $db, array $read_options = []){} 120 | 121 | public function valid(){} 122 | 123 | public function rewind(){} 124 | 125 | public function last(){} 126 | 127 | public function seek($key){} 128 | 129 | public function next(){} 130 | 131 | public function prev(){} 132 | 133 | public function key(){} 134 | 135 | public function current(){} 136 | 137 | public function getError(){} 138 | 139 | public function destroy(){} 140 | 141 | } 142 | 143 | class LevelDBWriteBatch{ 144 | public function __construct(){} 145 | 146 | public function set($key, $value, array $write_options = []){} 147 | 148 | public function put($key, $value, array $write_options = []){} 149 | 150 | public function delete($key, array $write_options = []){} 151 | 152 | public function clear(){} 153 | } 154 | 155 | class LevelDBSnapshot{ 156 | public function __construct(LevelDB $db){} 157 | 158 | public function release(){} 159 | 160 | } 161 | 162 | class LevelDBException extends Exception{ 163 | 164 | } 165 | -------------------------------------------------------------------------------- /tests/001-basic.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | leveldb - basic: get(), set(), put(), delete() 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | set('key', 'value')); 12 | var_dump($db->get('key')); 13 | var_dump($db->get('non-exists-key')); 14 | var_dump($db->put('name', 'reeze')); 15 | var_dump($db->get('name')); 16 | var_dump($db->delete('name')); 17 | var_dump($db->get('name')); 18 | ?> 19 | --CLEAN-- 20 | 24 | --EXPECTF-- 25 | bool(true) 26 | string(5) "value" 27 | bool(false) 28 | bool(true) 29 | string(5) "reeze" 30 | bool(true) 31 | bool(false) 32 | -------------------------------------------------------------------------------- /tests/002-db-management.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | leveldb - db management 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | set("key", "value"); 11 | 12 | unset($db); 13 | var_dump(LevelDB::destroy($path)); 14 | var_dump(file_exists($path)); 15 | ?> 16 | --EXPECTF-- 17 | bool(true) 18 | bool(false) 19 | -------------------------------------------------------------------------------- /tests/003-openbasedir.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | leveldb - open base dir 3 | --INI-- 4 | open_basedir=. 5 | --SKIPIF-- 6 | 7 | --FILE-- 8 | 17 | --EXPECTF-- 18 | Warning: LevelDB::__construct(): open_basedir restriction in effect. File(%s) is not within the allowed path(s): (%s) in %s on line %d 19 | 20 | Warning: LevelDB::destroy(): open_basedir restriction in effect. File(%s) is not within the allowed path(s): (%s) in %s on line %d 21 | 22 | Warning: LevelDB::repair(): open_basedir restriction in effect. File(%s) is not within the allowed path(s): (%s) in %s on line %d 23 | -------------------------------------------------------------------------------- /tests/004-write-batch.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | leveldb - write batch 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | set('batch_foo', 'batch_bar'); 14 | $batch->put('batch_foo2', 'batch_bar2'); 15 | $batch->delete('batch_foo'); 16 | 17 | var_dump($db->write($batch)); 18 | 19 | var_dump($db->get('batch_foo2')); 20 | var_dump($db->get('batch_foo')); 21 | 22 | echo "* batch write with delete\n"; 23 | $batch->clear(); 24 | $batch->delete('batch_foo2'); 25 | $batch->set('batch_foo', 'batch again'); 26 | 27 | var_dump($db->write($batch)); 28 | 29 | var_dump($db->get('batch_foo2')); 30 | var_dump($db->get('batch_foo')); 31 | ?> 32 | --CLEAN-- 33 | 37 | --EXPECTF-- 38 | * batch write with setting 39 | bool(true) 40 | string(10) "batch_bar2" 41 | bool(false) 42 | * batch write with delete 43 | bool(true) 44 | bool(false) 45 | string(11) "batch again" 46 | -------------------------------------------------------------------------------- /tests/005-iterator.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | leveldb - iterate through db 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | set($item, $item); 18 | } 19 | 20 | $it = new LevelDBIterator($db); 21 | 22 | echo "*** Loop through ***\n"; 23 | for ($it->rewind(); $it->valid(); $it->next()) { 24 | echo $it->key() . " => " . $it->current() . "\n"; 25 | } 26 | 27 | echo "\n*** Reset to last ***\n"; 28 | var_dump($it->last()); 29 | var_dump($it->key() . " => " . $it->current()); 30 | 31 | echo "\n*** Last->next will be invalid ***\n"; 32 | var_dump($it->next()); 33 | var_dump($it->valid()); 34 | var_dump($it->key()); 35 | 36 | echo "\n*** Seek to give key ***\n"; 37 | $it->seek("Second"); 38 | var_dump($it->current()); 39 | 40 | echo "\n*** Seek to a non-exist key will point to nearest next key ***\n"; 41 | $it->seek("11"); 42 | var_dump($it->current()); 43 | 44 | echo "\n*** Bound checking ***\n"; 45 | $it->rewind(); 46 | $it->prev(); 47 | $it->prev(); 48 | var_dump($it->current()); 49 | 50 | $it->next(); 51 | $it->next(); 52 | $it->next(); 53 | $it->next(); 54 | $it->next(); 55 | $it->next(); 56 | $it->next(); 57 | $it->next(); 58 | $it->next(); 59 | $it->next(); 60 | var_dump($it->current()); 61 | 62 | var_dump($it->getError()); 63 | ?> 64 | --CLEAN-- 65 | 69 | --EXPECTF-- 70 | *** Loop through *** 71 | => 72 | 10 => 10 73 | First => First 74 | Last => Last 75 | Second => Second 76 | Third => Third 77 | 78 | *** Reset to last *** 79 | NULL 80 | string(14) "Third => Third" 81 | 82 | *** Last->next will be invalid *** 83 | NULL 84 | bool(false) 85 | bool(false) 86 | 87 | *** Seek to give key *** 88 | string(6) "Second" 89 | 90 | *** Seek to a non-exist key will point to nearest next key *** 91 | string(5) "First" 92 | 93 | *** Bound checking *** 94 | bool(false) 95 | bool(false) 96 | bool(false) 97 | -------------------------------------------------------------------------------- /tests/006-iterator-foreach.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | leveldb - iterate through db by foreach 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | set($item, $item); 18 | } 19 | 20 | $it = new LevelDBIterator($db); 21 | 22 | echo "*** Loop through in foreach style ***\n"; 23 | foreach ($it as $key => $value) { 24 | echo "{$key} => {$value}\n"; 25 | } 26 | 27 | echo "*** Loop through in foreach with newly-created iterator ***\n"; 28 | foreach(new LevelDBIterator($db) as $key => $value){ 29 | echo "{$key} => {$value}\n"; 30 | } 31 | ?> 32 | --CLEAN-- 33 | 37 | --EXPECTF-- 38 | *** Loop through in foreach style *** 39 | => 40 | 10 => 10 41 | First => First 42 | Last => Last 43 | Second => Second 44 | Third => Third 45 | *** Loop through in foreach with newly-created iterator *** 46 | => 47 | 10 => 10 48 | First => First 49 | Last => Last 50 | Second => Second 51 | Third => Third 52 | -------------------------------------------------------------------------------- /tests/007-db-close.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | leveldb - db close 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | close(); 12 | 13 | 14 | unset($it); 15 | unset($db); 16 | 17 | // ensure destructeur properly close the db */ 18 | LevelDB::destroy($leveldb_path); 19 | var_dump(file_exists($leveldb_path)); 20 | ?> 21 | --CLEAN-- 22 | 26 | --EXPECTF-- 27 | Deprecated: %s LevelDB::close() is deprecated in %s 28 | bool(false) 29 | -------------------------------------------------------------------------------- /tests/008-options.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | leveldb - options open options 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | false)); 12 | } catch(LevelDBException $e) { 13 | echo $e->getMessage() . "\n"; 14 | } 15 | 16 | try { 17 | $db = new LevelDB($leveldb_path, array("max_open_files" => 10)); 18 | $db->set("key", "value"); 19 | var_dump($db->get("key")); 20 | } catch(LevelDBException $e) { 21 | echo $e->getMessage() . "\n"; 22 | } 23 | 24 | unset($db); 25 | try { 26 | $db = new LevelDB($leveldb_path, array("error_if_exists" => true)); 27 | } catch(LevelDBException $e) { 28 | echo $e->getMessage() . "\n"; 29 | } 30 | ?> 31 | ==DONE== 32 | --CLEAN-- 33 | 37 | --EXPECTF-- 38 | Invalid argument: %s: does not exist (create_if_missing is false) 39 | string(5) "value" 40 | Invalid argument: %s: exists (error_if_exists is true) 41 | ==DONE== 42 | -------------------------------------------------------------------------------- /tests/009-comparator.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | leveldb - custom comparator 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | 'invaid_func')); 13 | } catch(LevelDBException $e) { 14 | echo $e->getMessage() . "\n"; 15 | } 16 | 17 | echo "*** valid custom comparator ***\n"; 18 | $db = new LevelDB($leveldb_path, array('comparator' => 'custom_comparator')); 19 | 20 | $values = array(3, 1, 4, 6, 2, 5); 21 | foreach($values as $v) { 22 | $db->set($v, $v); 23 | } 24 | 25 | $it = new LevelDBIterator($db); 26 | foreach($it as $v) { 27 | echo "$v\n"; 28 | } 29 | unset($it); 30 | unset($db); 31 | 32 | echo "*** custom comparator can only open with the same comparator again ***\n"; 33 | try { 34 | $db = new LevelDB($leveldb_path); 35 | } catch(LevelDBException $e) { 36 | echo $e->getMessage() . "\n"; 37 | } 38 | 39 | 40 | $db = new LevelDB($leveldb_path, array('comparator' => 'custom_comparator')); 41 | var_dump($db->get(1) == 1); 42 | unset($db); 43 | 44 | 45 | echo "*** custom comparator which throw exception ***\n"; 46 | $db = new LevelDB($leveldb_path, array('comparator' => array('CustomFunc', 'willException'))); 47 | try { 48 | $db->set("Hi", "guys"); 49 | var_dump($db->get("Hi")); 50 | } catch(Exception $e) { 51 | echo $e->getMessage() . "\n"; 52 | } 53 | 54 | // reverse DESC 55 | function custom_comparator($a, $b) { 56 | if ($a == $b) { 57 | return 0; 58 | } 59 | return ($a > $b) ? -1 : 1; 60 | } 61 | 62 | class CustomFunc { 63 | public static function willException($a, $b) { 64 | throw new Exception("Oops!"); 65 | } 66 | } 67 | ?> 68 | ==DONE== 69 | --CLEAN-- 70 | 74 | --EXPECTF-- 75 | *** could not use invalid custom comparator *** 76 | Invalid open option: comparator, invaid_func() is not callable 77 | *** valid custom comparator *** 78 | 6 79 | 5 80 | 4 81 | 3 82 | 2 83 | 1 84 | *** custom comparator can only open with the same comparator again *** 85 | Invalid argument: php_leveldb.custom_comparator%s leveldb.BytewiseComparator 86 | bool(true) 87 | *** custom comparator which throw exception *** 88 | Oops! 89 | ==DONE== 90 | -------------------------------------------------------------------------------- /tests/010-compression.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | leveldb - compression 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | 33)); 11 | unset($db); 12 | 13 | $db = new LevelDB($leveldb_path, array('compression' => LEVELDB_SNAPPY_COMPRESSION)); 14 | $db->set("key", "value"); 15 | 16 | ?> 17 | ==DONE== 18 | --CLEAN-- 19 | 23 | --EXPECTF-- 24 | Warning: LevelDB::__construct(): Unsupported compression type in %s on line %s 25 | ==DONE== 26 | -------------------------------------------------------------------------------- /tests/011-getApproximateSizes.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | leveldb - getApproximateSizes 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | set("b{$i}", "value"); 13 | } 14 | 15 | unset($db); 16 | 17 | $db = new LevelDB($leveldb_path); 18 | 19 | var_dump($db->getApproximateSizes(array("A", "B", 3), array("b0", "Z"))); 20 | var_dump($db->getApproximateSizes(array(), array())); 21 | var_dump($db->getApproximateSizes(array("a", "b"), array("c", "Z"))); 22 | ?> 23 | ==DONE== 24 | --CLEAN-- 25 | 29 | --EXPECTF-- 30 | Warning: LevelDB::getApproximateSizes(): The num of start keys and limit keys didn't match in %s on line %d 31 | bool(false) 32 | array(0) { 33 | } 34 | array(2) { 35 | [0]=> 36 | int(%d) 37 | [1]=> 38 | int(%d) 39 | } 40 | ==DONE== 41 | -------------------------------------------------------------------------------- /tests/012-getProperty.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | leveldb - getProperty 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | set("b{$i}", "value{$i}"); 13 | } 14 | 15 | $stats = $db->getProperty('leveldb.stats'); 16 | var_dump($stats !== false); 17 | var_dump(strlen($stats) > 1); 18 | var_dump($db->getProperty('leveldb.num-files-at-level1')); 19 | var_dump($db->getProperty('leveldb.num-files-at-level2')); 20 | var_dump($db->getProperty('leveldb.num-files-at-level3')); 21 | 22 | $sstables = $db->getProperty('leveldb.sstables'); 23 | var_dump($sstables !== false); 24 | var_dump(strlen($sstables) > 1); 25 | 26 | var_dump($db->getProperty('leveldb.anything')); 27 | var_dump($db->getProperty('anythingelse')); 28 | ?> 29 | ==DONE== 30 | --CLEAN-- 31 | 35 | --EXPECTF-- 36 | bool(true) 37 | bool(true) 38 | string(1) "%d" 39 | string(1) "%d" 40 | string(1) "%d" 41 | bool(true) 42 | bool(true) 43 | bool(false) 44 | bool(false) 45 | ==DONE== 46 | -------------------------------------------------------------------------------- /tests/013-compactRange.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | leveldb - compactRange 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | set("b{$i}", "value{$i}"); 13 | } 14 | 15 | var_dump($db->compactRange('a', 'Z')); 16 | ?> 17 | ==DONE== 18 | --CLEAN-- 19 | 23 | --EXPECTF-- 24 | NULL 25 | ==DONE== 26 | -------------------------------------------------------------------------------- /tests/014-iterator-destroy.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | leveldb - iterator destroy 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | set("key", "value"); 12 | $it = new LevelDBIterator($db); 13 | 14 | $it->destroy(); 15 | try { 16 | $it->next(); 17 | } catch(LevelDBException $e) { 18 | echo $e->getMessage() . "\n"; 19 | } 20 | ?> 21 | ==DONE== 22 | --CLEAN-- 23 | 27 | --EXPECTF-- 28 | Iterator has been destroyed 29 | ==DONE== 30 | -------------------------------------------------------------------------------- /tests/015-double-iterator.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | leveldb - Fixed bug segfault when double construct iterator 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | destroy(); 15 | $it2->destroy(); 16 | ?> 17 | ==DONE== 18 | --CLEAN-- 19 | 23 | --EXPECTF-- 24 | ==DONE== 25 | -------------------------------------------------------------------------------- /tests/016-different-iterators-should-differ.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | leveldb - different iterators should not affect each other 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | put($k, $k); 13 | } 14 | 15 | $it1 = new LevelDBIterator($db); 16 | $it2 = new LevelDBIterator($db); 17 | 18 | foreach($it1 as $k => $v) { 19 | echo "$k => $v\n"; 20 | } 21 | 22 | $it1->rewind(); 23 | var_dump($it1->next()); 24 | var_dump($it1->next()); 25 | var_dump($it1->current()); 26 | var_dump($it2->current()); 27 | 28 | $it1->destroy(); 29 | $it2->destroy(); 30 | ?> 31 | ==DONE== 32 | --CLEAN-- 33 | 37 | --EXPECTF-- 38 | 1 => 1 39 | 2 => 2 40 | 3 => 3 41 | 4 => 4 42 | NULL 43 | NULL 44 | string(1) "3" 45 | string(1) "1" 46 | ==DONE== 47 | -------------------------------------------------------------------------------- /tests/017-db-getIterator.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | leveldb - LevelDB::getIterator() 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | set($item, $item); 13 | } 14 | 15 | $it = $db->getIterator(); 16 | 17 | var_dump(get_class($it)); 18 | 19 | for ($it->rewind(); $it->valid(); $it->next()) { 20 | echo $it->key() . " => " . $it->current() . "\n"; 21 | } 22 | ?> 23 | --CLEAN-- 24 | 28 | --EXPECTF-- 29 | string(15) "LevelDBIterator" 30 | 1 => 1 31 | 2 => 2 32 | 3 => 3 33 | 4 => 4 34 | 5 => 5 35 | 6 => 6 36 | 7 => 7 37 | 8 => 8 38 | 9 => 9 39 | -------------------------------------------------------------------------------- /tests/018-snapshot.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | leveldb - snapshot 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | put("key1", "value1"); 13 | $db->put("key2", "value2"); 14 | 15 | $snapshot = new LevelDBSnapshot($db); 16 | 17 | $db->put("key3", "value3"); 18 | 19 | 20 | try { 21 | $it = new LevelDBIterator($db, array('snapshot' => '')); 22 | } catch(LevelDBException $e) { 23 | var_dump($e->getMessage()); 24 | } 25 | 26 | $it = $db->getIterator(array('snapshot' => $snapshot)); 27 | foreach($it as $k => $v) { 28 | echo "$k => $v\n"; 29 | } 30 | 31 | var_dump($db->get("key3", array('snapshot' => $snapshot))); 32 | var_dump($db->get("key3")); 33 | 34 | echo "*** Release snapshot x1 ***\n"; 35 | $snapshot->release(); 36 | echo "*** Release snapshot x2 ***\n"; 37 | $snapshot->release(); 38 | 39 | echo "*** Try to use released snapshot ***\n"; 40 | try { 41 | $it = new LevelDBIterator($db, array('snapshot' => $snapshot)); 42 | } catch(LevelDBException $e) { 43 | var_dump($e->getMessage()); 44 | } 45 | ?> 46 | ==DONE== 47 | --CLEAN-- 48 | 52 | --EXPECTF-- 53 | string(69) "Invalid snapshot parameter, it must be an instance of LevelDBSnapshot" 54 | key1 => value1 55 | key2 => value2 56 | bool(false) 57 | string(6) "value3" 58 | *** Release snapshot x1 *** 59 | *** Release snapshot x2 *** 60 | *** Try to use released snapshot *** 61 | string(48) "Invalid snapshot parameter, it has been released" 62 | ==DONE== 63 | -------------------------------------------------------------------------------- /tests/019-null-comparator.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | leveldb - NULL comparator should not throw exception 3 | --DESCRIPTION-- 4 | NULL is the default value of comparator open options 5 | open with null shouldn't throw exception 6 | --SKIPIF-- 7 | 8 | --FILE-- 9 | NULL)); 14 | 15 | ?> 16 | Should no exception 17 | ==DONE== 18 | --CLEAN-- 19 | 23 | --EXPECT-- 24 | Should no exception 25 | ==DONE== 26 | -------------------------------------------------------------------------------- /tests/020-null-snapshot.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | leveldb - NULL snapshot should not throw exception 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | get("key", array('snapshot' => NULL))); 13 | 14 | ?> 15 | Should no exception 16 | ==DONE== 17 | --CLEAN-- 18 | 22 | --EXPECT-- 23 | bool(false) 24 | Should no exception 25 | ==DONE== 26 | -------------------------------------------------------------------------------- /tests/leveldb.inc: -------------------------------------------------------------------------------- 1 | rewind(); $it->valid(); $it->next()) { 7 | $db->delete($it->key()); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /tests/skipif.inc: -------------------------------------------------------------------------------- 1 | --------------------------------------------------------------------------------