1 | /* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*- */ |
2 | #ident "$Id$" |
3 | /*====== |
4 | This file is part of PerconaFT. |
5 | |
6 | |
7 | Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved. |
8 | |
9 | PerconaFT is free software: you can redistribute it and/or modify |
10 | it under the terms of the GNU General Public License, version 2, |
11 | as published by the Free Software Foundation. |
12 | |
13 | PerconaFT is distributed in the hope that it will be useful, |
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 | GNU General Public License for more details. |
17 | |
18 | You should have received a copy of the GNU General Public License |
19 | along with PerconaFT. If not, see <http://www.gnu.org/licenses/>. |
20 | |
21 | ---------------------------------------- |
22 | |
23 | PerconaFT is free software: you can redistribute it and/or modify |
24 | it under the terms of the GNU Affero General Public License, version 3, |
25 | as published by the Free Software Foundation. |
26 | |
27 | PerconaFT is distributed in the hope that it will be useful, |
28 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
29 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
30 | GNU Affero General Public License for more details. |
31 | |
32 | You should have received a copy of the GNU Affero General Public License |
33 | along with PerconaFT. If not, see <http://www.gnu.org/licenses/>. |
34 | ======= */ |
35 | |
36 | #ident "Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved." |
37 | |
38 | #include <db.h> |
39 | |
40 | #include "cursor.hpp" |
41 | #include "db.hpp" |
42 | #include "db_env.hpp" |
43 | #include "db_txn.hpp" |
44 | #include "exceptions.hpp" |
45 | |
46 | namespace ftcxx { |
47 | |
48 | DBC::DBC(const DB &db, const DBTxn &txn, int flags) |
49 | : _txn(), |
50 | _dbc(nullptr) |
51 | { |
52 | if (db.db() != nullptr) { |
53 | DB_TXN *txnp = txn.txn(); |
54 | if (txnp == nullptr) { |
55 | _txn = DBTxn(DBEnv(db.db()->dbenv), DB_TXN_READ_ONLY | DB_READ_UNCOMMITTED); |
56 | txnp = _txn.txn(); |
57 | } |
58 | |
59 | ::DBC *c; |
60 | int r = db.db()->cursor(db.db(), txnp, &c, flags); |
61 | handle_ft_retval(r); |
62 | _dbc = c; |
63 | } |
64 | } |
65 | |
66 | DBC::DBC(const DBEnv &env, const DBTxn &txn) |
67 | : _txn(), |
68 | _dbc(nullptr) |
69 | { |
70 | if (env.env() != nullptr) { |
71 | DB_TXN *txnp = txn.txn(); |
72 | if (txnp == nullptr) { |
73 | _txn = DBTxn(env, DB_TXN_READ_ONLY | DB_READ_UNCOMMITTED); |
74 | txnp = _txn.txn(); |
75 | } |
76 | |
77 | ::DBC *c; |
78 | int r = env.env()->get_cursor_for_directory(env.env(), txnp, &c); |
79 | handle_ft_retval(r); |
80 | _dbc = c; |
81 | } |
82 | } |
83 | |
84 | DBC::~DBC() { |
85 | if (_dbc != nullptr) { |
86 | close(); |
87 | } |
88 | } |
89 | |
90 | void DBC::close() { |
91 | int r = _dbc->c_close(_dbc); |
92 | handle_ft_retval(r); |
93 | _dbc = nullptr; |
94 | } |
95 | |
96 | bool DBC::set_range(const IterationStrategy &strategy, const Bounds &bounds, YDB_CALLBACK_FUNCTION callback, void *) const { |
97 | int r = dbc()->c_set_bounds(dbc(), bounds.left_dbt(), bounds.right_dbt(), strategy.prelock, 0); |
98 | handle_ft_retval(r); |
99 | |
100 | if (strategy.forward) { |
101 | if (bounds.left_infinite()) { |
102 | r = dbc()->c_getf_first(dbc(), strategy.getf_flags(), callback, extra); |
103 | } else { |
104 | r = dbc()->c_getf_set_range(dbc(), strategy.getf_flags(), const_cast<DBT *>(bounds.left_dbt()), callback, extra); |
105 | } |
106 | } else { |
107 | if (bounds.right_infinite()) { |
108 | r = dbc()->c_getf_last(dbc(), strategy.getf_flags(), callback, extra); |
109 | } else { |
110 | r = dbc()->c_getf_set_range_reverse(dbc(), strategy.getf_flags(), const_cast<DBT *>(bounds.right_dbt()), callback, extra); |
111 | } |
112 | } |
113 | if (r == DB_NOTFOUND) { |
114 | return false; |
115 | } else if (r != 0 && r != -1) { |
116 | handle_ft_retval(r); |
117 | } |
118 | return true; |
119 | } |
120 | |
121 | bool DBC::advance(const IterationStrategy &strategy, YDB_CALLBACK_FUNCTION callback, void *) const { |
122 | int r; |
123 | if (strategy.forward) { |
124 | r = dbc()->c_getf_next(dbc(), strategy.getf_flags(), callback, extra); |
125 | } else { |
126 | r = dbc()->c_getf_prev(dbc(), strategy.getf_flags(), callback, extra); |
127 | } |
128 | if (r == DB_NOTFOUND) { |
129 | return false; |
130 | } else if (r != 0 && r != -1) { |
131 | handle_ft_retval(r); |
132 | } |
133 | return true; |
134 | } |
135 | |
136 | } // namespace ftcxx |
137 | |