I want to INSERT data in a SQLite table and do this :
sqlite3_stmt *pStmt;
sqlite3_prepare(db,"INSERT INTO table(col2,col3) VALUES (?,?) RETURNING col1;",-1,&pStmt,NULL);
for (int i = 0; i < dataset_length; i++) {
sqlite3_bind_int(pStmt,1,dataset[i].value1);
sqlite3_bind_int(pStmt,2,dataset[i].value2);
switch (sqlite3_step(pStmt)) {
case SQLITE_ROW: {
// Nice! A row has been inserted.
dataset[i].id = sqlite3_column_int(pStmt,0);
} break;
case SQLITE_DONE: {
// No results. What? Return an error.
} return false;
default: {
// Return an error
} return false;
}
// ↓ Problem below ↓
sqlite3_reset(pStmt);
}
//sqlite3_cleanup(pStmt); <- Don't worry about cleanups
return true;
sqlite3_step() always returns SQLITE_ROW and the RETURNING expression works.
If I do a SELECT before the sqlite3_reset(), it returns the freshly inserted row. If I prepare and run the same query after the sqlite3_reset(), my table is empty, the row is vanished.
I tried without the sqlite3_reset() and that works, but I don't understand why and think it's due to the auto-reset feature I OMIT in the Windows build.
Where I am wrong in my SQLite usage?
I finally find out where I was wrong. SQLite mandate to call sqlite_reset() only after receiving an error or SQLITE_DONE.
In my code I only generate a SQLITE_ROW, but I sqlite_reset() before getting a SQLITE_DONE and it cause SQLite to somewhat "reset" the statement and rolling back changes from my point of view.
The correct way is to after a SQLITE_ROW, to call sqlite_step() again that generate a SQLITE_DONE and then sqlite_reset(). That means :
// The way to SQLite with a RETURNING INSERT
for (...) {
// sqlite3_bind...()
sqlite3_step(); // Returns SQLITE_ROW
// sqlite3_column...()
sqlite3_step(); // Returns SQLITE_DONE
sqlite3_reset(); // Returns SQLITE_OK
}
Here is below my fixed code from my question :
sqlite3_stmt *pStmt;
sqlite3_prepare(db,"INSERT INTO table(col2,col3) VALUES (?,?) RETURNING col1;",-1,&pStmt,NULL);
for (int i = 0; i < dataset_length; i++) {
sqlite3_bind_int(pStmt,1,dataset[i].value1);
sqlite3_bind_int(pStmt,2,dataset[i].value2);
switch (sqlite3_step(pStmt)) {
case SQLITE_ROW: {
// Nice! A row has been inserted.
dataset[i].id = sqlite3_column_int(pStmt,0);
// Generate a SQLITE_DONE
if (sqlite3_step(pStmt) != SQLITE_DONE)
// Something went wrong, return an error
return false;
} break;
case SQLITE_DONE: {
// No results. What? Return an error.
} return false;
default: {
// Return an error
} return false;
}
sqlite3_reset(pStmt);
}
//sqlite3_cleanup(pStmt); <- Don't worry about cleanups
return true;
Of course my code imply that there is only 1 row returned by SQLite, adapt your code if SQLite returns more. The rule is that a sqlite_step() must returns a SQLITE_DONE before doing a sqlite_reset().
I have a small problem. I want to close my console using a close method. Not via the X.
For this I have a case "9" in the switch block;
This means that when I enter "9" and press enter, the window should close. The previous attempts to call Application.Close(); with a method did not work.
Does anyone have a solution, or is this not even possible from the switch?
private void InputOption()
{
string input;
Menu nextMenu;
while(true) //Die Eingabe muss die zahlen beinhalten.
{
Console.Write("Eingabe: ");
input = Console.ReadLine();
bool correctInput = true;
switch(input)
{
case "1":
nextMenu = new CreateProfileMenu();
break;
case "2":
nextMenu = new LoadProfileMenu();
break;
case "9":
Close();
break;
default:
correctInput = false;
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("Ungültige Eingabe!");
Console.ForegroundColor = ConsoleColor.DarkCyan;
break;
}
if (correctInput)
{
break;
}
}
I have found the problem. The assembly
I have found the error. There was a missing link to System.Windows.Forms;
I have now successfully implemented the method Close() in the Switch Block.
case "9" :
Close();
...
private void Close()
{
Application.Exit();
}
This is a static function which is an unmanaged function which I am trying to call from a managed CLR project. But everytime I add the erase an exception happens. Both classes are inside the same project
I keep getting an exception on the erase,
#pragma managed(push, off)
void MessageContainer::ParseByteStream(UINT8 *buf, int length)
{
s_RxBufVector.insert(s_RxBufVector.end(), buf, buf + length);
if (s_RxBufVector.size() >= sizeof(Msg_Struct) * 2)
{
int BytesConsumed = 0;
s_RxBufIterator = s_RxBufVector.begin();
while (BytesConsumed < (int)s_RxBufVector.size() - sizeof(Msg_Struct))
{
if (ntohl(*((UINT32 *)&s_RxBufVector[BytesConsumed + __PREAMBLE_OFFSET])) == PreambleVal)
{
switch (ntohl(*((UINT32 *)&s_RxBufVector[BytesConsumed + __COMMAND_ID_OFFSET])))
{
case eCommandIdRxMsg:
if (MsgRx != nullptr)
(*MsgRx)(ntohl(*((UINT32*)&s_RxBufVector[BytesConsumed + __ID_OFFSET])), ntohs(*((UINT16*)(&s_RxBufVector[BytesConsumed + __CHANNEL_OFFSET]))),
ntohs(*((UINT16*)&s_RxBufVector[BytesConsumed + __LENGTH_OFFSET])), &s_RxBufVector[BytesConsumed + __BUFFER_OFFSET]);
break;
case eCommandIdCmdAck:
if (CmdAck != nullptr)
//(*CmdAck())
break;
case eCommandIdSendAck:
if (TxConf != nullptr)
//(*TxConf())
break;
default:
break;
}
BytesConsumed += sizeof(Msg_Struct);
}
else
{
BytesConsumed++;
}
}
s_RxBufVector.erase(s_RxBufIterator, s_RxBufIterator + BytesConsumed);
}
}
private:
static std::vector<UINT8, std::allocator<UINT8>> s_RxBufVector;
static std::vector<UINT8>::iterator s_RxBufIterator;
Init()
{
s_RxBufVector.reserve(4096);
}
Is there something wrong with the Vector accessing.
An unhandled exception of type 'System.AccessViolationException' occurred
Break stops here
_Adopt(_Right._Myproxy->_Mycont);
Worse is that I was trying to delete 24 Bytes at the beginning when the size is already 48
EDIT:
Ok, I found commenting out the code for the callback to the managed code solves the Exception but does not help me either
(*MsgRx)(ntohl(*((UINT32*)&s_RxBufVector[BytesConsumed + __ID_OFFSET])), ntohs(* (UINT16*)(&s_RxBufVector[BytesConsumed + __CHANNEL_OFFSET]))), ntohs(*((UINT16*)&s_RxBufVector[BytesConsumed + __LENGTH_OFFSET])), &s_RxBufVector[BytesConsumed + __BUFFER_OFFSET]);
The Callback is declared here
delegate void MessageReceivedCallbackDelegate(UInt32 Id, UInt16 Channel, UInt16 len, Byte *data);
MessageContainer::SetMessageRxCB((void*)Marshal::GetFunctionPointerForDelegate(gcnew MessageReceivedCallbackDelegate(MessageReceived)));
unmanaged
void MessageContainer::SetMessageRxCB(void *fn)
{
MsgRx = (RxCbFn)fn;
}
Seems like the managed code is causing some problems to the vector. Probably something wrong with how I try to call the managed code, I need some hints :)
SOLVED:
Ok, I forgot to decorate the delegates
[UnmanagedFunctionPointerAttribute(CallingConvention::Cdecl)]
delegate void MessageReceivedCallbackDelegate(UInt32 Id, UInt16 Channel, UInt16 Dlc, Byte *data)
I try to use firebase db,
I found very important restrictions, which are not described in firebase help or FAQ.
First problem is that symbol: dot '.' prohibited in keys,
i.e. firebase reject (with unknown reason) next:
nameRef.child('Henry.Morgan#caribbean.sea').set('Pirat');
Second problem with forward slashes in your keys '/',
when you try to add key like this
{'02/10/2013': true}
In firebase you can see:
'02': {
'10': {
'2013': true
}
}
Have you got any ideas how to solve it (automatically)?
May be set some flag that it is string key with all symbols?
Of course, I can parse/restore data every time before write and after read, but...
By the way '.' '/' - all restricted symbols for firebase ?
The reason that adding a child 02/10/2013 creates a structure in Firebase is because the forward slashes are resulting in the creation of a new level.
So the line I assume you are using something similar to: firebaseRef.child('02/10/2013').set(true) is equivalent to firebaseRef.child('02').child('10').child('2013').set(true).
To avoid the problems of not being able to use the following characters in reference key names (source),
. (period)
$ (dollar sign)
[ (left square bracket)
] (right square bracket)
# (hash or pound sign)
/ (forward slash)
we can use one of JavaScript's built in encoding functions since as far as I can tell, Firebase does not provide a built in method to do so. Here's a run-through to see which is the most effective for our purposes:
var forbiddenChars = '.$[]#/'; //contains the forbidden characters
escape(forbiddenChars); //results in ".%24%5B%5D%23/"
encodeURI(forbiddenChars); //results in ".%24%5B%5D%23%2F"
encodeURIComponent(forbiddenChars); //results in ".%24%5B%5D%23%2F"
Evidently, the most effective solution is encodeURIComponent. However, it doesn't solve all our problems. The . character still poses a problem as shown by the above test and trying to encodeURIComponent your test e-mail address. My suggestion would be to chain a replace function after the encodeURIComponent to deal with the periods.
Here's what the solution would look like for your two example cases:
encodeURIComponent('Henry.Morgan#caribbean.sea').replace(/\./g, '%2E') //results in "Henry%2EMorgan%40caribbean%2Esea"
encodeURIComponent('02/10/2013'); //results in "02%2F10%2F2013"
Since both the final results are safe for insertion into a Firebase as a key name, the only other concern is decoding after reading from a Firebase which can be solved with replace('%2E', '.') and a simple decodeURIComponent(...).
I faced the same problem myself, and I have created firebase-encode for this purpose.
Unlike the chosen answer, firebase-encode encodes only unsafe characters (./[]#$) and % (necessary due to how encoding/decoding works).
It leaves other special characters that are safe to be used as firebase key while encodeURIComponent will encode them.
Here's the source code for details:
// http://stackoverflow.com/a/6969486/692528
const escapeRegExp = (str) => str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&');
const chars = '.$[]#/%'.split('');
const charCodes = chars.map((c) => `%${c.charCodeAt(0).toString(16).toUpperCase()}`);
const charToCode = {};
const codeToChar = {};
chars.forEach((c, i) => {
charToCode[c] = charCodes[i];
codeToChar[charCodes[i]] = c;
});
const charsRegex = new RegExp(`[${escapeRegExp(chars.join(''))}]`, 'g');
const charCodesRegex = new RegExp(charCodes.join('|'), 'g');
const encode = (str) => str.replace(charsRegex, (match) => charToCode[match]);
const decode = (str) => str.replace(charCodesRegex, (match) => codeToChar[match]);
I wrote this for Java (since I came here expecting a java implementation):
public static String encodeForFirebaseKey(String s) {
return s
.replace("_", "__")
.replace(".", "_P")
.replace("$", "_D")
.replace("#", "_H")
.replace("[", "_O")
.replace("]", "_C")
.replace("/", "_S")
;
}
public static String decodeFromFirebaseKey(String s) {
int i = 0;
int ni;
String res = "";
while ((ni = s.indexOf("_", i)) != -1) {
res += s.substring(i, ni);
if (ni + 1 < s.length()) {
char nc = s.charAt(ni + 1);
if (nc == '_') {
res += '_';
} else if (nc == 'P') {
res += '.';
} else if (nc == 'D') {
res += '$';
} else if (nc == 'H') {
res += '#';
} else if (nc == 'O') {
res += '[';
} else if (nc == 'C') {
res += ']';
} else if (nc == 'S') {
res += '/';
} else {
// this case is due to bad encoding
}
i = ni + 2;
} else {
// this case is due to bad encoding
break;
}
}
res += s.substring(i);
return res;
}
Character limitations are documented at https://www.firebase.com/docs/creating-references.html - you cannot use '.', '/', '[', ']', '#', and '$' in key names. There is no automatic way of escaping these characters, I'd recommend avoiding their use altogether or creating your own escaping/unescaping mechanism.
If you're using Swift 3, this works for me (try it in a playground):
var str = "this.is/a#crazy[string]right$here.$[]#/"
if let strEncoded = str.addingPercentEncoding(withAllowedCharacters: .alphanumerics) {
print(strEncoded)
if let strDecoded = strEncoded.removingPercentEncoding {
print(strDecoded)
}
}
I got annoyed with this problem so I took the answer from #sushain97 (thanks!) and built a deep encoder/decoder.
https://www.npmjs.com/package/firebase-key-encode
Basic usage:
var firebaseKeyEncode = require('firebase-key-encode');
firebaseKeyEncode.encode('my.bad.key');
// Output: my%2Ebad%2Ekey
Deep Usage:
var firebaseKeyEncode = require('firebase-key-encode');
var badTree = {
"pets": [
{
"jimmy.choo": 15}
],
"other.key": 5
}
firebaseKeyEncode.deepEncode(badTree);
// Output: {
// "pets": [
// {
// "jimmy%2Echoo": 15}
// ],
// "other%2Ekey": 5
// }
Personally, I found a simple and easy hack for this same problem I encountered
I took the dateTime string and convert it using replace('/','|')
the result will be something like this 2017|07|24 02:39:37 instead of 2017/07/24 02:39:37.
Even though it is not what OP asks,
but in my experience rather than using such dubious keys it is better to let .push() create an id,
and other things - e-mail, date etc. save as content of the dedicated fields.
$id: {
email: "Henry.Morgan#caribbean.sea"
}
P.S. Don't try to save volume by inserting what should be content into the key.
Premature optimization is the root of all evil (c).
Efficient C# implementation (for Unity and .net). Based on the answer from #josue.0.
public static string EncodeFirebaseKey(string s) {
StringBuilder sb = new StringBuilder();
foreach (char c in s) {
switch (c) {
case '_':
sb.Append("__");
break;
case '$':
sb.Append("_D");
break;
case '.':
sb.Append("_P");
break;
case '#':
sb.Append("_H");
break;
case '[':
sb.Append("_O");
break;
case ']':
sb.Append("_C");
break;
case '/':
sb.Append("_S");
break;
default:
sb.Append(c);
break;
}
}
return sb.ToString();
}
public static string DecodeFirebaseKey(string s) {
StringBuilder sb = new StringBuilder();
bool underscore = false;
for (int i = 0; i < s.Length; i++) {
if (underscore) {
switch (s[i]) {
case '_':
sb.Append('_');
break;
case 'D':
sb.Append('$');
break;
case 'P':
sb.Append('.');
break;
case 'H':
sb.Append('#');
break;
case 'O':
sb.Append('[');
break;
case 'C':
sb.Append(']');
break;
case 'S':
sb.Append('/');
break;
default:
Debug.LogWarning("Bad firebase key for decoding");
break;
}
underscore = false;
} else {
switch (s[i]) {
case '_':
underscore = true;
break;
default:
sb.Append(s[i]);
break;
}
}
}
return sb.ToString();
}
Python implementation
_escape = {'&': '&&',
'$': '&36',
'#': '&35',
'[': '&91',
']': '&93',
'/': '&47',
'.': '&46'}
_unescape = {e: u for u, e in _escape.items()}
def escape_firebase_key(text):
return text.translate(str.maketrans(_escape))
def unescape_firebase_key(text):
chunks = []
i = 0
while True:
a = text[i:].find('&')
if a == -1:
return ''.join(chunks + [text[i:]])
else:
if text[i+a:i+a+2] == '&&':
chunks.append('&')
i += a+2
else:
s = text[i+a:i+a+3]
if s in _unescape:
chunks.append(text[i:i+a])
chunks.append(_unescape[s])
i += a+3
else:
raise RuntimeError('Cannot unescape')
And a few test cases:
test_pairs = [('&hello.', '&&hello&46'),
('&&&', '&&&&&&'),
('some#email.com', 'some#email&46com'),
('#$[]/.', '&35&36&91&93&47&46')]
for u, e in test_pairs:
assert escape_firebase_key(u) == e, f"escaped '{u}' is '{e}', but was '{escape_firebase_key(u)}'"""
assert unescape_firebase_key(e) == u, f"unescaped '{e}' is '{u}', but was '{unescape_firebase_key(e)}'"
try:
unescape_firebase_key('&error')
assert False, 'Must have raised an exception here'
except RuntimeError as ex:
assert str(ex) == 'Cannot unescape'
const encodeKey = s => s.replace(/[\.\$\[\]#\/%]/g, c => '%' + c.charCodeAt(0).toString(16).toUpperCase())
const decodeKey = s => s.replace(/%(2E|24|5B|5D|23|2F|25)/g, decodeURIComponent)
console.log(encodeKey('.$[]#/%23')) // %2E%24%5B%5D%23%2F%2523
console.log(decodeKey(encodeKey('.$[]#/%23'))) // .$[]#/%23
import re
import urllib.parse
encode_key = lambda s: re.sub('[\.\$\[\]#\/%]', lambda c: f'%{ord(c.group()):X}', s)
decode_key = lambda s: re.sub('%(2E|24|5B|5D|23|2F|25)', lambda c: urllib.parse.unquote(c.group()), s)
print(encode_key('.$[]#/%23')) # %2E%24%5B%5D%23%2F%2523
print(decode_key(encode_key('.$[]#/%23'))) # .$[]#/%23
Using the twaindotnet library in C#, I'm wondering if there's a way to set the default datasource using the library.
As a feeble attempt, I've tried adding a SetDefault method to the DataSource class of twaindonet, like this
public static void SetDefault(Identity applicationId, IWindowsMessageHook messageHook, DataSource newDataSource)
{
var defaultSourceId = newDataSource.SourceId;
// Attempt to get information about the system default source
var result = Twain32Native.DsmIdentity(
applicationId,
IntPtr.Zero,
DataGroup.Control,
DataArgumentType.Identity,
Message.Set,
defaultSourceId);
if (result != TwainResult.Success)
{
var status = DataSourceManager.GetConditionCode(applicationId, null);
throw new TwainException("Error getting information about the default source: " + result, result, status);
}
}
which is called from the DataSourceManage class like this
public void SelectSource(DataSource dataSource)
{
DataSource.Dispose();
DataSource.SetDefault(ApplicationId, _messageHook, dataSource);
}
But when I try to use SetDefault, Twain32Native.DsmIdentity always results in Failure being returned.
I basically copied from SetDefault the setDefaultDataSource method from TWAIN sample Data Source and Application
pTW_IDENTITY TwainApp::setDefaultDataSource(unsigned int _index)
{
if(m_DSMState < 3)
{
cout << "You need to open the DSM first." << endl;
return NULL;
}
else if(m_DSMState > 3)
{
PrintCMDMessage("A source has already been opened, please close it first\n");
return NULL;
}
if(_index >= 0 && _index < m_DataSources.size())
{
m_pDataSource = &(m_DataSources[_index]);
// set the specific data source
TW_UINT16 twrc;
twrc = _DSM_Entry(
&m_MyInfo,
0,
DG_CONTROL,
DAT_IDENTITY,
MSG_SET,
(TW_MEMREF) m_pDataSource);
switch (twrc)
{
case TWRC_SUCCESS:
break;
case TWRC_FAILURE:
printError(0, "Failed to get the data source info!");
break;
}
}
else
{
return NULL;
}
return m_pDataSource;
}
Any help would be greatly appreciated.
The possible cause is that the version of your TWAIN DSM is too low. Only DSM 2.0 or above supports setting default TWAIN data source.