better-sqlite3 : I get undefined instead of the default values of the table - sqlite

I expected to see the default of values set for the table, but I get undefined
This is the code:
import Database from 'better-sqlite3-multiple-ciphers'
// https://gist.github.com/anhdiepmmk/b8dcd1c7be8c09580f607ef186529192
// https://www.sqlite.org/quirks.html#no_separate_boolean_datatype
// https://www.sqlite.org/stricttables.html#strict_tables
const commandToCreateJitsiSettingsTable = `
CREATE TABLE IF NOT EXISTS jitsiTable (
id INTEGER PRIMARY KEY AUTOINCREMENT,
alwaysOnTopWindowEnable INTEGER NOT NULL DEFAULT 1,
disableAGC INTEGER NOT NULL DEFAULT 0,
serverURL TEXT,
serverTimeout REAL DEFAULT undefined,
created_at timestamp NOT NULL DEFAULT current_timestamp,
updated_at timestamp NOT NULL DEFAULT current_timestamp
)
`
if (!fs.existsSync(path.join(settingsUserDataFolder, "Settings.db")) {
const SettingsDB = new Database(path.join(settingsUserDataFolder,"Settings.db"), {})
SettingsDB.pragma('journal_mode = WAL')
SettingsDB.pragma("rekey='secret-key'");
SettingsDB.exec(commandToCreateJitsiSettingsTable)
SettingsDB.close();
} else {
console.log("Settings.db already exists")
const SettingsDB = require('better-sqlite3-multiple-ciphers')(path.join(settingsUserDataFolder,"Settings.db"), {})
SettingsDB.pragma("key='secret-key'");
const row = SettingsDB.prepare("SELECT * FROM jitsiTable");
console.log(row.alwaysOnTopWindowEnable, row.disableAGC, row.serverURL, row.serverTimeout, row.created_at, row.updated_at)
SettingsDB.close();
}
Output:
Settings.db already exists
undefined undefined undefined undefined undefined undefined
How to correctly set and then get the default values in the table?

You have prepared the statement but have not retrieved any data. You set the row variable to a prepared statement, not data. You need to use one of these methods, such as .get() or .all() depending on your needs on the prepared statement to retrieve the data. In your case, probably .get(). See the API docs for details.
For example, you could replace these lines
const row = SettingsDB.prepare("SELECT * FROM jitsiTable");
console.log(row.alwaysOnTopWindowEnable, row.disableAGC, row.serverURL, row.serverTimeout, row.created_at, row.updated_at)
with
const stmt = SettingsDB.prepare("SELECT * FROM jitsiTable");
for (const row of stmt.iterate()) {
console.log(row.alwaysOnTopWindowEnable, row.disableAGC, row.serverURL, row.serverTimeout, row.created_at, row.updated_at)
}

Thanks to #PChemGuy and to a kind guy of better-sqlite3 repo I realized that insert operation was missing :
const SettingsDB = require('better-sqlite3-multiple-ciphers')
(path.join(settingsUserDataFolder,"Settings.db"), {})
SettingsDB.pragma("key='secret-key'");
const insert = SettingsDB.prepare('INSERT INTO jitsiTable
(alwaysOnTopWindowEnable, disableAGC, serverTimeout) VALUES (?, ?, ?)');
const row = SettingsDB.prepare("SELECT * FROM jitsiTable").get();
console.log(row.alwaysOnTopWindowEnable, row.disableAGC, row.serverURL,
row.serverTimeout, row.created_at, row.updated_at)
Output:
0 1 null 30 2022-12-10 11:00:22 2022-12-10 11:00:22
iterate() is for getting all the insertions so far:
const SettingsDB = require('better-sqlite3-multiple-ciphers')
(path.join(settingsUserDataFolder,"Settings.db"), {})
SettingsDB.pragma("key='secret-key'");
const insert = SettingsDB.prepare('INSERT INTO jitsiTable
(alwaysOnTopWindowEnable, disableAGC, serverTimeout) VALUES (?, ?,
?)');
insert.run(0, 1, 30)
const stmt = SettingsDB.prepare("SELECT * FROM jitsiTable");
for (const row of stmt.iterate()) {
console.log(row.alwaysOnTopWindowEnable, row.disableAGC,
row.serverURL, row.serverTimeout, row.created_at, row.updated_at)
}
SettingsDB.close();
Output :
0 1 null 30 2022-12-10 11:00:22 2022-12-10 11:00:22
0 1 null 30 2022-12-10 11:05:46 2022-12-10 11:05:46
0 1 null 30 2022-12-10 11:18:42 2022-12-10 11:18:42
0 1 null 30 2022-12-10 11:22:10 2022-12-10 11:22:10
0 1 null 30 2022-12-10 11:24:18 2022-12-10 11:24:18
0 1 null 30 2022-12-10 11:27:17 2022-12-10 11:27:17
0 1 null 30 2022-12-10 11:35:28 2022-12-10 11:35:28

Related

How to export Varbyte in Teradata

I have a table with example data as follows:
Num JobId
1 12345678
where Num is of Integer datatype, and JobId is of Varbyte datatype.
I need to extract it, and the TPT script I have used for this is:
USING CHARACTER SET UTF8
DEFINE JOB EXPORT_DELIMITED_FILE
DESCRIPTION 'Export' ( DEFINE SCHEMA FILE_SCHEMA (
Num INTEGER,
JobID Varbyte(16)
);
DEFINE OPERATOR SQL_SELECTOR
TYPE SELECTOR
SCHEMA FILE_SCHEMA ATTRIBUTES
(
VARCHAR PrivateLogName = 'selector_log',
VARCHAR TdpId = '192.168.xx.xxx',
VARCHAR UserName = 'dbc', VARCHAR UserPassword = 'dbc',
VARCHAR SelectStmt = 'SELECT * FROM AdventureWorksDW.DB1_TB1;',
DEFINE OPERATOR FILE_WRITER
TYPE DATACONNECTOR CONSUMER
SCHEMA *
ATTRIBUTES
(
VARCHAR PrivateLogName = 'dataconnector_log',
VARCHAR DirectoryPath = 'filepath',
VARCHAR FileName = 'DB1_TB1.csv',
VARCHAR FORMAT= 'DELIMITED', //delimited doesn't work
VARCHAR TextDelimiter= '|',
VARCHAR OpenMode = 'Write'
);
APPLY TO OPERATOR (FILE_WRITER)
SELECT * FROM OPERATOR (SQL_SELECTOR);
);
I need the csv file in the format:
1 | 12345678
How to achieve this?
Binary data is not supported for delimited format. But you can transform it to a string using from_bytes in your select:
USING CHARACTER SET UTF8
DEFINE JOB EXPORT_DELIMITED_FILE
DESCRIPTION 'Export'
(
APPLY TO OPERATOR
( $FILE_WRITER[1]
ATTR ( VARCHAR PrivateLogName = 'dataconnector_log',
VARCHAR DirectoryPath = 'filepath',
VARCHAR FileName = 'DB1_TB1.csv',
VARCHAR FORMAT= 'DELIMITED',
VARCHAR TextDelimiter= '|',
VARCHAR OpenMode = 'Write'
)
)
SELECT *
FROM OPERATOR
( $SELECTOR[1]
ATTR
( PrivateLogName = 'selector_log',
TdpId = '192.168.xx.xxx',
UserName = 'dbc',
UserPassword = 'dbc',
SelectStmt = 'SELECT num, from_bytes(jobid, ''base16'') FROM td01.testtab;'
)
);
);

"TypeError: NoneType is not subscriptable" when executing multiple queries

Member function that retrieves db.
def GetDb(self):
db = getattr(g, '_database', None)
if db is None:
db = g._database = sqlite3.connect(self.path)
db.row_factory = sqlite3.Row
return db
Member function that returns list from db queries
def GetOrderItemsList(self, orderid):
list = []
with app.app_context():
db = self.GetDb()
cur = db.execute('SELECT * FROM ordersList WHERE orderId = ?',[orderid])
records = cur.fetchall();
for row in records:
print(row)
invid = row['inventoryId']
OrderItem
OrderItem.orderId = row['orderId']
OrderItem.productId = row['inventoryId']
OrderItem.productName = 'none'
OrderItem.quantity = row['quantity']
OrderItem.productPrice = row['price']
nextcur = db.execute('SELECT * FROM inventory WHERE invId = ?', [invid])
#nextcur = db.execute('SELECT * FROM inventory WHERE invId = 1') #works
res = nextcur.fetchone();
OrderItem.productName = res['invName']
print(res['invName'])
list.append(OrderItem)
return list
OrderItem:
class OrderItem(object):
def __init__(self, ordId, invId, name, quantity, price):
self.orderId = ordId
self.productId = invId
self.productName = name
self.quantity = quantity
self.productPrice = price
Error message:
Traceback error
OrderItem.productName = res['invName']
TypeError: 'NoneType' object is not subscriptable
Error
nextcur = db.execute('SELECT * FROM inventory WHERE invId = ?', [invid])
Works
nextcur = db.execute('SELECT * FROM inventory WHERE invId = 1')
Been fighting this for many hours. Searching on google. Reading questions on here.
Any help would be appreciated.
The error
'NoneType' object is not subscriptable
Means that you're trying to access an object's key of an object that doesn't exist, i.e. the object is None.
Please check that here
[invid]
invid is not None, i.e. print (invid)
Also, the issue could be that here
res['invName']
res is None, please check the contents of res (with print, etc) before accessing invName, as it is None.
Fix with join, item instances and img for order product list.
Inventory and OrderItems
create table inventory(invId integer PRIMARY KEY AUTOINCREMENT NOT NULL, invName varchar(50), description varchar(100), invImg varchar(50) ,category integer ,quantity integer, price real);
create table ordersList(orderId integer, inventoryId integer, orderQuantity integer, orderPrice real);
class OrderItem(object):
def __init__(self, ordId, invId, img, name, quantity, price):
self.orderId = ordId
self.productId = invId
self.productName = name
self.productImg = img
self.quantity = quantity
self.productPrice = price
def GetOrderItemsList(orderid):
list = []
db = get_db()
cur = db.execute('SELECT orderId, inventoryId, orderQuantity, orderPrice,
inventory.invName AS invName, inventory.invImg AS invImg FROM ordersList INNERJOIN
inventory ON inventory.invId= ordersList.inventoryId WHERE orderId = ?', [orderid])
records = cur.fetchall();
for row in records:
item = OrderItem(row['orderId'], row['inventoryId'],
row['invImg'], row['invName'],
row['orderQuantity'], row['orderPrice'] )
list.append(item)
return list

How to check if a given Date exists in DART?

If you pass a non-existing/non-real date like: '20181364' (2018/13/64) into DateTime (constructor or parse-method), no exception is thrown. Instead a calculated DateTime is returned.
Example:
'20181364' --> 2019-03-05 00:00:00.000
How can I check if a given date really exists/is valid?
I tried to solve this using DartPad (without success), so no Flutter doctor output required here.
void main() {
var inputs = ['20180101', // -> 2018-01-01 00:00:00.000
'20181231', // -> 2018-12-31 00:00:00.000
'20180230', // -> 2018-03-02 00:00:00.000
'20181301', // -> 2019-01-01 00:00:00.000
'20181364'];// -> 2019-03-05 00:00:00.000
inputs.forEach((input) => print(convertToDate(input)));
}
String convertToDate(String input){
return DateTime.parse(input).toString();
}
It would be great if there exist some kind of method to check if a given date really exists/is valid, e.g.:
a validate function in DateTime
another lib that does not use DateTime.parse() for validation
How would you solve this?
You can convert parsed date to string with original format and then compare if it's matching the input.
void main() {
var inputs = ['20180101', // -> 2018-01-01 00:00:00.000
'20181231', // -> 2018-12-31 00:00:00.000
'20180230', // -> 2018-03-02 00:00:00.000
'20181301', // -> 2019-01-01 00:00:00.000
'20181364'];// -> 2019-03-05 00:00:00.000
inputs.forEach((input) {
print("$input is valid string: ${isValidDate(input)}");
});
}
bool isValidDate(String input) {
final date = DateTime.parse(input);
final originalFormatString = toOriginalFormatString(date);
return input == originalFormatString;
}
String toOriginalFormatString(DateTime dateTime) {
final y = dateTime.year.toString().padLeft(4, '0');
final m = dateTime.month.toString().padLeft(2, '0');
final d = dateTime.day.toString().padLeft(2, '0');
return "$y$m$d";
}
My solution to validate the birthday was this, we can see that it has the leap year calculation.
class DateHelper{
/*
* Is valid date and format
*
* Format: dd/MM/yyyy
* valid:
* 01/12/1996
* invalid:
* 01/13/1996
*
* Format: MM/dd/yyyy
* valid:
* 12/01/1996
* invalid
* 13/01/1996
* */
static bool isValidDateBirth(String date, String format) {
try {
int day, month, year;
//Get separator data 10/10/2020, 2020-10-10, 10.10.2020
String separator = RegExp("([-/.])").firstMatch(date).group(0)[0];
//Split by separator [mm, dd, yyyy]
var frSplit = format.split(separator);
//Split by separtor [10, 10, 2020]
var dtSplit = date.split(separator);
for (int i = 0; i < frSplit.length; i++) {
var frm = frSplit[i].toLowerCase();
var vl = dtSplit[i];
if (frm == "dd")
day = int.parse(vl);
else if (frm == "mm")
month = int.parse(vl);
else if (frm == "yyyy")
year = int.parse(vl);
}
//First date check
//The dart does not throw an exception for invalid date.
var now = DateTime.now();
if(month > 12 || month < 1 || day < 1 || day > daysInMonth(month, year) || year < 1810 || (year > now.year && day > now.day && month > now.month))
throw Exception("Date birth invalid.");
return true;
} catch (e) {
return false;
}
}
static int daysInMonth(int month, int year) {
int days = 28 + (month + (month/8).floor()) % 2 + 2 % month + 2 * (1/month).floor();
return (isLeapYear(year) && month == 2)? 29 : days;
}
static bool isLeapYear(int year)
=> (( year % 4 == 0 && year % 100 != 0 ) || year % 400 == 0 );
}
Support for validating dates was added for dart in December 2020: https://pub.dev/documentation/intl/latest/intl/DateFormat/parseStrict.html

Foreign key support in SQLite3 C++ ver.3.25.3

EDIT
That worked:
std::string tab_B = R"(
CREATE TABLE B (
b INT NOT NULL PRIMARY KEY,
bb INT NOT NULL,
FOREIGN KEY(b) REFERENCES A(a)
);
)";
Pragma and config were not needed
END OF EDIT
I've tried pragma way:
std::string fk_on = "PRAGMA foreign_keys = ON;";
sqlite3_exec(DB, fk_on.c_str(), NULL, 0, &messaggeError);
and config one:
sqlite3_db_config(DB, SQLITE_DBCONFIG_ENABLE_FKEY, 1, &fkeyConstraintsEnabled);
Pragma gives me nothing, fkeyConstraintsEnabled gives 1.
What I am trying to do is to create B table:
std::string tab_A = R"(
CREATE TABLE A (
a INT NOT NULL PRIMARY KEY
);
)";
std::string tab_B = R"(
CREATE TABLE B (
b INT NOT NULL PRIMARY KEY,
bb INT NOT NULL FOREIGN_KEY REFERENCES A(a)
);
)";
std::string tab_A = R"(
CREATE TABLE A (
a INT NOT NULL PRIMARY KEY
);
)";
std::string tab_B = R"(
CREATE TABLE B (
b INT NOT NULL PRIMARY KEY,
bb INT NOT NULL , FOREIGN_KEY(bb) REFERENCES A(a)
);
)";
That's how it's done according to the sqlite documentation. This is, btw, a sqlite problem not a c++ one.

SqlDataSource SelectCommand contains null values

My SQL code that works running on the server.
SELECT
[LINE_NO], [CUST_ORDER_ID], [PART_ID],
[CUSTOMER_PART_ID], [MISC_REFERENCE], [PROMISE_DATE],
[PROMISE_DEL_DATE]
FROM
[CUST_ORDER_LINE]
WHERE
([CUST_ORDER_ID] = '33742-1'
AND [PROMISE_DATE] IS NULL
AND [PROMISE_DEL_DATE] IS NULL)
My asp.net code.
SelectCommand = "SELECT [LINE_NO], [CUST_ORDER_ID], [PART_ID], [CUSTOMER_PART_ID], [MISC_REFERENCE], [PROMISE_DATE], [PROMISE_DEL_DATE] FROM [CUST_ORDER_LINE] WHERE ([CUST_ORDER_ID] = ? AND [PROMISE_DATE] = ? AND [PROMISE_DEL_DATE] = ?)"
I'm using 3 query string parameters. The promise date and promise delivery date can be null. But when those values are null it returns no records.
How can I program this to change the SQL to 'is null' instead of = ''.
I think this is what you want:
Param 1 = OrderID
Param 2/3 are both Promise Date
Param 4/5 are both Promise Delivery Date
Code:
SelectCommand = "SELECT [LINE_NO], [CUST_ORDER_ID], [PART_ID], [CUSTOMER_PART_ID], [MISC_REFERENCE], [PROMISE_DATE], [PROMISE_DEL_DATE] FROM [CUST_ORDER_LINE] WHERE [CUST_ORDER_ID] = ? AND (? IS NULL OR [PROMISE_DATE] = ?) AND (? IS NULL OR [PROMISE_DEL_DATE] = ?)"
The SQL would be:
DECLARE #P1 INT, #P2 DATETIME, #P3 DATETIME
SELECT [LINE_NO], [CUST_ORDER_ID], [PART_ID], [CUSTOMER_PART_ID], [MISC_REFERENCE], [PROMISE_DATE], [PROMISE_DEL_DATE]
FROM [CUST_ORDER_LINE]
WHERE [CUST_ORDER_ID] = #P1
AND (#P2 IS NULL OR [PROMISE_DATE] = #P2)
AND (#P3 IS NULL OR [PROMISE_DEL_DATE] = #P3)

Resources