-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSQLiteLongArray.java
More file actions
216 lines (199 loc) · 9.17 KB
/
Copy pathSQLiteLongArray.java
File metadata and controls
216 lines (199 loc) · 9.17 KB
1
2
3
4
5
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
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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
/*
* Copyright 2010 ALM Works Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.almworks.sqlite4java;
import static com.almworks.sqlite4java.SQLiteConstants.WRAPPER_STATEMENT_DISPOSED;
/**
* SQLiteLongArray wraps a virtual table handle, created with {@link SQLiteConnection#createArray}.
* Use methods of this class to set the array's contents (maybe several times), and dispose it when done.
* <p/>
* Like with other classes, the methods are confined to the thread that opened SQLiteConnection, unless stated otherwise.
* <p/>
* The virtual array table has a single column named <code>value</code> with INTEGER affinity.
* <p/>
* If you bind ordered and/or unique values to the array, it may greatly improve performance if the underlying
* code knows about that fact. See {@link #bind(long[], int, int, boolean, boolean)} method for details.
*
* @author Igor Sereda
*/
public class SQLiteLongArray {
/**
* Controller (whether cached or uncached), used to return the instance.
*/
private SQLiteController myController;
/**
* Handle for native operations.
*/
private SWIGTYPE_p_intarray myHandle;
/**
* Virtual table name.
*/
private final String myName;
/**
* If true, the instance cannot be used.
*/
private volatile boolean myDisposed;
SQLiteLongArray(SQLiteController controller, SWIGTYPE_p_intarray handle, String name) {
assert controller != null;
assert handle != null;
assert name != null;
myController = controller;
myHandle = handle;
myName = name;
}
/**
* Returns the name of the virtual table, which should be used in SQL.
* <p/>
* This method is thread-safe.
*
* @return virtual table's name, not null
*/
public String getName() {
return myName;
}
/**
* Returns true if the instance is disposed and cannot be used. If the array was cached, it may still remain
* and be addressable through SQL, but it may contain no data or any irrelevant data (as defined by the current
* user of the instance).
*
* @return true if the instance is unusable
*/
public boolean isDisposed() {
return myDisposed;
}
@Override
public String toString() {
return myName;
}
/**
* Disposes this instance, making it unusable and freeing the resources. If the array table is cached,
* then it is unbound from values (emptied) and returned to the cache. If the array table is not cached,
* it is deleted from the database.
* <p/>
* This method is partially thread-safe. When called not from the confining thread, the exception will not be
* thrown, but the method will do nothing.
* <p/>
* Calling <code>dispose()</code> second time has no effect.
* <p/>
* Calling {@link #bind} after instance has been disposed would result in exception.
*/
public void dispose() {
if (myHandle == null)
return;
SQLiteController controller = myController;
try {
controller.validate();
} catch (SQLiteException e) {
Internal.recoverableError(this, "invalid dispose: " + e, true);
return;
}
Internal.logFine(this, "disposing");
controller.dispose(this);
myHandle = null;
myController = SQLiteController.getDisposed(myController);
myDisposed = true;
}
/**
* Fills virtual array table with values from the specified portion of a Java array.
* <p/>
* Values are copied into a native non-heap memory, so the array can be used for other purposes after
* calling this method.
* <p/>
* If <tt>ordered</tt> and <tt>unique</tt> are false, values need not to be unique or come in any specific order.
* If <tt>ordered</tt> is true, then the caller guarantees that the values come in ascending order. If <tt>unique</tt>
* is true, then the values are guaranteed to be unique. Failing those guarantees would result in incorrect search
* results.
* <p/>
* Passing ordered and/or unique values allows SQLite to optimize search and access to the array.
* <p/>
* Memory, allocated for the virtual array table, is freed on the next call to bind, when array instance
* is disposed, or when database is closed.
*
* @param values array of the values to bind, may be null if length == 0
* @param offset the index of an element to be bound as the first row
* @param length the number of values to bind, if set to 0 then the virtual array table will be empty
* @param ordered if true, the values within the specified by offset and length region are in non-strict ascending order
* @param unique if true, the values within the specified by offset and length region are not repeating
* @return this instance
* @throws SQLiteException if this instance has been disposed or problem occurs on the underlying layer
* @throws ArrayIndexOutOfBoundsException if offset and length do not specify a valid range within values array
* @throws NullPointerException if values is null and length is not zero
*/
public SQLiteLongArray bind(long[] values, int offset, int length, boolean ordered, boolean unique) throws SQLiteException {
if (offset < 0) throw new ArrayIndexOutOfBoundsException(offset);
if (length < 0) throw new ArrayIndexOutOfBoundsException(length);
if (length > 0 && offset + length > values.length) throw new ArrayIndexOutOfBoundsException(offset + length);
myController.validate();
if (Internal.isFineLogging())
Internal.logFine(this, "bind[" + length + "]");
int rc;
if (length == 0) {
rc = _SQLiteManual.sqlite3_intarray_unbind(handle());
} else {
if (values == null) throw new NullPointerException();
rc = _SQLiteManual.sqlite3_intarray_bind(handle(), values, offset, length, ordered, unique);
}
myController.throwResult(rc, "bind(array)", this);
return this;
}
/**
* Fills virtual array table with values from a Java array. This is a convenience method for {@link #bind(long[], int, int, boolean, boolean)}.
*
* @param values array of the values to bind, may be null if length == 0
* @param offset the index of an element to be bound as the first row
* @param length the number of values to bind, if set to 0 then the virtual array table will be empty
* @return this instance
* @throws SQLiteException if this instance has been disposed or problem occurs on the underlying layer
* @throws ArrayIndexOutOfBoundsException if offset and length do not specify a valid range within values array
* @throws NullPointerException if values is null and length is not zero
*/
public SQLiteLongArray bind(long[] values, int offset, int length) throws SQLiteException {
return bind(values, offset, length, false, false);
}
/**
* Fills virtual array table with values from a Java array. This is a convenience method for {@link #bind(long[], int, int, boolean, boolean)}.
*
* @param values array of the values to bind, if null - bind to an empty array
* @return this instance
* @throws SQLiteException if this instance has been disposed or problem occurs on the underlying layer
* @throws ArrayIndexOutOfBoundsException if offset and length do not specify a valid range within values array
*/
public SQLiteLongArray bind(long... values) throws SQLiteException {
return bind(values, 0, values == null ? 0 : values.length, false, false);
}
/**
* Fills virtual array table with values from a Java array. This is a convenience method for {@link #bind(long[], int, int, boolean, boolean)}.
*
* @param values array of the values to bind, if null - bind to an empty array
* @param ordered if true, the values within the specified by offset and length region are in non-strict ascending order
* @param unique if true, the values within the specified by offset and length region are not repeating
* @return this instance
* @throws SQLiteException if this instance has been disposed or problem occurs on the underlying layer
* @throws ArrayIndexOutOfBoundsException if offset and length do not specify a valid range within values array
*/
public SQLiteLongArray bind(long[] values, boolean ordered, boolean unique) throws SQLiteException {
return bind(values, 0, values == null ? 0 : values.length, ordered, unique);
}
private SWIGTYPE_p_intarray handle() throws SQLiteException {
SWIGTYPE_p_intarray handle = myHandle;
if (handle == null) {
throw new SQLiteException(WRAPPER_STATEMENT_DISPOSED, null);
}
return handle;
}
SWIGTYPE_p_intarray arrayHandle() {
return myHandle;
}
}