├── .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: [](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 void LevelDB::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 | LevelDB::close 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 void LevelDB::compactRange
14 | string start
15 | string limit
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 | LevelDB::compactRange 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 | string name
15 | string options
16 | string read_options
17 | string write_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 | LevelDB::__construct 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 void LevelDB::delete
14 | string key
15 | string write_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 | LevelDB::delete 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 void LevelDB::destroy
14 | string name
15 | string options
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 | LevelDB::destroy 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 void LevelDB::get
14 | string key
15 | string read_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 | LevelDB::get 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 void LevelDB::getApproximateSizes
14 | string start
15 | string limit
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 | LevelDB::getApproximateSizes 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 void LevelDB::getProperty
14 | string name
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 getProperty
33 | using name
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 | LevelDB::getProperty 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 void LevelDB::put
14 | string key
15 | string value
16 | string write_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 | LevelDB::put 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 void LevelDB::repair
14 | string name
15 | string options
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 | LevelDB::repair 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 void LevelDB::set
14 | string key
15 | string value
16 | string write_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 void LevelDB::write
16 | LevelDBWriteBatch batch
17 | string write_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 | LevelDB::write 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 | string db
15 | string read_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 | LevelDBIterator::__construct 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 void LevelDBIterator::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 | LevelDBIterator::current 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 void LevelDBIterator::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 | LevelDBIterator::destroy 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 void LevelDBIterator::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 | LevelDBIterator::getError 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 void LevelDBIterator::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 | LevelDBIterator::key 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 void LevelDBIterator::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 | LevelDBIterator::last 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 void LevelDBIterator::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 | LevelDBIterator::next 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 void LevelDBIterator::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 | LevelDBIterator::prev 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 void LevelDBIterator::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 | LevelDBIterator::rewind 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 void LevelDBIterator::seek
14 | string key
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 | LevelDBIterator::seek 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 void LevelDBIterator::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 | LevelDBIterator::valid 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 void LevelDBWriteBatch::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 | LevelDBWriteBatch::clear 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 | string name
15 | string options
16 | string read_options
17 | string write_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 | LevelDBWriteBatch::__construct 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 void LevelDBWriteBatch::delete
14 | string key
15 | string write_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 | LevelDBWriteBatch::delete 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 void LevelDBWriteBatch::put
14 | string key
15 | string value
16 | string write_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 | LevelDBWriteBatch::put 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 void LevelDBWriteBatch::set
14 | string key
15 | string value
16 | string write_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 | LevelDBWriteBatch::set 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 |
--------------------------------------------------------------------------------