| 255 | } |
| 256 | |
| 257 | pub async fn create(d: Device) -> Result<Device, Error> { |
| 258 | let mut c = get_async_db_conn().await?; |
| 259 | let d: Device = c |
| 260 | .transaction::<Device, Error, _>(async |c| { |
| 261 | let query = tenant::dsl::tenant |
| 262 | .select(tenant::all_columns) |
| 263 | .inner_join(application::table) |
| 264 | .filter(application::dsl::id.eq(&d.application_id)); |
| 265 | // use for update to lock the tenant |
| 266 | #[cfg(feature = "postgres")] |
| 267 | let query = query.for_update(); |
| 268 | let t: super::tenant::Tenant = query.first(c).await?; |
| 269 | |
| 270 | let dev_count: i64 = device::dsl::device |
| 271 | .select(dsl::count_star()) |
| 272 | .inner_join(application::table) |
| 273 | .filter(application::dsl::tenant_id.eq(&t.id)) |
| 274 | .first(c) |
| 275 | .await?; |
| 276 | |
| 277 | if t.max_device_count != 0 && dev_count as i32 >= t.max_device_count { |
| 278 | return Err(Error::NotAllowed( |
| 279 | "Max number of devices exceeded for tenant".into(), |
| 280 | )); |
| 281 | } |
| 282 | |
| 283 | diesel::insert_into(device::table) |
| 284 | .values(&d) |
| 285 | .get_result(c) |
| 286 | .await |
| 287 | .map_err(|e| Error::from_diesel(e, d.dev_eui.to_string())) |
| 288 | }) |
| 289 | .await?; |
| 290 | info!(dev_eui = %d.dev_eui, "Device created"); |
| 291 | Ok(d) |
| 292 | } |
| 293 | |
| 294 | pub async fn get(dev_eui: &EUI64) -> Result<Device, Error> { |
| 295 | let d = device::dsl::device |