简体   繁体   中英

C++: Does sqlite3 use errno codes?

I am using the sqlite3 C++ api. After running

int rc = sqlite3_exec(db, pSQL, 0, 0, 0);

which returns a rc result of SQLITE_OK .

Additionally, I have tested for errno != 0 . The result of cout << strerror(errno) << endl is consistently: No such file or directory

In other words, I know that sqlite3 has its own set of "Return Codes" (ie SQLITE_OK). However, does sqlite3 use errno codes correctly/consistently? That is, if another part of my application is using the global errno variable, should I be resetting it after every call to sqlite3_exec ?

Thanks.


A more complete example of my code:

    const int errno_start = errno;
    if (errno_start > 0) {
        std::cout << "errno=" << strerror(errno) << std::endl;
        std::cout << "errno_start=" << strerror(errno_start) << std::endl;
    }
    // prepare sql statement
    const char *pSQL;
    pSQL = "CREATE TABLE "
            "IF NOT EXISTS "
            "test1"
            "("
            "id INTEGER,"
            "field VARCHAR(32),"
            "value DOUBLE,"
            "timestamp DATETIME"
            ")";

    //int rc = sqlite3_exec(db, pSQL, callback, 0, &szErrMsg);
    int rc = sqlite3_exec(db, pSQL, 0, 0, 0);
    const int errno_here1 = errno;
    if (errno_here1 > 0) {
        std::cout << "errno_start=" << strerror(errno_start) << ", errno_here1="
                << strerror(errno_here1) << std::endl;
    }
    if (rc != SQLITE_OK) {
        std::cout << "SQL Error: " << szErrMsg << std::endl;
        sqlite3_free(szErrMsg);
    } else {
        std::cout << "initialize successful" << std::endl;
    }

Result from this snippet is:

errno_start=Success, errno_here1=No such file or directory

initialize successful

You should never rely on the value in errno to persist beyond the next OS call, as pretty much any OS call that can fail (ie, almost all of them) may set it. At least there's one thing though: errno is now usually a thread-local behind the scenes. Still, a library may well set errno when you call into it, so it is wise to save the value immediately after a failing system call and ignore it otherwise.

SQLite makes OS calls inside itself (when it accesses the DB file, of course) so it may well set errno to virtually anything. The errors that it encounters are handled inside it; if there's something wrong, it will tell you using its own, documented error mechanism. That never includes any information from errno as it happens (and in fact that would be non-portable; SQLite runs on Windows as well, and that uses a different error code reporting mechanism).

sqlite3 returns an result code that corresponds to a set of DEFINES as laid out in the sqlite3 API :

#define SQLITE_OK           0   /* Successful result */
/* beginning-of-error-codes */
#define SQLITE_ERROR        1   /* SQL error or missing database */
#define SQLITE_INTERNAL     2   /* Internal logic error in SQLite */
#define SQLITE_PERM         3   /* Access permission denied */
#define SQLITE_ABORT        4   /* Callback routine requested an abort */
#define SQLITE_BUSY         5   /* The database file is locked */
#define SQLITE_LOCKED       6   /* A table in the database is locked */
#define SQLITE_NOMEM        7   /* A malloc() failed */
#define SQLITE_READONLY     8   /* Attempt to write a readonly database */
#define SQLITE_INTERRUPT    9   /* Operation terminated by sqlite3_interrupt()*/
#define SQLITE_IOERR       10   /* Some kind of disk I/O error occurred */
#define SQLITE_CORRUPT     11   /* The database disk image is malformed */
#define SQLITE_NOTFOUND    12   /* Unknown opcode in sqlite3_file_control() */
#define SQLITE_FULL        13   /* Insertion failed because database is full */
#define SQLITE_CANTOPEN    14   /* Unable to open the database file */
#define SQLITE_PROTOCOL    15   /* Database lock protocol error */
#define SQLITE_EMPTY       16   /* Database is empty */
#define SQLITE_SCHEMA      17   /* The database schema changed */
#define SQLITE_TOOBIG      18   /* String or BLOB exceeds size limit */
#define SQLITE_CONSTRAINT  19   /* Abort due to constraint violation */
#define SQLITE_MISMATCH    20   /* Data type mismatch */
#define SQLITE_MISUSE      21   /* Library used incorrectly */
#define SQLITE_NOLFS       22   /* Uses OS features not supported on host */
#define SQLITE_AUTH        23   /* Authorization denied */
#define SQLITE_FORMAT      24   /* Auxiliary database format error */
#define SQLITE_RANGE       25   /* 2nd parameter to sqlite3_bind out of range */
#define SQLITE_NOTADB      26   /* File opened that is not a database file */
#define SQLITE_ROW         100  /* sqlite3_step() has another row ready */
#define SQLITE_DONE        101  /* sqlite3_step() has finished executing */
/* end-of-error-codes */

Nothing in the API indicates that they use the same error codes as defined in Errno.h. It is simply a coincidence.

sqlite3 API already provides an interface to print a string representation of the error code. I recommend you study the API a little more.

EDIT : Based on your comment, I have looked at the source for sqlite3 and it uses OS functions which set errno . That may be why you are seeing errno change. There is no relation between SQLITE result code and errno.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM