Skip to content

Commit 3d186fb

Browse files
committed
Added retuning version of insert and insert_bulk
1 parent 3dd94f7 commit 3d186fb

File tree

1 file changed

+251
-0
lines changed

1 file changed

+251
-0
lines changed

src/lib.rs

Lines changed: 251 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1541,6 +1541,257 @@ pub extern "C" fn rorm_row_free(_: Box<Row>) {}
15411541
// INSERT
15421542
// --------
15431543

1544+
/**
1545+
This functions inserts a row into the database while returning the requested columns.
1546+
1547+
**Parameter**:
1548+
- `db`: Reference tot he Database, provided by [rorm_db_connect]
1549+
- `transaction`: Mutable pointer to a Transaction. Can be a null pointer to ignore this parameter.
1550+
- `model`: Name of the table to query.
1551+
- `columns`: Array of columns to insert to the table.
1552+
- `row`: List of values to insert. Must be of the same length as `columns`.
1553+
- `returning`: Array of column to return after for the insert operation.
1554+
- `callback`: callback function. Takes the `context` a pointer to a row and an [Error].
1555+
- `context`: Pass through void pointer.
1556+
1557+
**Important**:
1558+
- Make sure that `db`, `model`, `columns`, `row` and `returning` are allocated until the callback is executed.
1559+
- The Row that is returned in the callback is freed after the callback has ended.
1560+
1561+
This function is called from an asynchronous context.
1562+
*/
1563+
#[no_mangle]
1564+
pub extern "C" fn rorm_db_insert_returning(
1565+
db: &'static Database,
1566+
transaction: Option<&'static mut Transaction>,
1567+
model: FFIString<'static>,
1568+
columns: FFISlice<'static, FFIString<'static>>,
1569+
row: FFISlice<'static, FFIValue<'static>>,
1570+
returning: FFISlice<'static, FFIString<'static>>,
1571+
callback: Option<unsafe extern "C" fn(VoidPtr, Option<Box<Row>>, Error) -> ()>,
1572+
context: VoidPtr,
1573+
) {
1574+
let cb = callback.expect("Callback must not be empty");
1575+
1576+
let Ok(model) = model.try_into() else {
1577+
unsafe { cb(context, None, Error::InvalidStringError) };
1578+
return;
1579+
};
1580+
1581+
let mut column_vec = vec![];
1582+
{
1583+
let column_slice: &[FFIString] = columns.into();
1584+
for &x in column_slice {
1585+
let Ok(v) = x.try_into() else {
1586+
unsafe { cb(context, None, Error::InvalidStringError) };
1587+
return;
1588+
};
1589+
column_vec.push(v);
1590+
}
1591+
}
1592+
1593+
let mut value_vec = vec![];
1594+
{
1595+
let value_slice: &[FFIValue] = row.into();
1596+
for x in value_slice {
1597+
let x_conv = x.try_into();
1598+
if x_conv.is_err() {
1599+
match x_conv.as_ref().err().unwrap() {
1600+
Error::InvalidStringError
1601+
| Error::InvalidDateError
1602+
| Error::InvalidTimeError
1603+
| Error::InvalidDateTimeError => unsafe {
1604+
cb(context, None, x_conv.err().unwrap())
1605+
},
1606+
_ => {}
1607+
}
1608+
return;
1609+
}
1610+
value_vec.push(x_conv.unwrap());
1611+
}
1612+
}
1613+
1614+
let mut returning_vec = vec![];
1615+
{
1616+
let returning_slice: &[FFIString] = returning.into();
1617+
for x in returning_slice {
1618+
let Ok(v) = x.try_into() else {
1619+
unsafe { cb(context, None, Error::InvalidStringError) };
1620+
return;
1621+
};
1622+
returning_vec.push(v);
1623+
}
1624+
}
1625+
1626+
let fut = async move {
1627+
match db
1628+
.insert_returning(
1629+
model,
1630+
column_vec.as_slice(),
1631+
value_vec.as_slice(),
1632+
transaction,
1633+
returning_vec.as_slice(),
1634+
)
1635+
.await
1636+
{
1637+
Err(err) => unsafe {
1638+
cb(
1639+
context,
1640+
None,
1641+
Error::DatabaseError(err.to_string().as_str().into()),
1642+
)
1643+
},
1644+
Ok(v) => unsafe { cb(context, Some(Box::new(v)), Error::NoError) },
1645+
};
1646+
};
1647+
1648+
let f = |err: String| {
1649+
unsafe { cb(context, None, Error::RuntimeError(err.as_str().into())) };
1650+
};
1651+
spawn_fut!(fut, cb(context, None, Error::MissingRuntimeError), f);
1652+
}
1653+
1654+
/**
1655+
This function inserts multiple rows into the database while returning the requested columns from all
1656+
inserted values.
1657+
1658+
**Parameter**:
1659+
- `db`: Reference to the Database, provided by [rorm_db_connect].
1660+
- `transaction`: Mutable pointer to a Transaction. Can be a null pointer to ignore this parameter.
1661+
- `model`: Name of the table to query.
1662+
- `columns`: Array of columns to insert to the table.
1663+
- `rows`: List of list of values to insert. The inner lists must be of the same length as `columns`.
1664+
- `returning`: Array of column to return after for the insert operation.
1665+
- `callback`: callback function. Takes the `context` and an [Error].
1666+
- `context`: Pass through void pointer.
1667+
1668+
**Important**:
1669+
- Make sure that `db`, `model`, `columns`, `rows` and `returning` are allocated until the callback is executed.
1670+
- The FFISlice returned in the callback is freed after the callback has ended.
1671+
1672+
This function is called from an asynchronous context.
1673+
*/
1674+
#[no_mangle]
1675+
pub extern "C" fn rorm_db_insert_bulk_returning(
1676+
db: &'static Database,
1677+
transaction: Option<&'static mut Transaction>,
1678+
model: FFIString<'static>,
1679+
columns: FFISlice<'static, FFIString<'static>>,
1680+
rows: FFISlice<'static, FFISlice<'static, FFIValue<'static>>>,
1681+
returning: FFISlice<'static, FFIString<'static>>,
1682+
callback: Option<unsafe extern "C" fn(VoidPtr, FFISlice<&Row>, Error) -> ()>,
1683+
context: VoidPtr,
1684+
) {
1685+
let cb = callback.expect("Callback must not be empty");
1686+
1687+
let model_conv = model.try_into();
1688+
if model_conv.is_err() {
1689+
unsafe { cb(context, FFISlice::empty(), Error::InvalidStringError) };
1690+
return;
1691+
}
1692+
let model = model_conv.unwrap();
1693+
1694+
let mut column_vec = vec![];
1695+
{
1696+
let column_slice: &[FFIString] = columns.into();
1697+
for &x in column_slice {
1698+
let x_conv = x.try_into();
1699+
if x_conv.is_err() {
1700+
unsafe { cb(context, FFISlice::empty(), Error::InvalidStringError) };
1701+
return;
1702+
}
1703+
column_vec.push(x_conv.unwrap());
1704+
}
1705+
}
1706+
1707+
let mut rows_vec = vec![];
1708+
{
1709+
let row_slices: &[FFISlice<FFIValue>] = rows.into();
1710+
for row in row_slices {
1711+
let mut row_vec = vec![];
1712+
let row_slice: &[FFIValue] = row.into();
1713+
for x in row_slice {
1714+
let val = x.try_into();
1715+
if val.is_err() {
1716+
match val.as_ref().err().unwrap() {
1717+
Error::InvalidStringError
1718+
| Error::InvalidDateError
1719+
| Error::InvalidTimeError
1720+
| Error::InvalidDateTimeError => unsafe {
1721+
cb(context, FFISlice::empty(), val.err().unwrap())
1722+
},
1723+
_ => {}
1724+
}
1725+
return;
1726+
}
1727+
row_vec.push(val.unwrap());
1728+
}
1729+
rows_vec.push(row_vec);
1730+
}
1731+
}
1732+
1733+
let mut returning_vec = vec![];
1734+
{
1735+
let returning_slice: &[FFIString] = returning.into();
1736+
for x in returning_slice {
1737+
let Ok(v) = x.try_into() else {
1738+
unsafe { cb(context, FFISlice::empty(), Error::InvalidStringError )}
1739+
return;
1740+
};
1741+
1742+
returning_vec.push(v);
1743+
}
1744+
}
1745+
1746+
let fut = async move {
1747+
match db
1748+
.insert_bulk_returning(
1749+
model,
1750+
column_vec.as_slice(),
1751+
rows_vec
1752+
.iter()
1753+
.map(|x| x.as_slice())
1754+
.collect::<Vec<&[Value]>>()
1755+
.as_slice(),
1756+
transaction,
1757+
returning_vec.as_slice(),
1758+
)
1759+
.await
1760+
{
1761+
Ok(v) => {
1762+
let rows: Vec<&Row> = v.iter().collect();
1763+
let slice = rows.as_slice().into();
1764+
unsafe { cb(context, slice, Error::NoError) }
1765+
}
1766+
Err(err) => {
1767+
let ffi_str = err.to_string();
1768+
unsafe {
1769+
cb(
1770+
context,
1771+
FFISlice::empty(),
1772+
Error::DatabaseError(ffi_str.as_str().into()),
1773+
)
1774+
};
1775+
}
1776+
}
1777+
};
1778+
1779+
let f = |err: String| {
1780+
unsafe {
1781+
cb(
1782+
context,
1783+
FFISlice::empty(),
1784+
Error::RuntimeError(err.as_str().into()),
1785+
)
1786+
};
1787+
};
1788+
spawn_fut!(
1789+
fut,
1790+
cb(context, FFISlice::empty(), Error::MissingRuntimeError),
1791+
f
1792+
);
1793+
}
1794+
15441795
/**
15451796
This function inserts a row into the database.
15461797

0 commit comments

Comments
 (0)