Skip to content

Commit 650edca

Browse files
authored
Merge pull request #45 from SpringQL/build/0.13.0
feat: 0.13.0
2 parents f8d67bf + 661d147 commit 650edca

File tree

8 files changed

+164
-16
lines changed

8 files changed

+164
-16
lines changed

.github/workflows/ci.yml

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ jobs:
2222
rust:
2323
- nightly
2424
- stable
25-
- 1.56.0 # MSRV
25+
- 1.57.0 # MSRV
2626
make:
2727
- name: format
2828
task: format
@@ -48,37 +48,37 @@ jobs:
4848
- rust: nightly
4949
make:
5050
name: format
51-
- rust: 1.56.0
51+
- rust: 1.57.0
5252
make:
5353
name: format
5454
- rust: nightly
5555
make:
5656
name: lint
57-
- rust: 1.56.0
57+
- rust: 1.57.0
5858
make:
5959
name: lint
6060
- rust: nightly
6161
make:
6262
name: doc
63-
- rust: 1.56.0
63+
- rust: 1.57.0
6464
make:
6565
name: doc
6666
- rust: nightly
6767
make:
6868
name: deadlink
69-
- rust: 1.56.0
69+
- rust: 1.57.0
7070
make:
7171
name: deadlink
7272
- rust: stable
7373
make:
7474
name: codecov
75-
- rust: 1.56.0
75+
- rust: 1.57.0
7676
make:
7777
name: codecov
7878
- rust: nightly
7979
make:
8080
name: copyright
81-
- rust: 1.56.0
81+
- rust: 1.57.0
8282
make:
8383
name: copyright
8484
env:

CHANGELOG.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,13 @@ Also check the changes in springql-core: <https://github.com/SpringQL/SpringQL/b
1313
<!-- markdownlint-disable MD024 -->
1414
## [Unreleased]
1515

16+
## [v0.13.0]
17+
18+
### Added
19+
20+
- `spring_column_blob()` and `spring_column_unsigned_int()`. ([#45](https://github.com/SpringQL/SpringQL-client-c/pull/45))
21+
- `SpringErrno::Time` error number. ([#45](https://github.com/SpringQL/SpringQL-client-c/pull/45))
22+
1623
## [v0.12.0]
1724

1825
### For developers
@@ -54,8 +61,9 @@ Depends on springql-core v0.7.1.
5461
[Semantic Versioning]: https://semver.org/
5562

5663
<!-- Versions -->
57-
[Unreleased]: https://github.com/SpringQL/SpringQL-client-c/compare/v0.12.0...HEAD
64+
[Unreleased]: https://github.com/SpringQL/SpringQL-client-c/compare/v0.13.0...HEAD
5865
[Released]: https://github.com/SpringQL/SpringQL-client-c/releases
66+
[v0.13.0]: https://github.com/SpringQL/SpringQL-client-c/compare/v0.12.0...v0.13.0
5967
[v0.12.0]: https://github.com/SpringQL/SpringQL-client-c/compare/v0.11.0...v0.12.0
6068
[v0.11.0]: https://github.com/SpringQL/SpringQL-client-c/compare/v0.9.0+2...v0.11.0
6169
[v0.9.0+2]: https://github.com/SpringQL/SpringQL-client-c/compare/v0.9.0...v0.9.0+2

Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "springql-client-c"
3-
version = "0.12.0"
3+
version = "0.13.0"
44

55
authors = ["Sho Nakatani <[email protected]>"]
66
license = "MIT OR Apache-2.0"
@@ -15,6 +15,6 @@ name = "springql_client"
1515
cbindgen = "0.23"
1616

1717
[dependencies]
18-
springql-core = "0.12.0"
18+
springql-core = "0.13.0"
1919

2020
log = "0.4"

springql.h

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ typedef enum SpringErrno {
2525
Sql = -10,
2626
InvalidConfig = -11,
2727
Null = -12,
28+
Time = -13,
2829
/**
2930
* Insufficient buffer size
3031
*/
@@ -227,6 +228,27 @@ enum SpringErrno spring_column_int(const SpringRow *row, uint16_t i_col, int *ou
227228
*/
228229
enum SpringErrno spring_column_long(const SpringRow *row, uint16_t i_col, long *out);
229230

231+
/**
232+
* Get a 4-byte unsigned integer column.
233+
*
234+
* # Parameters
235+
*
236+
* - `row`: A `SpringRow` pointer to get a column value from.
237+
* - `i_col`: The column index to get a value from.
238+
* - `out`: A pointer to a buffer to store the column value.
239+
*
240+
* # Returns
241+
*
242+
* - `Ok`: On success.
243+
* - `Unavailable`:
244+
* - Column pointed by `i_col` is already fetched.
245+
* - `i_col` is out of range.
246+
* - `CNull`: Column value is NULL.
247+
*/
248+
enum SpringErrno spring_column_unsigned_int(const SpringRow *row,
249+
uint16_t i_col,
250+
unsigned int *out);
251+
230252
/**
231253
* Get a text column.
232254
*
@@ -247,6 +269,26 @@ enum SpringErrno spring_column_long(const SpringRow *row, uint16_t i_col, long *
247269
*/
248270
int spring_column_text(const SpringRow *row, uint16_t i_col, char *out, int out_len);
249271

272+
/**
273+
* Get a BLOB column.
274+
*
275+
* # Parameters
276+
*
277+
* - `row`: A `SpringRow` pointer to get a column value from.
278+
* - `i_col`: The column index to get a value from.
279+
* - `out`: A pointer to a buffer to store the column value.
280+
* - `out_len`: The length of the buffer pointed by `out`.
281+
*
282+
* # Returns
283+
*
284+
* - `> 0`: Length of the text.
285+
* - `Unavailable`:
286+
* - Column pointed by `i_col` is already fetched.
287+
* - `i_col` is out of range.
288+
* - `CNull`: Column value is NULL.
289+
*/
290+
int spring_column_blob(const SpringRow *row, uint16_t i_col, void *out, int out_len);
291+
250292
/**
251293
* Get a bool column.
252294
*

src/cstr.rs renamed to src/c_mem.rs

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
use std::{
44
os::raw::{c_char, c_int},
5-
ptr, slice,
5+
ptr, slice, ffi::c_void,
66
};
77

88
use log::warn;
@@ -35,3 +35,30 @@ pub(super) fn strcpy(src: &str, dest_buf: *mut c_char, dest_len: c_int) -> c_int
3535

3636
src.len() as c_int
3737
}
38+
39+
/// # Returns
40+
///
41+
/// - `> 0`: the length of `src`.
42+
/// - `< 0`: SpringErrno
43+
pub(super) fn memcpy(src: &[u8], dest_buf: *mut c_void, dest_len: c_int) -> c_int {
44+
if src.len() >= dest_len as usize {
45+
warn!("dest_len is smaller than src.");
46+
warn!(
47+
"Expected at least {} bytes but got {}",
48+
src.len() + 1,
49+
dest_len
50+
);
51+
return SpringErrno::CInsufficient as c_int;
52+
}
53+
54+
let buffer = unsafe { slice::from_raw_parts_mut(dest_buf as *mut u8, dest_len as usize) };
55+
unsafe {
56+
ptr::copy_nonoverlapping(src.as_ptr(), buffer.as_mut_ptr(), src.len());
57+
}
58+
59+
// Add a trailing null so people using the string as a `char *` don't
60+
// accidentally read into garbage.
61+
buffer[src.len()] = 0;
62+
63+
src.len() as c_int
64+
}

src/lib.rs

Lines changed: 73 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,22 @@
44
55
#![allow(clippy::missing_safety_doc)] // C header file does not need `Safety` section
66

7-
pub(crate) mod cstr;
7+
pub(crate) mod c_mem;
88
mod spring_config;
99
pub mod spring_errno;
1010
pub mod spring_last_err;
1111
mod spring_pipeline;
1212
mod spring_row;
1313

1414
use std::{
15-
ffi::CStr,
16-
os::raw::{c_char, c_float, c_int, c_long, c_short},
15+
ffi::{c_void, CStr},
16+
os::raw::{c_char, c_float, c_int, c_long, c_short, c_uint},
1717
panic::{catch_unwind, UnwindSafe},
1818
ptr,
1919
};
2020

2121
use crate::{
22-
cstr::strcpy,
22+
c_mem::{memcpy, strcpy},
2323
spring_config::SpringConfig,
2424
spring_errno::SpringErrno,
2525
spring_last_err::{update_last_error, LastError},
@@ -327,6 +327,39 @@ pub unsafe extern "C" fn spring_column_long(
327327
}
328328
}
329329

330+
/// Get a 4-byte unsigned integer column.
331+
///
332+
/// # Parameters
333+
///
334+
/// - `row`: A `SpringRow` pointer to get a column value from.
335+
/// - `i_col`: The column index to get a value from.
336+
/// - `out`: A pointer to a buffer to store the column value.
337+
///
338+
/// # Returns
339+
///
340+
/// - `Ok`: On success.
341+
/// - `Unavailable`:
342+
/// - Column pointed by `i_col` is already fetched.
343+
/// - `i_col` is out of range.
344+
/// - `CNull`: Column value is NULL.
345+
#[no_mangle]
346+
pub unsafe extern "C" fn spring_column_unsigned_int(
347+
row: *const SpringRow,
348+
i_col: u16,
349+
out: *mut c_uint,
350+
) -> SpringErrno {
351+
let row = (*row).as_row();
352+
let i_col = i_col as usize;
353+
let result = with_catch(|| row.get_not_null_by_index(i_col as usize));
354+
match result {
355+
Ok(v) => {
356+
*out = v;
357+
SpringErrno::Ok
358+
}
359+
Err(e) => e,
360+
}
361+
}
362+
330363
/// Get a text column.
331364
///
332365
/// # Parameters
@@ -363,6 +396,42 @@ pub unsafe extern "C" fn spring_column_text(
363396
}
364397
}
365398

399+
/// Get a BLOB column.
400+
///
401+
/// # Parameters
402+
///
403+
/// - `row`: A `SpringRow` pointer to get a column value from.
404+
/// - `i_col`: The column index to get a value from.
405+
/// - `out`: A pointer to a buffer to store the column value.
406+
/// - `out_len`: The length of the buffer pointed by `out`.
407+
///
408+
/// # Returns
409+
///
410+
/// - `> 0`: Length of the text.
411+
/// - `Unavailable`:
412+
/// - Column pointed by `i_col` is already fetched.
413+
/// - `i_col` is out of range.
414+
/// - `CNull`: Column value is NULL.
415+
#[no_mangle]
416+
pub unsafe extern "C" fn spring_column_blob(
417+
row: *const SpringRow,
418+
i_col: u16,
419+
out: *mut c_void,
420+
out_len: c_int,
421+
) -> c_int {
422+
let row = (*row).as_row();
423+
let i_col = i_col as usize;
424+
let result: Result<Vec<u8>, SpringErrno> =
425+
with_catch(|| row.get_not_null_by_index(i_col as usize));
426+
match result {
427+
Ok(v) => {
428+
let v_len = memcpy(&v, out, out_len);
429+
v_len as c_int
430+
}
431+
Err(e) => e as c_int,
432+
}
433+
}
434+
366435
/// Get a bool column.
367436
///
368437
/// # Parameters

src/spring_errno.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ pub enum SpringErrno {
2424
Sql = -10,
2525
InvalidConfig = -11,
2626
Null = -12,
27+
Time = -13,
2728

2829
/// Insufficient buffer size
2930
CInsufficient = -126,
@@ -45,6 +46,7 @@ impl From<&SpringError> for SpringErrno {
4546
SpringError::Sql(_) => SpringErrno::Sql,
4647
SpringError::InvalidConfig { .. } => SpringErrno::InvalidConfig,
4748
SpringError::Null { .. } => SpringErrno::Null,
49+
SpringError::Time(_) => SpringErrno::Time,
4850
}
4951
}
5052
}

src/spring_last_err.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use std::{
1111
use ::log::{info, warn};
1212
use ::springql_core::api::error::SpringError;
1313

14-
use crate::{cstr::strcpy, spring_errno::SpringErrno};
14+
use crate::{c_mem::strcpy, spring_errno::SpringErrno};
1515

1616
thread_local! {
1717
static LAST_ERROR: RefCell<Option<LastError>> = RefCell::new(None);

0 commit comments

Comments
 (0)