koffi 0.9.26 → 0.9.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +28 -28
- package/benchmark/CMakeLists.txt +15 -4
- package/benchmark/atoi_cc.cc +6 -9
- package/benchmark/atoi_koffi.js +10 -9
- package/benchmark/atoi_napi.cc +15 -9
- package/benchmark/atoi_napi.js +9 -8
- package/benchmark/atoi_node_ffi.js +9 -9
- package/benchmark/raylib_cc.cc +7 -10
- package/benchmark/raylib_koffi.js +11 -10
- package/benchmark/raylib_node_ffi.js +11 -10
- package/package.json +2 -2
- package/src/call_arm32.cc +2 -2
- package/src/call_arm32_fwd.S +12 -12
- package/src/ffi.cc +24 -11
- package/src/ffi.hh +1 -0
- package/src/util.cc +22 -11
- package/src/util.hh +6 -3
- package/test/CMakeLists.txt +4 -0
- package/test/registry/machines.json +10 -30
- package/test/tests/misc.c +47 -2
- package/test/tests/misc.js +56 -20
- package/test/tests/raylib.js +1 -1
- package/test/tests/sqlite.js +1 -1
- package/vendor/sqlite3/shell.c +31 -22
- package/vendor/sqlite3/sqlite3.c +329 -132
- package/vendor/sqlite3/sqlite3.h +10 -6
- package/benchmark/raylib_cc.exe +0 -0
package/src/util.hh
CHANGED
|
@@ -74,6 +74,7 @@ class CallData {
|
|
|
74
74
|
|
|
75
75
|
Span<uint8_t> *stack_mem;
|
|
76
76
|
Span<uint8_t> *heap_mem;
|
|
77
|
+
BlockAllocator big_alloc;
|
|
77
78
|
|
|
78
79
|
Span<uint8_t> old_stack_mem;
|
|
79
80
|
Span<uint8_t> old_heap_mem;
|
|
@@ -101,8 +102,8 @@ public:
|
|
|
101
102
|
|
|
102
103
|
template <typename T = void>
|
|
103
104
|
bool AllocStack(Size size, Size align, T **out_ptr = nullptr);
|
|
104
|
-
template <typename T>
|
|
105
|
-
bool AllocHeap(Size size, Size align, T **out_ptr);
|
|
105
|
+
template <typename T = void>
|
|
106
|
+
bool AllocHeap(Size size, Size align, T **out_ptr = nullptr);
|
|
106
107
|
|
|
107
108
|
const char *PushString(const Napi::Value &value);
|
|
108
109
|
bool PushObject(const Napi::Object &obj, const TypeInfo *type, uint8_t *dest);
|
|
@@ -151,7 +152,9 @@ bool CallData::AllocHeap(Size size, Size align, T **out_ptr)
|
|
|
151
152
|
heap_mem->ptr += delta;
|
|
152
153
|
heap_mem->len -= delta;
|
|
153
154
|
|
|
154
|
-
|
|
155
|
+
if (out_ptr) {
|
|
156
|
+
*out_ptr = (T *)ptr;
|
|
157
|
+
}
|
|
155
158
|
return true;
|
|
156
159
|
}
|
|
157
160
|
|
package/test/CMakeLists.txt
CHANGED
|
@@ -25,9 +25,7 @@
|
|
|
25
25
|
"Linux ARM32": {
|
|
26
26
|
"directory": "/home/debian/luigi",
|
|
27
27
|
"build": {
|
|
28
|
-
"
|
|
29
|
-
"Build Koffi": "node ../cnoke/cnoke.js",
|
|
30
|
-
"Build dependencies": "node ../cnoke/cnoke.js -C test"
|
|
28
|
+
"Build": "node ../cnoke/cnoke.js -C test"
|
|
31
29
|
},
|
|
32
30
|
"commands": {
|
|
33
31
|
"Test Raylib": "xvfb-run node test/tests/raylib.js",
|
|
@@ -64,9 +62,7 @@
|
|
|
64
62
|
"Linux ARM64": {
|
|
65
63
|
"directory": "/home/debian/luigi",
|
|
66
64
|
"build": {
|
|
67
|
-
"
|
|
68
|
-
"Build Koffi": "node ../cnoke/cnoke.js",
|
|
69
|
-
"Build dependencies": "node ../cnoke/cnoke.js -C test"
|
|
65
|
+
"Build": "node ../cnoke/cnoke.js -C test"
|
|
70
66
|
},
|
|
71
67
|
"commands": {
|
|
72
68
|
"Test Raylib": "xvfb-run node test/tests/raylib.js",
|
|
@@ -103,9 +99,7 @@
|
|
|
103
99
|
"Linux i386": {
|
|
104
100
|
"directory": "/home/debian/luigi",
|
|
105
101
|
"build": {
|
|
106
|
-
"
|
|
107
|
-
"Build Koffi": "node ../cnoke/cnoke.js",
|
|
108
|
-
"Build dependencies": "node ../cnoke/cnoke.js -C test"
|
|
102
|
+
"Build": "node ../cnoke/cnoke.js -C test"
|
|
109
103
|
},
|
|
110
104
|
"commands": {
|
|
111
105
|
"Test Raylib": "xvfb-run node test/tests/raylib.js",
|
|
@@ -142,9 +136,7 @@
|
|
|
142
136
|
"Linux x64": {
|
|
143
137
|
"directory": "/home/debian/luigi",
|
|
144
138
|
"build": {
|
|
145
|
-
"
|
|
146
|
-
"Build Koffi": "node ../cnoke/cnoke.js",
|
|
147
|
-
"Build dependencies": "node ../cnoke/cnoke.js -C test"
|
|
139
|
+
"Build": "node ../cnoke/cnoke.js -C test"
|
|
148
140
|
},
|
|
149
141
|
"commands": {
|
|
150
142
|
"Test Raylib": "xvfb-run node test/tests/raylib.js",
|
|
@@ -181,9 +173,7 @@
|
|
|
181
173
|
"Windows i386": {
|
|
182
174
|
"directory": "C:/Users/windows/Desktop/luigi32",
|
|
183
175
|
"build": {
|
|
184
|
-
"
|
|
185
|
-
"Build Koffi": "C:\\Node32\\node32.cmd node ../cnoke/cnoke.js",
|
|
186
|
-
"Build dependencies": "C:\\Node32\\node32.cmd node ../cnoke/cnoke.js -C test"
|
|
176
|
+
"Build": "C:\\Node32\\node32.cmd node ../cnoke/cnoke.js -C test"
|
|
187
177
|
},
|
|
188
178
|
"commands": {
|
|
189
179
|
"Test Raylib": "seatsh C:\\Node32\\node32.cmd node test/tests/raylib.js",
|
|
@@ -195,9 +185,7 @@
|
|
|
195
185
|
"Windows x64": {
|
|
196
186
|
"directory": "C:/Users/windows/Desktop/luigi64",
|
|
197
187
|
"build": {
|
|
198
|
-
"
|
|
199
|
-
"Build Koffi": "C:\\Node64\\node64.cmd node ../cnoke/cnoke.js",
|
|
200
|
-
"Build dependencies": "C:\\Node64\\node64.cmd node ../cnoke/cnoke.js -C test"
|
|
188
|
+
"Build": "C:\\Node64\\node64.cmd node ../cnoke/cnoke.js -C test"
|
|
201
189
|
},
|
|
202
190
|
"commands": {
|
|
203
191
|
"Test Raylib": "seatsh C:\\Node64\\node64.cmd node test/tests/raylib.js",
|
|
@@ -234,9 +222,7 @@
|
|
|
234
222
|
"FreeBSD x64": {
|
|
235
223
|
"directory": "/home/freebsd/luigi",
|
|
236
224
|
"build": {
|
|
237
|
-
"
|
|
238
|
-
"Build Koffi": "node ../cnoke/cnoke.js",
|
|
239
|
-
"Build dependencies": "node ../cnoke/cnoke.js -C test"
|
|
225
|
+
"Build": "node ../cnoke/cnoke.js -C test"
|
|
240
226
|
},
|
|
241
227
|
"commands": {
|
|
242
228
|
"Test Raylib": "xvfb-run node test/tests/raylib.js",
|
|
@@ -273,9 +259,7 @@
|
|
|
273
259
|
"FreeBSD i386": {
|
|
274
260
|
"directory": "/home/freebsd/luigi",
|
|
275
261
|
"build": {
|
|
276
|
-
"
|
|
277
|
-
"Build Koffi": "node ../cnoke/cnoke.js",
|
|
278
|
-
"Build dependencies": "node ../cnoke/cnoke.js -C test"
|
|
262
|
+
"Build": "node ../cnoke/cnoke.js -C test"
|
|
279
263
|
},
|
|
280
264
|
"commands": {
|
|
281
265
|
"Test Raylib": "xvfb-run node test/tests/raylib.js",
|
|
@@ -312,9 +296,7 @@
|
|
|
312
296
|
"FreeBSD ARM64": {
|
|
313
297
|
"directory": "/home/freebsd/luigi",
|
|
314
298
|
"build": {
|
|
315
|
-
"
|
|
316
|
-
"Build Koffi": "node ../cnoke/cnoke.js",
|
|
317
|
-
"Build dependencies": "node ../cnoke/cnoke.js -C test"
|
|
299
|
+
"Build": "node ../cnoke/cnoke.js -C test"
|
|
318
300
|
},
|
|
319
301
|
"commands": {
|
|
320
302
|
"Test Raylib": "xvfb-run node test/tests/raylib.js",
|
|
@@ -351,9 +333,7 @@
|
|
|
351
333
|
"macOS x64": {
|
|
352
334
|
"directory": "/Users/macos/luigi",
|
|
353
335
|
"build": {
|
|
354
|
-
"
|
|
355
|
-
"Build Koffi": "PATH=/usr/local/bin:/usr/bin:/bin SDKROOT=/Library/Developer/CommandLineTools/SDKs/MacOSX11.3.sdk node ../cnoke/cnoke.js",
|
|
356
|
-
"Build dependencies": "PATH=/usr/local/bin:/usr/bin:/bin SDKROOT=/Library/Developer/CommandLineTools/SDKs/MacOSX11.3.sdk node ../cnoke/cnoke.js -C test"
|
|
336
|
+
"Build": "PATH=/usr/local/bin:/usr/bin:/bin SDKROOT=/Library/Developer/CommandLineTools/SDKs/MacOSX11.3.sdk node ../cnoke/cnoke.js -C test"
|
|
357
337
|
},
|
|
358
338
|
"commands": {
|
|
359
339
|
"Test Misc": "PATH=/usr/local/bin:/usr/bin:/bin node test/tests/misc.js",
|
package/test/tests/misc.c
CHANGED
|
@@ -53,6 +53,19 @@ typedef struct BFG {
|
|
|
53
53
|
double g;
|
|
54
54
|
} inner;
|
|
55
55
|
} BFG;
|
|
56
|
+
#pragma pack(push, 1)
|
|
57
|
+
typedef struct PackedBFG {
|
|
58
|
+
int8_t a;
|
|
59
|
+
int64_t b;
|
|
60
|
+
signed char c;
|
|
61
|
+
const char *d;
|
|
62
|
+
short e;
|
|
63
|
+
struct {
|
|
64
|
+
float f;
|
|
65
|
+
double g;
|
|
66
|
+
} inner;
|
|
67
|
+
} PackedBFG;
|
|
68
|
+
#pragma pack(pop)
|
|
56
69
|
|
|
57
70
|
EXPORT void FillPack3(int a, int b, int c, Pack3 *p)
|
|
58
71
|
{
|
|
@@ -135,14 +148,36 @@ EXPORT const char *ConcatenateToStr8(int64_t a, int64_t b, int64_t c, int64_t d,
|
|
|
135
148
|
return buf;
|
|
136
149
|
}
|
|
137
150
|
|
|
138
|
-
EXPORT BFG STDCALL MakeBFG(int x, double y,
|
|
151
|
+
EXPORT BFG STDCALL MakeBFG(BFG *p, int x, double y, const char *str)
|
|
139
152
|
{
|
|
140
153
|
BFG bfg;
|
|
141
154
|
|
|
155
|
+
char buf[64];
|
|
156
|
+
snprintf(buf, sizeof(buf), "X/%s/X", str);
|
|
157
|
+
|
|
158
|
+
bfg.a = x;
|
|
159
|
+
bfg.b = x * 2;
|
|
160
|
+
bfg.c = x - 27;
|
|
161
|
+
bfg.d = buf;
|
|
162
|
+
bfg.e = x * 27;
|
|
163
|
+
bfg.inner.f = (float)y * x;
|
|
164
|
+
bfg.inner.g = (double)y - x;
|
|
165
|
+
*p = bfg;
|
|
166
|
+
|
|
167
|
+
return bfg;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
EXPORT PackedBFG FASTCALL MakePackedBFG(int x, double y, PackedBFG *p, const char *str)
|
|
171
|
+
{
|
|
172
|
+
PackedBFG bfg;
|
|
173
|
+
|
|
174
|
+
char buf[64];
|
|
175
|
+
snprintf(buf, sizeof(buf), "X/%s/X", str);
|
|
176
|
+
|
|
142
177
|
bfg.a = x;
|
|
143
178
|
bfg.b = x * 2;
|
|
144
179
|
bfg.c = x - 27;
|
|
145
|
-
bfg.d =
|
|
180
|
+
bfg.d = buf;
|
|
146
181
|
bfg.e = x * 27;
|
|
147
182
|
bfg.inner.f = (float)y * x;
|
|
148
183
|
bfg.inner.g = (double)y - x;
|
|
@@ -150,3 +185,13 @@ EXPORT BFG STDCALL MakeBFG(int x, double y, BFG *p)
|
|
|
150
185
|
|
|
151
186
|
return bfg;
|
|
152
187
|
}
|
|
188
|
+
|
|
189
|
+
EXPORT const char *ReturnBigString(const char *str)
|
|
190
|
+
{
|
|
191
|
+
static char buf[1 * 1024 * 1024];
|
|
192
|
+
|
|
193
|
+
size_t len = strlen(str);
|
|
194
|
+
memcpy(buf, str, len + 1);
|
|
195
|
+
|
|
196
|
+
return buf;
|
|
197
|
+
}
|
package/test/tests/misc.js
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
// You should have received a copy of the GNU Affero General Public License
|
|
14
14
|
// along with this program. If not, see https://www.gnu.org/licenses/.
|
|
15
15
|
|
|
16
|
-
const koffi = require('
|
|
16
|
+
const koffi = require('../build/koffi.node');
|
|
17
17
|
const assert = require('assert');
|
|
18
18
|
const path = require('path');
|
|
19
19
|
|
|
@@ -29,7 +29,18 @@ const BFG = koffi.struct('BFG', {
|
|
|
29
29
|
c: 'char',
|
|
30
30
|
d: 'string',
|
|
31
31
|
e: 'short',
|
|
32
|
-
inner: koffi.struct(
|
|
32
|
+
inner: koffi.struct({
|
|
33
|
+
f: 'float',
|
|
34
|
+
g: 'double'
|
|
35
|
+
})
|
|
36
|
+
});
|
|
37
|
+
const PackedBFG = koffi.pack('PackedBFG', {
|
|
38
|
+
a: 'int8_t',
|
|
39
|
+
b: 'int64_t',
|
|
40
|
+
c: 'char',
|
|
41
|
+
d: 'string',
|
|
42
|
+
e: 'short',
|
|
43
|
+
inner: koffi.pack({
|
|
33
44
|
f: 'float',
|
|
34
45
|
g: 'double'
|
|
35
46
|
})
|
|
@@ -60,28 +71,53 @@ async function test() {
|
|
|
60
71
|
const ConcatenateToStr1 = lib.cdecl('ConcatenateToStr1', 'string', [...Array(8).fill('int8_t'), koffi.struct('IJK1', {i: 'int8_t', j: 'int8_t', k: 'int8_t'}), 'int8_t']);
|
|
61
72
|
const ConcatenateToStr4 = lib.cdecl('ConcatenateToStr4', 'string', [...Array(8).fill('int32_t'), koffi.pointer(koffi.struct('IJK4', {i: 'int32_t', j: 'int32_t', k: 'int32_t'})), 'int32_t']);
|
|
62
73
|
const ConcatenateToStr8 = lib.cdecl('ConcatenateToStr8', 'string', [...Array(8).fill('int64_t'), koffi.struct('IJK8', {i: 'int64_t', j: 'int64_t', k: 'int64_t'}), 'int64_t']);
|
|
63
|
-
const MakeBFG = lib.stdcall('MakeBFG', BFG, [
|
|
74
|
+
const MakeBFG = lib.stdcall('MakeBFG', BFG, [koffi.out(koffi.pointer(BFG)), 'int', 'double', 'string']);
|
|
75
|
+
const MakePackedBFG = lib.stdcall('MakePackedBFG', PackedBFG, ['int', 'double', koffi.out(koffi.pointer(PackedBFG)), 'string']);
|
|
76
|
+
const ReturnBigString = lib.stdcall('ReturnBigString', 'string', ['string']);
|
|
77
|
+
|
|
78
|
+
// Simple tests
|
|
79
|
+
{
|
|
80
|
+
let p = {};
|
|
64
81
|
|
|
65
|
-
|
|
82
|
+
FillPack3(1, 2, 3, p);
|
|
83
|
+
assert.deepEqual(p, { a: 1, b: 2, c: 3 });
|
|
66
84
|
|
|
67
|
-
|
|
68
|
-
|
|
85
|
+
let q = RetPack3(6, 9, -12);
|
|
86
|
+
assert.deepEqual(q, { a: 6, b: 9, c: -12 });
|
|
87
|
+
|
|
88
|
+
AddPack3(6, 9, -12, p);
|
|
89
|
+
assert.deepEqual(p, { a: 7, b: 11, c: -9 });
|
|
90
|
+
}
|
|
69
91
|
|
|
70
|
-
|
|
71
|
-
|
|
92
|
+
// Many parameters
|
|
93
|
+
{
|
|
94
|
+
assert.equal(ConcatenateToInt1(5, 6, 1, 2, 3, 9, 4, 4, 0, 6, 8, 7), 561239440687n);
|
|
95
|
+
assert.equal(ConcatenateToInt4(5, 6, 1, 2, 3, 9, 4, 4, 0, 6, 8, 7), 561239440687n);
|
|
96
|
+
assert.equal(ConcatenateToInt8(5, 6, 1, 2, 3, 9, 4, 4, 0, 6, 8, 7), 561239440687n);
|
|
97
|
+
assert.equal(ConcatenateToStr1(5, 6, 1, 2, 3, 9, 4, 4, {i: 0, j: 6, k: 8}, 7), '561239440687');
|
|
98
|
+
assert.equal(ConcatenateToStr4(5, 6, 1, 2, 3, 9, 4, 4, {i: 0, j: 6, k: 8}, 7), '561239440687');
|
|
99
|
+
assert.equal(ConcatenateToStr8(5, 6, 1, 2, 3, 9, 4, 4, {i: 0, j: 6, k: 8}, 7), '561239440687');
|
|
100
|
+
}
|
|
72
101
|
|
|
73
|
-
|
|
74
|
-
|
|
102
|
+
// Big struct
|
|
103
|
+
{
|
|
104
|
+
let out = {};
|
|
105
|
+
let bfg = MakeBFG(out, 2, 7, '__Hello123456789++++foobarFOOBAR!__');
|
|
106
|
+
assert.deepEqual(bfg, { a: 2, b: 4, c: -25, d: 'X/__Hello123456789++++foobarFOOBAR!__/X', e: 54, inner: { f: 14, g: 5 } });
|
|
107
|
+
assert.deepEqual(out, bfg);
|
|
108
|
+
}
|
|
75
109
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
110
|
+
// Packed struct
|
|
111
|
+
{
|
|
112
|
+
let out = {};
|
|
113
|
+
let bfg = MakePackedBFG(2, 7, out, '__Hello123456789++++foobarFOOBAR!__');
|
|
114
|
+
assert.deepEqual(bfg, { a: 2, b: 4, c: -25, d: 'X/__Hello123456789++++foobarFOOBAR!__/X', e: 54, inner: { f: 14, g: 5 } });
|
|
115
|
+
assert.deepEqual(out, bfg);
|
|
116
|
+
}
|
|
82
117
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
118
|
+
// Big string
|
|
119
|
+
{
|
|
120
|
+
let str = 'fooBAR!'.repeat(1024 * 1024);
|
|
121
|
+
assert.equal(ReturnBigString(str), str);
|
|
122
|
+
}
|
|
87
123
|
}
|
package/test/tests/raylib.js
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
// You should have received a copy of the GNU Affero General Public License
|
|
14
14
|
// along with this program. If not, see https://www.gnu.org/licenses/.
|
|
15
15
|
|
|
16
|
-
const koffi = require('
|
|
16
|
+
const koffi = require('../build/koffi.node');
|
|
17
17
|
const crypto = require('crypto');
|
|
18
18
|
const fs = require('fs');
|
|
19
19
|
const os = require('os');
|
package/test/tests/sqlite.js
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
// along with this program. If not, see https://www.gnu.org/licenses/.
|
|
15
15
|
|
|
16
16
|
const crypto = require('crypto');
|
|
17
|
-
const koffi = require('
|
|
17
|
+
const koffi = require('../build/koffi.node');
|
|
18
18
|
const assert = require('assert');
|
|
19
19
|
const fs = require('fs');
|
|
20
20
|
const os = require('os');
|
package/vendor/sqlite3/shell.c
CHANGED
|
@@ -7964,9 +7964,14 @@ static int zipfileFilter(
|
|
|
7964
7964
|
zipfileCursorErr(pCsr, "zipfile() function requires an argument");
|
|
7965
7965
|
return SQLITE_ERROR;
|
|
7966
7966
|
}else if( sqlite3_value_type(argv[0])==SQLITE_BLOB ){
|
|
7967
|
+
static const u8 aEmptyBlob = 0;
|
|
7967
7968
|
const u8 *aBlob = (const u8*)sqlite3_value_blob(argv[0]);
|
|
7968
7969
|
int nBlob = sqlite3_value_bytes(argv[0]);
|
|
7969
7970
|
assert( pTab->pFirstEntry==0 );
|
|
7971
|
+
if( aBlob==0 ){
|
|
7972
|
+
aBlob = &aEmptyBlob;
|
|
7973
|
+
nBlob = 0;
|
|
7974
|
+
}
|
|
7970
7975
|
rc = zipfileLoadDirectory(pTab, aBlob, nBlob);
|
|
7971
7976
|
pCsr->pFreeEntry = pTab->pFirstEntry;
|
|
7972
7977
|
pTab->pFirstEntry = pTab->pLastEntry = 0;
|
|
@@ -19906,7 +19911,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
|
|
19906
19911
|
|
|
19907
19912
|
if( c=='i' && strncmp(azArg[0], "import", n)==0 ){
|
|
19908
19913
|
char *zTable = 0; /* Insert data into this table */
|
|
19909
|
-
char *zSchema =
|
|
19914
|
+
char *zSchema = 0; /* within this schema (may default to "main") */
|
|
19910
19915
|
char *zFile = 0; /* Name of file to extra content from */
|
|
19911
19916
|
sqlite3_stmt *pStmt = NULL; /* A statement */
|
|
19912
19917
|
int nCol; /* Number of columns in the table */
|
|
@@ -19915,11 +19920,13 @@ static int do_meta_command(char *zLine, ShellState *p){
|
|
|
19915
19920
|
int needCommit; /* True to COMMIT or ROLLBACK at end */
|
|
19916
19921
|
int nSep; /* Number of bytes in p->colSeparator[] */
|
|
19917
19922
|
char *zSql; /* An SQL statement */
|
|
19923
|
+
char *zFullTabName; /* Table name with schema if applicable */
|
|
19918
19924
|
ImportCtx sCtx; /* Reader context */
|
|
19919
19925
|
char *(SQLITE_CDECL *xRead)(ImportCtx*); /* Func to read one value */
|
|
19920
19926
|
int eVerbose = 0; /* Larger for more console output */
|
|
19921
19927
|
int nSkip = 0; /* Initial lines to skip */
|
|
19922
19928
|
int useOutputMode = 1; /* Use output mode to determine separators */
|
|
19929
|
+
char *zCreate = 0; /* CREATE TABLE statement text */
|
|
19923
19930
|
|
|
19924
19931
|
failIfSafeMode(p, "cannot run .import in safe mode");
|
|
19925
19932
|
memset(&sCtx, 0, sizeof(sCtx));
|
|
@@ -20042,7 +20049,6 @@ static int do_meta_command(char *zLine, ShellState *p){
|
|
|
20042
20049
|
import_cleanup(&sCtx);
|
|
20043
20050
|
goto meta_command_exit;
|
|
20044
20051
|
}
|
|
20045
|
-
/* Below, resources must be freed before exit. */
|
|
20046
20052
|
if( eVerbose>=2 || (eVerbose>=1 && useOutputMode) ){
|
|
20047
20053
|
char zSep[2];
|
|
20048
20054
|
zSep[1] = 0;
|
|
@@ -20054,11 +20060,17 @@ static int do_meta_command(char *zLine, ShellState *p){
|
|
|
20054
20060
|
output_c_string(p->out, zSep);
|
|
20055
20061
|
utf8_printf(p->out, "\n");
|
|
20056
20062
|
}
|
|
20063
|
+
/* Below, resources must be freed before exit. */
|
|
20057
20064
|
while( (nSkip--)>0 ){
|
|
20058
20065
|
while( xRead(&sCtx) && sCtx.cTerm==sCtx.cColSep ){}
|
|
20059
20066
|
}
|
|
20060
|
-
|
|
20061
|
-
|
|
20067
|
+
if( zSchema!=0 ){
|
|
20068
|
+
zFullTabName = sqlite3_mprintf("\"%w\".\"%w\"", zSchema, zTable);
|
|
20069
|
+
}else{
|
|
20070
|
+
zFullTabName = sqlite3_mprintf("\"%w\"", zTable);
|
|
20071
|
+
}
|
|
20072
|
+
zSql = sqlite3_mprintf("SELECT * FROM %s", zFullTabName);
|
|
20073
|
+
if( zSql==0 || zFullTabName==0 ){
|
|
20062
20074
|
import_cleanup(&sCtx);
|
|
20063
20075
|
shell_out_of_memory();
|
|
20064
20076
|
}
|
|
@@ -20066,11 +20078,10 @@ static int do_meta_command(char *zLine, ShellState *p){
|
|
|
20066
20078
|
rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
|
|
20067
20079
|
import_append_char(&sCtx, 0); /* To ensure sCtx.z is allocated */
|
|
20068
20080
|
if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(p->db))==0 ){
|
|
20069
|
-
char *zCreate = sqlite3_mprintf("CREATE TABLE \"%w\".\"%w\"",
|
|
20070
|
-
zSchema, zTable);
|
|
20071
20081
|
sqlite3 *dbCols = 0;
|
|
20072
20082
|
char *zRenames = 0;
|
|
20073
20083
|
char *zColDefs;
|
|
20084
|
+
zCreate = sqlite3_mprintf("CREATE TABLE %s", zFullTabName);
|
|
20074
20085
|
while( xRead(&sCtx) ){
|
|
20075
20086
|
zAutoColumn(sCtx.z, &dbCols, 0);
|
|
20076
20087
|
if( sCtx.cTerm!=sCtx.cColSep ) break;
|
|
@@ -20084,9 +20095,12 @@ static int do_meta_command(char *zLine, ShellState *p){
|
|
|
20084
20095
|
}
|
|
20085
20096
|
assert(dbCols==0);
|
|
20086
20097
|
if( zColDefs==0 ){
|
|
20098
|
+
utf8_printf(stderr,"%s: empty file\n", sCtx.zFile);
|
|
20099
|
+
import_fail:
|
|
20087
20100
|
sqlite3_free(zCreate);
|
|
20101
|
+
sqlite3_free(zSql);
|
|
20102
|
+
sqlite3_free(zFullTabName);
|
|
20088
20103
|
import_cleanup(&sCtx);
|
|
20089
|
-
utf8_printf(stderr,"%s: empty file\n", sCtx.zFile);
|
|
20090
20104
|
rc = 1;
|
|
20091
20105
|
goto meta_command_exit;
|
|
20092
20106
|
}
|
|
@@ -20097,22 +20111,18 @@ static int do_meta_command(char *zLine, ShellState *p){
|
|
|
20097
20111
|
rc = sqlite3_exec(p->db, zCreate, 0, 0, 0);
|
|
20098
20112
|
if( rc ){
|
|
20099
20113
|
utf8_printf(stderr, "%s failed:\n%s\n", zCreate, sqlite3_errmsg(p->db));
|
|
20100
|
-
|
|
20101
|
-
import_cleanup(&sCtx);
|
|
20102
|
-
rc = 1;
|
|
20103
|
-
goto meta_command_exit;
|
|
20114
|
+
goto import_fail;
|
|
20104
20115
|
}
|
|
20105
20116
|
sqlite3_free(zCreate);
|
|
20117
|
+
zCreate = 0;
|
|
20106
20118
|
rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
|
|
20107
20119
|
}
|
|
20108
|
-
sqlite3_free(zSql);
|
|
20109
20120
|
if( rc ){
|
|
20110
20121
|
if (pStmt) sqlite3_finalize(pStmt);
|
|
20111
20122
|
utf8_printf(stderr,"Error: %s\n", sqlite3_errmsg(p->db));
|
|
20112
|
-
|
|
20113
|
-
rc = 1;
|
|
20114
|
-
goto meta_command_exit;
|
|
20123
|
+
goto import_fail;
|
|
20115
20124
|
}
|
|
20125
|
+
sqlite3_free(zSql);
|
|
20116
20126
|
nCol = sqlite3_column_count(pStmt);
|
|
20117
20127
|
sqlite3_finalize(pStmt);
|
|
20118
20128
|
pStmt = 0;
|
|
@@ -20122,8 +20132,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
|
|
20122
20132
|
import_cleanup(&sCtx);
|
|
20123
20133
|
shell_out_of_memory();
|
|
20124
20134
|
}
|
|
20125
|
-
sqlite3_snprintf(nByte+20, zSql, "INSERT INTO
|
|
20126
|
-
zSchema, zTable);
|
|
20135
|
+
sqlite3_snprintf(nByte+20, zSql, "INSERT INTO %s VALUES(?", zFullTabName);
|
|
20127
20136
|
j = strlen30(zSql);
|
|
20128
20137
|
for(i=1; i<nCol; i++){
|
|
20129
20138
|
zSql[j++] = ',';
|
|
@@ -20135,14 +20144,13 @@ static int do_meta_command(char *zLine, ShellState *p){
|
|
|
20135
20144
|
utf8_printf(p->out, "Insert using: %s\n", zSql);
|
|
20136
20145
|
}
|
|
20137
20146
|
rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
|
|
20138
|
-
sqlite3_free(zSql);
|
|
20139
20147
|
if( rc ){
|
|
20140
20148
|
utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
|
|
20141
20149
|
if (pStmt) sqlite3_finalize(pStmt);
|
|
20142
|
-
|
|
20143
|
-
rc = 1;
|
|
20144
|
-
goto meta_command_exit;
|
|
20150
|
+
goto import_fail;
|
|
20145
20151
|
}
|
|
20152
|
+
sqlite3_free(zSql);
|
|
20153
|
+
sqlite3_free(zFullTabName);
|
|
20146
20154
|
needCommit = sqlite3_get_autocommit(p->db);
|
|
20147
20155
|
if( needCommit ) sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
|
|
20148
20156
|
do{
|
|
@@ -22636,7 +22644,8 @@ static int process_input(ShellState *p){
|
|
|
22636
22644
|
qss = QSS_Start;
|
|
22637
22645
|
}
|
|
22638
22646
|
}
|
|
22639
|
-
if( nSql
|
|
22647
|
+
if( nSql ){
|
|
22648
|
+
/* This may be incomplete. Let the SQL parser deal with that. */
|
|
22640
22649
|
errCnt += runOneSqlLine(p, zSql, p->in, startline);
|
|
22641
22650
|
}
|
|
22642
22651
|
free(zSql);
|