The big sqlite refactor

* refactor: safe sql access

* Clean up the worst rebase mistakes

* Some more progress on the rebase fallout and this branch

* upgrade and compile again

* cleanup from rebase

* example of how to prepare now

* rebase fixes

* add sql.query_map

* less preparation

* more improvements in sql code

* fix string truncation

* more prepare conversions

* most prep done

* fix tests

* fix ffi

* fix last prepares

* fix segfaults and some queries

* use r2d2 pool

* fix dc_job sql call, to reduce contention

* try newer rust

* No more vararg printing (drop dc_log_)

* ignore expected errors

* fix: uses exists instead of execute where needed

* fix: get_contacts logic was broken

* fix: contact creation

* test on 32bit linux

* ci: try running 32bit without cross

* undo 32bit tests

* refactor: rename dc_sqlite3 to sql

* fix: safer string conversions

* more string fixes

* try fixing appveyor build to 64bit

* chore(ci): hardcode target

* chore(ci): appveyor

* some cleanup work

* try fix darwin

* fix and improve sql escaping

* fix various bugs

* fix chat deletion

* refactor: cleanup config values and move to their own file

* refactor: move more methods onto the sql struct

* dont panic on failed state loading

* first round of cr

* one more cr fix

* stop using strange defaults

* remove unused escapes
This commit is contained in:
Friedel Ziegelmayer
2019-07-18 00:24:45 +02:00
committed by GitHub
parent 3e3403d3d7
commit 8a0fc609e6
47 changed files with 7356 additions and 9608 deletions

View File

@@ -1,76 +1,65 @@
use crate::context::Context;
use crate::dc_sqlite3::*;
use crate::dc_tools::*;
use crate::types::*;
use crate::sql;
use crate::x::strdup;
// Token namespaces
pub type dc_tokennamespc_t = libc::c_uint;
pub type dc_tokennamespc_t = usize;
pub const DC_TOKEN_AUTH: dc_tokennamespc_t = 110;
pub const DC_TOKEN_INVITENUMBER: dc_tokennamespc_t = 100;
// Functions to read/write token from/to the database. A token is any string associated with a key.
pub unsafe fn dc_token_save(
pub fn dc_token_save(
context: &Context,
namespc: dc_tokennamespc_t,
foreign_id: uint32_t,
foreign_id: u32,
token: *const libc::c_char,
) {
let mut stmt: *mut sqlite3_stmt = 0 as *mut sqlite3_stmt;
if !token.is_null() {
// foreign_id may be 0
stmt = dc_sqlite3_prepare(
context,
&context.sql,
b"INSERT INTO tokens (namespc, foreign_id, token, timestamp) VALUES (?, ?, ?, ?);\x00"
as *const u8 as *const libc::c_char,
);
sqlite3_bind_int(stmt, 1i32, namespc as libc::c_int);
sqlite3_bind_int(stmt, 2i32, foreign_id as libc::c_int);
sqlite3_bind_text(stmt, 3i32, token, -1i32, None);
sqlite3_bind_int64(stmt, 4i32, time() as sqlite3_int64);
sqlite3_step(stmt);
) -> bool {
if token.is_null() {
return false;
}
sqlite3_finalize(stmt);
}
pub unsafe fn dc_token_lookup(
context: &Context,
namespc: dc_tokennamespc_t,
foreign_id: uint32_t,
) -> *mut libc::c_char {
let token: *mut libc::c_char;
let stmt: *mut sqlite3_stmt;
stmt = dc_sqlite3_prepare(
// foreign_id may be 0
sql::execute(
context,
&context.sql,
b"SELECT token FROM tokens WHERE namespc=? AND foreign_id=?;\x00" as *const u8
as *const libc::c_char,
);
sqlite3_bind_int(stmt, 1i32, namespc as libc::c_int);
sqlite3_bind_int(stmt, 2i32, foreign_id as libc::c_int);
sqlite3_step(stmt);
token = dc_strdup_keep_null(sqlite3_column_text(stmt, 0i32) as *mut libc::c_char);
sqlite3_finalize(stmt);
token
"INSERT INTO tokens (namespc, foreign_id, token, timestamp) VALUES (?, ?, ?, ?);",
params![namespc as i32, foreign_id as i32, as_str(token), time()],
)
.is_ok()
}
pub unsafe fn dc_token_exists(
pub fn dc_token_lookup(
context: &Context,
namespc: dc_tokennamespc_t,
foreign_id: u32,
) -> *mut libc::c_char {
if let Some(token) = context.sql.query_row_col::<_, String>(
context,
"SELECT token FROM tokens WHERE namespc=? AND foreign_id=?;",
params![namespc as i32, foreign_id as i32],
0,
) {
unsafe { strdup(to_cstring(token).as_ptr()) }
} else {
std::ptr::null_mut()
}
}
pub fn dc_token_exists(
context: &Context,
namespc: dc_tokennamespc_t,
token: *const libc::c_char,
) -> libc::c_int {
let mut exists: libc::c_int = 0i32;
let mut stmt: *mut sqlite3_stmt = 0 as *mut sqlite3_stmt;
if !token.is_null() {
stmt = dc_sqlite3_prepare(
context,
&context.sql,
b"SELECT id FROM tokens WHERE namespc=? AND token=?;\x00" as *const u8
as *const libc::c_char,
);
sqlite3_bind_int(stmt, 1i32, namespc as libc::c_int);
sqlite3_bind_text(stmt, 2i32, token, -1i32, None);
exists = (sqlite3_step(stmt) != 0i32) as libc::c_int
) -> bool {
if token.is_null() {
return false;
}
sqlite3_finalize(stmt);
return exists;
context
.sql
.exists(
"SELECT id FROM tokens WHERE namespc=? AND token=?;",
params![namespc as i32, as_str(token)],
)
.unwrap_or_default()
}