Hang on `SELECT * FROM table` on iOS, if table is empty
bgohsman opened this issue · 1 comments
- Make sure to check the demo app(s) for sample usage
- Make sure to check the existing issues in this repository
- If the demo apps cannot help and there is no issue for your problem, tell us about it. Please, ensure your title is less than 63 characters long and starts with a capital
letter.
Which platform(s) does your issue occur on?
- iOS/Android/Both
- iOS/Android versions
- emulator or device. What type of device?
Please, provide the following version numbers that your issue occurs with:
- CLI: 6.5.0
- Cross-platform modules: 6.5.0
- Runtime(s): 6.5.0
- Plugin(s):
"dependencies": {
"@nativescript/theme": "^2.2.1",
"axios": "^0.19.1",
"binary-parser": "^1.5.0",
"ml-regression": "^5.0.0",
"nativescript-app-environment": "^1.0.0",
"nativescript-audio": "^5.0.5",
"nativescript-bluetooth": "^3.0.0-beta.10",
"nativescript-fancyalert": "^3.0.9",
"nativescript-geolocation": "^5.1.0",
"nativescript-iqkeyboardmanager": "^1.5.1",
"nativescript-permissions": "^1.3.8",
"nativescript-picker": "^2.1.2",
"nativescript-socketio": "^3.3.1",
"nativescript-sqlite-access": "^1.0.3",
"nativescript-toasty": "^2.0.1",
"nativescript-ui-gauge": "^6.0.0",
"nativescript-ui-listview": "^8.0.1",
"nativescript-vue": "^2.4.0",
"tns-core-modules": "^6.5.0",
"vuex": "^3.1.2"
}
"devDependencies": {
"@babel/core": "^7.7.5",
"@babel/preset-env": "^7.7.6",
"@types/binary-parser": "^1.3.1",
"@types/node": "^12.12.16",
"@typescript-eslint/eslint-plugin": "^2.10.0",
"@typescript-eslint/parser": "^2.10.0",
"babel-loader": "^8.0.6",
"eslint": "^6.7.2",
"eslint-config-prettier": "^6.7.0",
"eslint-loader": "^3.0.2",
"eslint-plugin-prettier": "^3.1.1",
"eslint-plugin-react": "^7.17.0",
"eslint-plugin-react-hooks": "^2.3.0",
"eslint-plugin-vue": "^6.0.1",
"nativescript-dev-webpack": "^1.4.0",
"nativescript-vue-template-compiler": "^2.4.0",
"nativescript-worker-loader": "~0.10.0",
"node-sass": "^4.13.1",
"prettier": "^1.19.1",
"tns-platform-declarations": "^6.5.0",
"typescript": "3.7.3",
"vue": "^2.6.11",
"vue-eslint-parser": "^7.0.0",
"vue-loader": "^15.8.3"
}
Please, tell us how to recreate the issue in as much detail as possible.
Describe the steps to reproduce it.
- In the demo app, call the
reload()
method prior to inserting any records in the table - Build/run for iOS (emulator or device) and the app will appear to hang
Is there any code involved?
I tracked this issue to the do/while
loop within __processCursor()
in sqlite-access.ios.js
on line#111.
function __processCursor(cursorRef, returnType, reduceFn) {
var result = reduceFn && {} || [];
do {
if (reduceFn) {
result = reduceFn(result, __getRowValues(cursorRef, returnType));
continue;
}
result.push(__getRowValues(cursorRef, returnType));
} while (sqlite3_step(cursorRef) !== 101);
sqlite3_finalize(cursorRef);
return result;
}
With no records in the table, __getRowValues()
will still return an object where every column has null
values. That object gets pushed into result[]
and while
checks the outcome of sqlite3_step(cursorRef)
for a value of 101. However, the value is 21 (SQLITE_MISUSE). So the do/while
infinitely pushes empty objects into result[]
and __processCursor()
never returns.
Potential Solution
SQLite has a lot of return types. Checking for all of them would be a bit of a nightmare. But perhaps checking for the most common failure points would be good here. 21 is a bit of an outlier as it only throws a log warning and doesn't halt execution, so things just keep running until you run out of system resources. It's such a soft/quiet warning that it took a while to even know it was happening. I couldn't even see the log warnings until I built/ran the app from directly within Xcode. The NativeScript debugger doesn't show them.
Interim Workaround
In the mean time, I wrapped the call to reload()
, in my code, with an initial call to get the number of records in the table:
select('SELECT COUNT(ALL) from mytable', null)
If the count is zero, I don't proceed. If there are 1 or more records, then I know it is safe to select all.
This issue was fixed in the version v1.0.4 and v1.05.