Skip to content

Pass binary filename to sqlite3_open #278

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

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added .DS_Store
Binary file not shown.
20 changes: 16 additions & 4 deletions c_src/sqlite3_nif.c
Original file line number Diff line number Diff line change
Expand Up @@ -191,33 +191,45 @@ exqlite_open(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
assert(env);

unsigned char* filename;
int flags;
int rc = 0;
int size = 0;
connection_t* conn = NULL;
sqlite3* db = NULL;
ErlNifMutex* mutex = NULL;
char filename[MAX_PATHNAME];
ErlNifBinary filename_binary;
ERL_NIF_TERM result;

if (argc != 2) {
return enif_make_badarg(env);
}

size = enif_get_string(env, argv[0], filename, MAX_PATHNAME, ERL_NIF_LATIN1);
if (size <= 0) {
if (!enif_inspect_binary(env, argv[0], &filename_binary)) {
return make_error_tuple(env, "invalid_filename");
}

filename = (unsigned char*)sqlite3_malloc(filename_binary.size + sizeof(unsigned char));
if (!filename) {
return make_error_tuple(env, "out_of_memory ");
}

memcpy(filename, filename_binary.data, filename_binary.size);
filename[filename_binary.size] = '\0';

if (!enif_get_int(env, argv[1], &flags)) {
return make_error_tuple(env, "invalid flags");
sqlite3_free(filename);
return make_error_tuple(env, "invalid_flags");
}

rc = sqlite3_open_v2(filename, &db, flags, NULL);
if (rc != SQLITE_OK) {
sqlite3_free(filename);
return make_error_tuple(env, "database_open_failed");
}

sqlite3_free(filename);

mutex = enif_mutex_create("exqlite:connection");
if (mutex == NULL) {
sqlite3_close_v2(db);
Expand Down
2 changes: 1 addition & 1 deletion lib/exqlite/sqlite3.ex
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ defmodule Exqlite.Sqlite3 do
@spec open(String.t(), [open_opt()]) :: {:ok, db()} | {:error, reason()}
def open(path, opts \\ []) do
mode = Keyword.get(opts, :mode, :readwrite)
Sqlite3NIF.open(String.to_charlist(path), flags_from_mode(mode))
Sqlite3NIF.open(path, flags_from_mode(mode))
end

defp flags_from_mode(:readwrite),
Expand Down
10 changes: 10 additions & 0 deletions test/exqlite/connection_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,16 @@ defmodule Exqlite.ConnectionTest do
assert state.db
end

test "connects to a file with an accented character" do
path = Temp.path!(prefix: "databasé")
{:ok, state} = Connection.connect(database: path)

assert state.path == path
assert state.db

File.rm(path)
end

test "fails to write a file from URL with mode=ro" do
path = Temp.path!()

Expand Down