Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cannot open proj.db with memvfs #3887

Closed
gaoyuanning opened this issue Sep 8, 2023 · 1 comment
Closed

cannot open proj.db with memvfs #3887

gaoyuanning opened this issue Sep 8, 2023 · 1 comment
Labels

Comments

@gaoyuanning
Copy link

gaoyuanning commented Sep 8, 2023

Hi I try to use the proj to load the proj.db in memory format. To do this, I use char proj_db[] to store the proj.db in binary format, and load it by memvfs. But when I run the code, I get the error of open file. I wonder if there something wrong in my codes?

Here is my code:

#include <math.h>
#include <proj.h>
#include <filemanager.hpp>
#include <stdio.h>
#include <iostream>
#include "sqlite3.h"

extern "C" unsigned char proj_db[];
extern "C" unsigned int proj_db_len;
extern "C" int sqlite3_memvfs_init(sqlite3 *, char **, const sqlite3_api_routines *);

int main(void) {

    sqlite3_initialize();
    sqlite3_memvfs_init(nullptr, nullptr, nullptr);
    auto vfs = sqlite3_vfs_find("memvfs");
    if (!vfs) {
        std::cerr << "Could not find sqlite memvfs extension\n";
        return -1;
    }
    sqlite3_vfs_register(vfs, 0);

    /* Create the context. */
    /* You may set C=PJ_DEFAULT_CTX if you are sure you will     */
    /* use PJ objects from only one thread                       */
    PJ_CONTEXT *C = proj_context_create();

    char * path = sqlite3_mprintf("file:/proj.db?ptr=0x%p&sz=%lld&freeonclose=1", (void *)proj_db, (long long)proj_db_len);
    proj_context_set_sqlite3_vfs_name(C, "memvfs");
    bool ok = proj_context_set_database_path(C, path, nullptr, nullptr);

    if (!ok)
    {
        std::cerr << "canno open set the database path\n";
        return -1;
    }

    return 0;
}
@gaoyuanning gaoyuanning added the bug label Sep 8, 2023
@gaoyuanning gaoyuanning changed the title cannot open proj.db in memvfs cannot open proj.db with memvfs Sep 8, 2023
@gaoyuanning
Copy link
Author

gaoyuanning commented Sep 8, 2023

I found if I add SQLITE_OPEN_URI flag in sqlite3_open_v2() in below source codes, and re-compile the proj.
The above codes will work.

// proj-9.3.0/src/iso19111/factory.cpp
std::shared_ptr<SQLiteHandle> SQLiteHandle::open(PJ_CONTEXT *ctx,
                                                 const std::string &path) {

    const int sqlite3VersionNumber = sqlite3_libversion_number();
    // Minimum version for correct performance: 3.11
    if (sqlite3VersionNumber < 3 * 1000000 + 11 * 1000) {
        pj_log(ctx, PJ_LOG_ERROR,
               "SQLite3 version is %s, whereas at least 3.11 should be used",
               sqlite3_libversion());
    }

    std::string vfsName;
#ifdef ENABLE_CUSTOM_LOCKLESS_VFS
    std::unique_ptr<SQLite3VFS> vfs;
    if (ctx->custom_sqlite3_vfs_name.empty()) {
        vfs = SQLite3VFS::create(false, true, true);
        if (vfs == nullptr) {
            throw FactoryException("Open of " + path + " failed");
        }
        vfsName = vfs->name();
    } else
#endif
    {
        vfsName = ctx->custom_sqlite3_vfs_name;
    }
    sqlite3 *sqlite_handle = nullptr;
    // SQLITE_OPEN_FULLMUTEX as this will be used from concurrent threads
    if (sqlite3_open_v2(path.c_str(), &sqlite_handle,
                        SQLITE_OPEN_READONLY | SQLITE_OPEN_FULLMUTEX,
                        vfsName.empty() ? nullptr : vfsName.c_str()) !=
            SQLITE_OK ||
        !sqlite_handle) {
        if (sqlite_handle != nullptr) {
            sqlite3_close(sqlite_handle);
        }
        throw FactoryException("Open of " + path + " failed");
    }
    auto handle =
        std::shared_ptr<SQLiteHandle>(new SQLiteHandle(sqlite_handle, true));
#ifdef ENABLE_CUSTOM_LOCKLESS_VFS
    handle->vfs_ = std::move(vfs);
#endif
    handle->initialize();
    handle->checkDatabaseLayout(path, path, std::string());
    return handle;
}

rouault added a commit that referenced this issue Sep 13, 2023
proj.db opening: allow opening with a URI (typically for memvfs) (fixes #3887)
rouault added a commit that referenced this issue Sep 14, 2023
[Backport 9.3] proj.db opening: allow opening with a URI (typically for memvfs) (fixes #3887)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant