插入protobuf时SQLite无法识别的令牌错误:要处理哪些令牌&怎么样? [英] SQLite unrecognized token error while inserting protobuf: Which tokens to be handled & How?

查看:24
本文介绍了插入protobuf时SQLite无法识别的令牌错误:要处理哪些令牌&怎么样?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 sqlite3_exec() 函数来执行查询.我知道根据下面的帖子,最好使用 _prepare、_bind、_step、_finalize 组合以获得各种好处.

I am using sqlite3_exec() function for executing the queries. I am aware that as per below post, it's better to use _prepare, _bind, _step, _finalize combination for various benefits.

带有加密 std::string(无法识别的令牌)的 sqllite 查询

但是,就我而言,我已经有了一个库,它与 sqlite3_exec() 紧密耦合,并且很难更改.即使出于教育目的,我也想知道,如何在 sqlite3 数据库中输入特殊令牌.目前,我正在使用 C++ 以编程方式从文件中读取此语句,并使用 sqlite3_exec()

However, in my case I already have a library in place, which is tightly coupled around sqlite3_exec() and it will be difficult to change. Even for education purpose, I would like to know, how can I enter special tokens inside an sqlite3 database. Currently I am programatically reading this statement from a file using C++ and inserting into the DB using sqlite3_exec()

目前,以下语句出错:

INSERT INTO Convey(username, data, id, type)  
VALUES('12345', '^Z^Dfine* ^HºÉÙ<98>ö÷×^B2^@', 'abcd', 31);

错误出现在这个符号 ^@ 作为 SQL error: unrecognized token:.当我拆解语句并检查每个字符的 ascii 时,它显示 0 代替 ^@.data 的类型,无论是 TEXT 还是 BLOB 都没有区别.

The error comes at this symbol ^@ as SQL error: unrecognized token:. When I dismantled the statement and checked ascii for each characters, it showed 0 in place of ^@. The type of data, be it TEXT or BLOB doesn't make a difference.

请注意,我试图在此处输入的数据"是序列化形式的 Google protobuf 消息.

Note that, the "data", I am trying to enter here is a Google protobuf message in a serialised form.

当必须使用 sqlite3_exec() 时,在 sqlite 中转义此类nul"之类的字符的正确方法是什么?

What is the correct way to escape such "nul" like characters in sqlite, when one has to use sqlite3_exec()?

[注意:1 方法是用一些预定义的模式替换 0,这些模式不太可能在二进制字符串中找到,然后在读取时恢复它们.我也对这个解决方案持开放态度.]

[Note: 1 way is to replace 0 with some pre-defined pattern, which less likely to be found in binary strings and then restore them while reading it. I am open to this solution as well.]

推荐答案

似乎不可能 INSERT 具有 blob 性质的数据,即包含 NUL ('\0') 字符(或可能新行 '\n' 个字符).

Seems that it's not possible to INSERT a data with blob nature, i.e. containing NUL ('\0') characters (or possibly new line '\n' characters).

因此,现在我以以下方式插入:

Hence, now I am inserting in following way:

  • 插入前,检查是否有这样的特殊字符(即'\0'、'\n')
  • 如果是,则在字符串中,在末尾附加一个特殊的已知标记,例如'%'
  • 列出该标记后以逗号分隔的位置;这些位置可以用临时占位符替换,例如0"

'^Z^Dfine* ^HºÉÙ<98>ö÷×^B2^@' 看起来像 '^Z^Dfine* ^HºÉÙ<98>ö÷×^B20#<;位置>'

在读取字符串时,必须对其进行解码.到目前为止,这非常有用并且运行良好!

While reading the string, the same has to be decoded. This is very helpful and working nicely so far!

有兴趣的朋友,这里是替换'\0'的代码:

For those who are interested, here is the code for replacement of '\0':

#define SQLa_STRING_END      '%'
#define SQLa_NUL_SEPARATOR   ','
#define SQLa_NUL_TOKEN       '0'

string
ToString (const string& s_,  // need to enclose with '' and add ' before '
          const bool isEncodingString = false)
{
  string s = s_;
  const char apostrophe = '\'';
  bool isStringEndPending = isEncodingString;
  for(size_t i = 0, length = s.length(); i < length; ++i)
    switch(s[i])
    {
    case apostrophe:
      s.insert(i++, 1, apostrophe);
      ++length;
    break;
    case 0:
      if(isEncodingString)
      {
        if(isStringEndPending)
        {
          s += SQLa_STRING_END;
          isStringEndPending = false;
        }
        s[i] = SQLa_NUL_TOKEN; ;
        s += std::to_string(i) + SQLa_NUL_SEPARATOR;
      }
    default:
    break;
    }
  s.insert(0, 1, '\'');
  return s += '\'';
}

string
FromString (const char value[])  // enclosing '' are not present
{
  string s = value;
  if(const auto posEnd = s.rfind(SQLa_STRING_END) + 1)
  {
    std::replace(s.begin() + posEnd, s.end(), SQLa_NUL_SEPARATOR, '\0');
    for(auto pos = posEnd, length = s.length() - 1;
        pos < length;
        s[::atoll(&s[pos])] = 0, pos = s.find(SQLa_NUL_SEPARATOR, pos) + 1);
    s.erase(posEnd - 1);
  }
  return s;
}

这篇关于插入protobuf时SQLite无法识别的令牌错误:要处理哪些令牌&amp;怎么样?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆