Update diesel to 2.0.0-rc.0.

Diesel 1.4.x makes it impossible to properly cross-compile when using
PostgreSQL and thus having a dependency on libpq. On compile and I
believe when using the diesel_migrations crate, there is a dependency on
both the host and target libpq. Unfortunately, only one can be installed
at a time, because of conflicts. See also:
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=995768

Until now the cross-compile solution is based on docker buildx, which
uses qemu to emulate the different targets. This works, but is very,
very slow.

Diesel 2.0.0-rc.0 no longer depends on both the host and target libpq on
compile and makes it possible to implement proper cross-compiling (using
the rust --target flag in combination with the cross-compile
toolchains).
This commit is contained in:
Orne Brocaar 2022-07-20 10:55:59 +01:00
parent 11d433a394
commit 634aea6a71
30 changed files with 644 additions and 614 deletions

86
Cargo.lock generated
View File

@ -676,11 +676,11 @@ dependencies = [
[[package]]
name = "bigdecimal"
version = "0.1.2"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1374191e2dd25f9ae02e3aa95041ed5d747fc77b3c102b49fe2dd9a8117a6244"
checksum = "6aaf33151a6429fe9211d1b276eafdf70cdff28b071e76c0b0e1503221ea3744"
dependencies = [
"num-bigint 0.2.6",
"num-bigint",
"num-integer",
"num-traits",
]
@ -821,9 +821,9 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
[[package]]
name = "bytes"
version = "1.1.0"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8"
checksum = "f0b3de4a0c5e67e16066a0715723abd91edc2f9001d09c46e1dca929351e130e"
[[package]]
name = "bytes-utils"
@ -1238,16 +1238,17 @@ dependencies = [
[[package]]
name = "diesel"
version = "1.4.8"
version = "2.0.0-rc.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b28135ecf6b7d446b43e27e225622a038cc4e2930a1022f51cdb97ada19b8e4d"
checksum = "e531d0abf8147036383c88ce3785d9cda6fe1b8b1183021ffa01cf49c5819d24"
dependencies = [
"bigdecimal",
"bitflags",
"byteorder",
"chrono",
"diesel_derives",
"num-bigint 0.2.6",
"itoa 1.0.2",
"num-bigint",
"num-integer",
"num-traits",
"pq-sys",
@ -1258,10 +1259,11 @@ dependencies = [
[[package]]
name = "diesel_derives"
version = "1.4.1"
version = "2.0.0-rc.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "45f5098f628d02a7a0f68ddba586fb61e80edec3bdc1be3b921f4ceec60858d3"
checksum = "212ba0cdc611523c37f26c7b3b4aedb4af7cbfe9239c4e7736a8a7c82284d77b"
dependencies = [
"proc-macro-error",
"proc-macro2",
"quote",
"syn",
@ -1269,10 +1271,11 @@ dependencies = [
[[package]]
name = "diesel_migrations"
version = "1.4.0"
version = "2.0.0-rc.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf3cde8413353dc7f5d72fa8ce0b99a560a359d2c5ef1e5817ca731cd9008f4c"
checksum = "e2edcb7e9cff76af48e7fa33cc4680acc7df19e58a4a4aaed3e2b67fb83bc06d"
dependencies = [
"diesel",
"migrations_internals",
"migrations_macros",
]
@ -2256,23 +2259,23 @@ checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
[[package]]
name = "migrations_internals"
version = "1.4.1"
version = "2.0.0-rc.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b4fc84e4af020b837029e017966f86a1c2d5e83e64b589963d5047525995860"
checksum = "61e2226081f9176165a49b006a0729de8cafa749615b349e15c444dbd39e4d9d"
dependencies = [
"diesel",
"serde",
"toml",
]
[[package]]
name = "migrations_macros"
version = "1.4.2"
version = "2.0.0-rc.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9753f12909fd8d923f75ae5c3258cae1ed3c8ec052e1b38c93c21a6d157f789c"
checksum = "37dbadac6f186c134552cd9a0ec14b157cf4f04eacacebd5e6c1bfc6aeb158b3"
dependencies = [
"migrations_internals",
"proc-macro2",
"quote",
"syn",
]
[[package]]
@ -2367,17 +2370,6 @@ dependencies = [
"minimal-lexical",
]
[[package]]
name = "num-bigint"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304"
dependencies = [
"autocfg",
"num-integer",
"num-traits",
]
[[package]]
name = "num-bigint"
version = "0.4.3"
@ -2497,7 +2489,7 @@ dependencies = [
"http",
"itertools",
"log",
"num-bigint 0.4.3",
"num-bigint",
"oauth2",
"rand",
"ring",
@ -2880,9 +2872,9 @@ checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872"
[[package]]
name = "pq-sys"
version = "0.4.6"
version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ac25eee5a0582f45a67e837e350d784e7003bd29a5f460796772061ca49ffda"
checksum = "3b845d6d8ec554f972a2c5298aad68953fd64e7441e846075450b44656a016d1"
dependencies = [
"pkg-config",
"vcpkg",
@ -2914,6 +2906,30 @@ dependencies = [
"toml",
]
[[package]]
name = "proc-macro-error"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
dependencies = [
"proc-macro-error-attr",
"proc-macro2",
"quote",
"syn",
"version_check",
]
[[package]]
name = "proc-macro-error-attr"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
dependencies = [
"proc-macro2",
"quote",
"version_check",
]
[[package]]
name = "proc-macro2"
version = "1.0.40"
@ -3714,7 +3730,7 @@ version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "adc4e5204eb1910f40f9cfa375f6f05b68c3abac4b6fd879c8ff5e7ae8a0a085"
dependencies = [
"num-bigint 0.4.3",
"num-bigint",
"num-traits",
"thiserror",
"time 0.3.11",
@ -4492,9 +4508,9 @@ checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
[[package]]
name = "uuid"
version = "0.8.2"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7"
checksum = "dd6469f4314d5f1ffec476e05f17cc9a78bc7a27a6a857842170bdf8d6f98d2f"
dependencies = [
"getrandom",
"serde",

View File

@ -25,7 +25,7 @@ RUN apt-get update && \
RUN rustup component add rustfmt clippy
RUN cargo install diesel_cli --no-default-features --features postgres
RUN cargo install diesel_cli --version 2.0.0-rc.0 --no-default-features --features postgres
RUN cargo install cargo-deb
RUN cargo install cargo-rpm

View File

@ -23,10 +23,10 @@ handlebars = "4.1"
# Database
validator = "0.13"
diesel = { version = "1.4", features = [ "chrono", "postgres", "r2d2", "uuidv07", "serde_json", "numeric" ] }
diesel_migrations = { version = "1.4" }
diesel = { version = "2.0.0-rc.0", features = [ "chrono", "postgres", "r2d2", "uuid", "serde_json", "numeric" ] }
diesel_migrations = { version = "2.0.0-rc.0" }
r2d2 = "0.8"
bigdecimal = "0.1.2"
bigdecimal = "0.3"
redis = { version = "0.21", features = ["r2d2", "cluster"] }
pq-sys = { version = "0.4.6", features = ["pkg-config"] }
@ -98,7 +98,7 @@ rquickjs = { version = "0.1.6", features = ["bindgen", "loader", "array-buffer",
# Misc
lazy_static = "1.4"
uuid = { version = "0.8", features = [ "v4", "serde" ] }
uuid = { version = "1.1", features = [ "v4", "serde" ] }
chrono = "0.4"
async-trait = "0.1"
aes = "0.7"

View File

@ -96,12 +96,12 @@ impl Validator for ValidateActiveUser {
let id = *id;
move || -> Result<i64, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let count = user::dsl::user
.select(dsl::count_star())
.find(id)
.filter(user::dsl::is_active.eq(true))
.first(&c)?;
.first(&mut c)?;
Ok(count)
}
})
@ -128,7 +128,7 @@ impl Validator for ValidateIsAdmin {
let id = *id;
move || -> Result<i64, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let count = user::dsl::user
.select(dsl::count_star())
.find(id)
@ -137,7 +137,7 @@ impl Validator for ValidateIsAdmin {
.eq(true)
.and(user::dsl::is_admin.eq(true)),
)
.first(&c)?;
.first(&mut c)?;
Ok(count)
}
})
@ -163,7 +163,7 @@ impl Validator for ValidateUsersAccess {
let flag = self.flag;
move || -> Result<i64, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let mut q = user::dsl::user
.select(dsl::count_star())
.find(&id)
@ -180,7 +180,7 @@ impl Validator for ValidateUsersAccess {
}
}
Ok(q.first(&c)?)
Ok(q.first(&mut c)?)
}
})
.await?
@ -190,13 +190,13 @@ impl Validator for ValidateUsersAccess {
task::spawn_blocking({
let id = *id;
move || -> Result<i64, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
// admin api key
let count = api_key::dsl::api_key
.select(dsl::count_star())
.find(&id)
.filter(api_key::dsl::is_admin.eq(true))
.first(&c)?;
.first(&mut c)?;
Ok(count)
}
})
@ -224,7 +224,7 @@ impl Validator for ValidateUserAccess {
let flag = self.flag;
move || {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let mut q = user::dsl::user
.select(dsl::count_star())
.find(&id)
@ -246,7 +246,7 @@ impl Validator for ValidateUserAccess {
}
}
Ok(q.first(&c)?)
Ok(q.first(&mut c)?)
}
})
.await?
@ -256,13 +256,13 @@ impl Validator for ValidateUserAccess {
task::spawn_blocking({
let id = *id;
move || -> Result<i64, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
// admin api key
let count = api_key::dsl::api_key
.select(dsl::count_star())
.find(&id)
.filter(api_key::dsl::is_admin.eq(true))
.first(&c)?;
.first(&mut c)?;
Ok(count)
}
})
@ -296,7 +296,7 @@ impl Validator for ValidateApiKeysAccess {
let flag = self.flag;
move || -> Result<i64, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let mut q = user::dsl::user
.select(dsl::count_star())
@ -328,7 +328,7 @@ impl Validator for ValidateApiKeysAccess {
}
};
Ok(q.first(&c)?)
Ok(q.first(&mut c)?)
}
})
.await?
@ -359,7 +359,7 @@ impl Validator for ValidateApiKeyAccess {
let flag = self.flag;
move || -> Result<i64, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let mut q = user::dsl::user
.select(dsl::count_star())
@ -384,7 +384,7 @@ impl Validator for ValidateApiKeyAccess {
}
};
Ok(q.first(&c)?)
Ok(q.first(&mut c)?)
}
})
.await?
@ -413,7 +413,7 @@ impl Validator for ValidateTenantsAccess {
let flag = self.flag;
move || -> Result<i64, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let mut q = user::dsl::user
.select(dsl::count_star())
@ -433,7 +433,7 @@ impl Validator for ValidateTenantsAccess {
}
};
Ok(q.first(&c)?)
Ok(q.first(&mut c)?)
}
})
.await?
@ -443,13 +443,13 @@ impl Validator for ValidateTenantsAccess {
task::spawn_blocking({
let id = *id;
move || -> Result<i64, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
// admin api key
let count = api_key::dsl::api_key
.select(dsl::count_star())
.find(&id)
.filter(api_key::dsl::is_admin.eq(true))
.first(&c)?;
.first(&mut c)?;
Ok(count)
}
})
@ -477,7 +477,7 @@ impl Validator for ValidateTenantAccess {
let tenant_id = self.tenant_id;
move || -> Result<i64, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let mut q = user::dsl::user
.select(dsl::count_star())
@ -501,7 +501,7 @@ impl Validator for ValidateTenantAccess {
}
};
Ok(q.first(&c)?)
Ok(q.first(&mut c)?)
}
})
.await?
@ -514,7 +514,7 @@ impl Validator for ValidateTenantAccess {
let tenant_id = self.tenant_id;
move || -> Result<i64, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let mut q = api_key::dsl::api_key
.select(dsl::count_star())
@ -540,7 +540,7 @@ impl Validator for ValidateTenantAccess {
}
};
Ok(q.first(&c)?)
Ok(q.first(&mut c)?)
}
})
.await?
@ -567,7 +567,7 @@ impl Validator for ValidateTenantUsersAccess {
let tenant_id = self.tenant_id;
move || -> Result<i64, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let mut q = user::dsl::user
.select(dsl::count_star())
.left_join(tenant_user::table.left_join(tenant::table))
@ -598,7 +598,7 @@ impl Validator for ValidateTenantUsersAccess {
}
};
Ok(q.first(&c)?)
Ok(q.first(&mut c)?)
}
})
.await?
@ -611,7 +611,7 @@ impl Validator for ValidateTenantUsersAccess {
let tenant_id = self.tenant_id;
move || -> Result<i64, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let mut q = api_key::dsl::api_key
.select(dsl::count_star())
.find(&id)
@ -632,7 +632,7 @@ impl Validator for ValidateTenantUsersAccess {
}
};
Ok(q.first(&c)?)
Ok(q.first(&mut c)?)
}
})
.await?
@ -665,7 +665,7 @@ impl Validator for ValidateTenantUserAccess {
let user_id = self.user_id;
move || -> Result<i64, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let mut q = user::dsl::user
.select(dsl::count_star())
.left_join(tenant_user::table.left_join(tenant::table))
@ -702,7 +702,7 @@ impl Validator for ValidateTenantUserAccess {
}
};
Ok(q.first(&c)?)
Ok(q.first(&mut c)?)
}
})
.await?
@ -715,7 +715,7 @@ impl Validator for ValidateTenantUserAccess {
let tenant_id = self.tenant_id;
move || -> Result<i64, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let mut q = api_key::dsl::api_key
.select(dsl::count_star())
.find(&id)
@ -736,7 +736,7 @@ impl Validator for ValidateTenantUserAccess {
}
};
Ok(q.first(&c)?)
Ok(q.first(&mut c)?)
}
})
.await?
@ -763,7 +763,7 @@ impl Validator for ValidateApplicationsAccess {
let tenant_id = self.tenant_id;
move || -> Result<i64, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let mut q = user::dsl::user
.select(dsl::count_star())
.left_join(tenant_user::table.left_join(tenant::table))
@ -800,7 +800,7 @@ impl Validator for ValidateApplicationsAccess {
}
};
Ok(q.first(&c)?)
Ok(q.first(&mut c)?)
}
})
.await?
@ -813,7 +813,7 @@ impl Validator for ValidateApplicationsAccess {
let tenant_id = self.tenant_id;
move || -> Result<i64, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let mut q = api_key::dsl::api_key
.select(dsl::count_star())
.find(&id)
@ -843,7 +843,7 @@ impl Validator for ValidateApplicationsAccess {
}
};
Ok(q.first(&c)?)
Ok(q.first(&mut c)?)
}
})
.await?
@ -873,7 +873,7 @@ impl Validator for ValidateApplicationAccess {
let application_id = self.application_id;
move || -> Result<i64, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let mut q = user::dsl::user
.select(dsl::count_star())
.left_join(
@ -915,7 +915,7 @@ impl Validator for ValidateApplicationAccess {
}
};
Ok(q.first(&c)?)
Ok(q.first(&mut c)?)
}
})
.await?
@ -928,7 +928,7 @@ impl Validator for ValidateApplicationAccess {
let application_id = self.application_id;
move || -> Result<i64, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let mut q = api_key::dsl::api_key
.select(dsl::count_star())
.left_join(
@ -953,7 +953,7 @@ impl Validator for ValidateApplicationAccess {
}
};
Ok(q.first(&c)?)
Ok(q.first(&mut c)?)
}
})
.await?
@ -978,7 +978,7 @@ impl Validator for ValidateDeviceProfileTemplatesAccess {
let flag = self.flag;
move || -> Result<i64, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let mut q = user::dsl::user
.select(dsl::count_star())
.filter(user::dsl::id.eq(&id).and(user::dsl::is_active.eq(true)))
@ -996,7 +996,7 @@ impl Validator for ValidateDeviceProfileTemplatesAccess {
}
};
Ok(q.first(&c)?)
Ok(q.first(&mut c)?)
}
})
.await?
@ -1008,7 +1008,7 @@ impl Validator for ValidateDeviceProfileTemplatesAccess {
let flag = self.flag;
move || -> Result<i64, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let mut q = api_key::dsl::api_key
.select(dsl::count_star())
.find(&id)
@ -1026,7 +1026,7 @@ impl Validator for ValidateDeviceProfileTemplatesAccess {
}
};
Ok(q.first(&c)?)
Ok(q.first(&mut c)?)
}
})
.await?
@ -1056,7 +1056,7 @@ impl Validator for ValidateDeviceProfileTemplateAccess {
let flag = self.flag;
move || -> Result<i64, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let mut q = user::dsl::user
.select(dsl::count_star())
.filter(user::dsl::id.eq(&id).and(user::dsl::is_active.eq(true)))
@ -1074,7 +1074,7 @@ impl Validator for ValidateDeviceProfileTemplateAccess {
}
};
Ok(q.first(&c)?)
Ok(q.first(&mut c)?)
}
})
.await?
@ -1086,7 +1086,7 @@ impl Validator for ValidateDeviceProfileTemplateAccess {
let flag = self.flag;
move || -> Result<i64, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let mut q = api_key::dsl::api_key
.select(dsl::count_star())
.find(&id)
@ -1104,7 +1104,7 @@ impl Validator for ValidateDeviceProfileTemplateAccess {
}
};
Ok(q.first(&c)?)
Ok(q.first(&mut c)?)
}
})
.await?
@ -1131,7 +1131,7 @@ impl Validator for ValidateDeviceProfilesAccess {
let tenant_id = self.tenant_id;
move || -> Result<i64, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let mut q = user::dsl::user
.select(dsl::count_star())
.left_join(tenant_user::table)
@ -1168,7 +1168,7 @@ impl Validator for ValidateDeviceProfilesAccess {
}
};
Ok(q.first(&c)?)
Ok(q.first(&mut c)?)
}
})
.await?
@ -1181,7 +1181,7 @@ impl Validator for ValidateDeviceProfilesAccess {
let tenant_id = self.tenant_id;
move || -> Result<i64, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let mut q = api_key::dsl::api_key
.select(dsl::count_star())
.find(&id)
@ -1202,7 +1202,7 @@ impl Validator for ValidateDeviceProfilesAccess {
}
};
Ok(q.first(&c)?)
Ok(q.first(&mut c)?)
}
})
.await?
@ -1232,7 +1232,7 @@ impl Validator for ValidateDeviceProfileAccess {
let device_profile_id = self.device_profile_id;
move || -> Result<i64, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let mut q = user::dsl::user
.select(dsl::count_star())
.left_join(
@ -1276,7 +1276,7 @@ impl Validator for ValidateDeviceProfileAccess {
}
};
Ok(q.first(&c)?)
Ok(q.first(&mut c)?)
}
})
.await?
@ -1289,7 +1289,7 @@ impl Validator for ValidateDeviceProfileAccess {
let device_profile_id = self.device_profile_id;
move || -> Result<i64, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let mut q =
api_key::dsl::api_key
.select(dsl::count_star())
@ -1314,7 +1314,7 @@ impl Validator for ValidateDeviceProfileAccess {
}
};
Ok(q.first(&c)?)
Ok(q.first(&mut c)?)
}
})
.await?
@ -1344,7 +1344,7 @@ impl Validator for ValidateDevicesAccess {
let application_id = self.application_id;
move || -> Result<i64, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let mut q = user::dsl::user
.select(dsl::count_star())
.left_join(
@ -1386,7 +1386,7 @@ impl Validator for ValidateDevicesAccess {
}
}
Ok(q.first(&c)?)
Ok(q.first(&mut c)?)
}
})
.await?
@ -1399,7 +1399,7 @@ impl Validator for ValidateDevicesAccess {
let application_id = self.application_id;
move || -> Result<i64, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let mut q = api_key::dsl::api_key
.select(dsl::count_star())
.left_join(
@ -1424,7 +1424,7 @@ impl Validator for ValidateDevicesAccess {
}
}
Ok(q.first(&c)?)
Ok(q.first(&mut c)?)
}
})
.await?
@ -1451,7 +1451,7 @@ impl Validator for ValidateDeviceAccess {
let dev_eui = self.dev_eui;
move || -> Result<i64, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let mut q = user::dsl::user
.select(dsl::count_star())
.left_join(
@ -1496,7 +1496,7 @@ impl Validator for ValidateDeviceAccess {
}
}
Ok(q.first(&c)?)
Ok(q.first(&mut c)?)
}
})
.await?
@ -1509,7 +1509,7 @@ impl Validator for ValidateDeviceAccess {
let dev_eui = self.dev_eui;
move || -> Result<i64, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let mut q = api_key::dsl::api_key
.select(dsl::count_star())
.left_join(
@ -1537,7 +1537,7 @@ impl Validator for ValidateDeviceAccess {
}
}
Ok(q.first(&c)?)
Ok(q.first(&mut c)?)
}
})
.await?
@ -1564,7 +1564,7 @@ impl Validator for ValidateDeviceQueueAccess {
let dev_eui = self.dev_eui;
move || -> Result<i64, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let mut q = user::dsl::user
.select(dsl::count_star())
.left_join(
@ -1594,7 +1594,7 @@ impl Validator for ValidateDeviceQueueAccess {
}
}
Ok(q.first(&c)?)
Ok(q.first(&mut c)?)
}
})
.await?
@ -1607,7 +1607,7 @@ impl Validator for ValidateDeviceQueueAccess {
let dev_eui = self.dev_eui;
move || -> Result<i64, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let mut q = api_key::dsl::api_key
.select(dsl::count_star())
.left_join(
@ -1635,7 +1635,7 @@ impl Validator for ValidateDeviceQueueAccess {
}
}
Ok(q.first(&c)?)
Ok(q.first(&mut c)?)
}
})
.await?
@ -1662,7 +1662,7 @@ impl Validator for ValidateGatewaysAccess {
let tenant_id = self.tenant_id;
move || -> Result<i64, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let mut q = user::dsl::user
.select(dsl::count_star())
.left_join(tenant_user::table.left_join(tenant::table))
@ -1699,7 +1699,7 @@ impl Validator for ValidateGatewaysAccess {
}
}
Ok(q.first(&c)?)
Ok(q.first(&mut c)?)
}
})
.await?
@ -1712,7 +1712,7 @@ impl Validator for ValidateGatewaysAccess {
let tenant_id = self.tenant_id;
move || -> Result<i64, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let mut q = api_key::dsl::api_key
.select(dsl::count_star())
.find(&id)
@ -1733,7 +1733,7 @@ impl Validator for ValidateGatewaysAccess {
}
}
Ok(q.first(&c)?)
Ok(q.first(&mut c)?)
}
})
.await?
@ -1760,7 +1760,7 @@ impl Validator for ValidateGatewayAccess {
let gateway_id = self.gateway_id;
move || -> Result<i64, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let mut q = user::dsl::user
.select(dsl::count_star())
.left_join(
@ -1799,7 +1799,7 @@ impl Validator for ValidateGatewayAccess {
}
}
Ok(q.first(&c)?)
Ok(q.first(&mut c)?)
}
})
.await?
@ -1812,7 +1812,7 @@ impl Validator for ValidateGatewayAccess {
let gateway_id = self.gateway_id;
move || -> Result<i64, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let mut q = api_key::dsl::api_key
.select(dsl::count_star())
.left_join(
@ -1837,7 +1837,7 @@ impl Validator for ValidateGatewayAccess {
}
}
Ok(q.first(&c)?)
Ok(q.first(&mut c)?)
}
})
.await?
@ -1867,7 +1867,7 @@ impl Validator for ValidateMulticastGroupsAccess {
let application_id = self.application_id;
move || -> Result<i64, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let mut q = user::dsl::user
.select(dsl::count_star())
.left_join(
@ -1909,7 +1909,7 @@ impl Validator for ValidateMulticastGroupsAccess {
}
}
Ok(q.first(&c)?)
Ok(q.first(&mut c)?)
}
})
.await?
@ -1922,7 +1922,7 @@ impl Validator for ValidateMulticastGroupsAccess {
let application_id = self.application_id;
move || -> Result<i64, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let mut q = api_key::dsl::api_key
.select(dsl::count_star())
.left_join(
@ -1947,7 +1947,7 @@ impl Validator for ValidateMulticastGroupsAccess {
}
}
Ok(q.first(&c)?)
Ok(q.first(&mut c)?)
}
})
.await?
@ -1977,7 +1977,7 @@ impl Validator for ValidateMulticastGroupAccess {
let multicast_group_id = self.multicast_group_id;
move || -> Result<i64, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let mut q = user::dsl::user
.select(dsl::count_star())
.left_join(
@ -2023,7 +2023,7 @@ impl Validator for ValidateMulticastGroupAccess {
}
}
Ok(q.first(&c)?)
Ok(q.first(&mut c)?)
}
})
.await?
@ -2036,7 +2036,7 @@ impl Validator for ValidateMulticastGroupAccess {
let multicast_group_id = self.multicast_group_id;
move || -> Result<i64, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let mut q = api_key::dsl::api_key
.select(dsl::count_star())
.left_join(
@ -2065,7 +2065,7 @@ impl Validator for ValidateMulticastGroupAccess {
}
}
Ok(q.first(&c)?)
Ok(q.first(&mut c)?)
}
})
.await?
@ -2095,7 +2095,7 @@ impl Validator for ValidateMulticastGroupQueueAccess {
let multicast_group_id = self.multicast_group_id;
move || -> Result<i64, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let mut q = user::dsl::user
.select(dsl::count_star())
.left_join(
@ -2141,7 +2141,7 @@ impl Validator for ValidateMulticastGroupQueueAccess {
}
}
Ok(q.first(&c)?)
Ok(q.first(&mut c)?)
}
})
.await?
@ -2154,7 +2154,7 @@ impl Validator for ValidateMulticastGroupQueueAccess {
let multicast_group_id = self.multicast_group_id;
move || -> Result<i64, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let mut q = api_key::dsl::api_key
.select(dsl::count_star())
.left_join(
@ -2183,7 +2183,7 @@ impl Validator for ValidateMulticastGroupQueueAccess {
}
}
Ok(q.first(&c)?)
Ok(q.first(&mut c)?)
}
})
.await?

View File

@ -56,9 +56,9 @@ async fn _health_handler() -> Result<()> {
return Err(anyhow!("Redis connection error"));
}
let c = get_db_conn()?;
let mut c = get_db_conn()?;
diesel::sql_query("select 1")
.execute(&c)
.execute(&mut c)
.context("PostgreSQL connection error")?;
Ok(())

View File

@ -1,11 +1,11 @@
use std::collections::HashMap;
use std::fmt;
use std::io::Write;
use std::str::FromStr;
use anyhow::{Context, Result};
use chrono::{DateTime, Utc};
use diesel::backend::Backend;
use diesel::backend::{self, Backend};
use diesel::pg::Pg;
use diesel::sql_types::Text;
use diesel::{deserialize, serialize};
use serde::{Deserialize, Serialize};
@ -16,7 +16,7 @@ mod js;
#[derive(Deserialize, Serialize, Copy, Clone, Debug, Eq, PartialEq, AsExpression, FromSqlRow)]
#[allow(non_camel_case_types, clippy::upper_case_acronyms)]
#[sql_type = "diesel::sql_types::Text"]
#[diesel(sql_type = diesel::sql_types::Text)]
pub enum Codec {
NONE,
CAYENNE_LPP,
@ -29,24 +29,23 @@ impl fmt::Display for Codec {
}
}
impl<ST, DB> deserialize::FromSql<ST, DB> for Codec
impl<DB> deserialize::FromSql<Text, DB> for Codec
where
DB: Backend,
*const str: deserialize::FromSql<ST, DB>,
*const str: deserialize::FromSql<Text, DB>,
{
fn from_sql(bytes: Option<&DB::RawValue>) -> deserialize::Result<Self> {
let string = String::from_sql(bytes)?;
fn from_sql(value: backend::RawValue<DB>) -> deserialize::Result<Self> {
let string = String::from_sql(value)?;
Ok(Codec::from_str(&string)?)
}
}
impl<DB> serialize::ToSql<Text, DB> for Codec
impl serialize::ToSql<Text, Pg> for Codec
where
DB: Backend,
str: serialize::ToSql<Text, DB>,
str: serialize::ToSql<Text, Pg>,
{
fn to_sql<W: Write>(&self, out: &mut serialize::Output<W, DB>) -> serialize::Result {
self.to_string().as_str().to_sql(out)
fn to_sql<'b>(&self, out: &mut serialize::Output<'b, '_, Pg>) -> serialize::Result {
<str as serialize::ToSql<Text, Pg>>::to_sql(&self.to_string(), &mut out.reborrow())
}
}

View File

@ -7,7 +7,7 @@ use chrono::{DateTime, Utc};
use diesel::pg::PgConnection;
use diesel::prelude::*;
use diesel::r2d2::{ConnectionManager, Pool, PooledConnection};
use diesel_migrations::embed_migrations;
use diesel_migrations::{embed_migrations, EmbeddedMigrations, MigrationHarness};
use tokio::task;
use tracing::info;
use uuid::Uuid;
@ -22,13 +22,14 @@ use schema::{
mod schema;
embed_migrations!("./src/integration/postgresql/migrations");
pub const MIGRATIONS: EmbeddedMigrations =
embed_migrations!("./src/integration/postgresql/migrations");
type PgPool = Pool<ConnectionManager<PgConnection>>;
type PgPoolConnection = PooledConnection<ConnectionManager<PgConnection>>;
#[derive(Insertable)]
#[table_name = "event_up"]
#[diesel(table_name = event_up)]
struct EventUp {
pub deduplication_id: Uuid,
pub time: DateTime<Utc>,
@ -54,7 +55,7 @@ struct EventUp {
}
#[derive(Insertable)]
#[table_name = "event_join"]
#[diesel(table_name = event_join)]
struct EventJoin {
pub deduplication_id: Uuid,
pub time: DateTime<Utc>,
@ -71,7 +72,7 @@ struct EventJoin {
}
#[derive(Insertable)]
#[table_name = "event_ack"]
#[diesel(table_name = event_ack)]
struct EventAck {
pub queue_item_id: Uuid,
pub deduplication_id: Uuid,
@ -90,7 +91,7 @@ struct EventAck {
}
#[derive(Insertable)]
#[table_name = "event_tx_ack"]
#[diesel(table_name = event_tx_ack)]
struct EventTxAck {
pub queue_item_id: Uuid,
pub downlink_id: i64,
@ -110,7 +111,7 @@ struct EventTxAck {
}
#[derive(Insertable)]
#[table_name = "event_log"]
#[diesel(table_name = event_log)]
struct EventLog {
pub time: DateTime<Utc>,
pub tenant_id: Uuid,
@ -129,7 +130,7 @@ struct EventLog {
}
#[derive(Insertable)]
#[table_name = "event_status"]
#[diesel(table_name = event_status)]
struct EventStatus {
pub deduplication_id: Uuid,
pub time: DateTime<Utc>,
@ -149,7 +150,7 @@ struct EventStatus {
}
#[derive(Insertable)]
#[table_name = "event_location"]
#[diesel(table_name = event_location)]
struct EventLocation {
pub deduplication_id: Uuid,
pub time: DateTime<Utc>,
@ -170,7 +171,7 @@ struct EventLocation {
}
#[derive(Insertable)]
#[table_name = "event_integration"]
#[diesel(table_name = event_integration)]
struct EventIntegration {
pub deduplication_id: Uuid,
pub time: DateTime<Utc>,
@ -204,10 +205,12 @@ impl Integration {
})
.build(ConnectionManager::new(&conf.dsn))
.context("Setup PostgreSQL connection pool error")?;
let db_conn = pg_pool.get()?;
let mut db_conn = pg_pool.get()?;
info!("Applying schema migrations");
embedded_migrations::run(&db_conn).context("Run migrations error")?;
db_conn
.run_pending_migrations(MIGRATIONS)
.map_err(|e| anyhow!("{}", e))?;
Ok(Integration { pg_pool })
}
@ -246,12 +249,12 @@ impl IntegrationTrait for Integration {
rx_info: serde_json::to_value(&pl.rx_info)?,
tx_info: serde_json::to_value(&pl.tx_info)?,
};
let c = self.pg_pool.get()?;
let mut c = self.pg_pool.get()?;
task::spawn_blocking(move || -> Result<()> {
diesel::insert_into(event_up::table)
.values(&e)
.execute(&c)?;
.execute(&mut c)?;
Ok(())
})
.await??;
@ -281,12 +284,12 @@ impl IntegrationTrait for Integration {
tags: serde_json::to_value(&di.tags)?,
dev_addr: pl.dev_addr.clone(),
};
let c = self.pg_pool.get()?;
let mut c = self.pg_pool.get()?;
task::spawn_blocking(move || -> Result<()> {
diesel::insert_into(event_join::table)
.values(&e)
.execute(&c)?;
.execute(&mut c)?;
Ok(())
})
.await??;
@ -318,12 +321,12 @@ impl IntegrationTrait for Integration {
acknowledged: pl.acknowledged,
f_cnt_down: pl.f_cnt_down as i64,
};
let c = self.pg_pool.get()?;
let mut c = self.pg_pool.get()?;
task::spawn_blocking(move || -> Result<()> {
diesel::insert_into(event_ack::table)
.values(&e)
.execute(&c)?;
.execute(&mut c)?;
Ok(())
})
.await??;
@ -356,12 +359,12 @@ impl IntegrationTrait for Integration {
gateway_id: pl.gateway_id.clone(),
tx_info: serde_json::to_value(&pl.tx_info)?,
};
let c = self.pg_pool.get()?;
let mut c = self.pg_pool.get()?;
task::spawn_blocking(move || -> Result<()> {
diesel::insert_into(event_tx_ack::table)
.values(&e)
.execute(&c)?;
.execute(&mut c)?;
Ok(())
})
.await??;
@ -393,12 +396,12 @@ impl IntegrationTrait for Integration {
description: pl.description.clone(),
context: serde_json::to_value(&pl.context)?,
};
let c = self.pg_pool.get()?;
let mut c = self.pg_pool.get()?;
task::spawn_blocking(move || -> Result<()> {
diesel::insert_into(event_log::table)
.values(&e)
.execute(&c)?;
.execute(&mut c)?;
Ok(())
})
.await??;
@ -431,12 +434,12 @@ impl IntegrationTrait for Integration {
battery_level_unavailable: pl.battery_level_unavailable,
battery_level: pl.battery_level,
};
let c = self.pg_pool.get()?;
let mut c = self.pg_pool.get()?;
task::spawn_blocking(move || -> Result<()> {
diesel::insert_into(event_status::table)
.values(&e)
.execute(&c)?;
.execute(&mut c)?;
Ok(())
})
.await??;
@ -470,12 +473,12 @@ impl IntegrationTrait for Integration {
source: loc.source.to_string(),
accuracy: loc.accuracy,
};
let c = self.pg_pool.get()?;
let mut c = self.pg_pool.get()?;
task::spawn_blocking(move || -> Result<()> {
diesel::insert_into(event_location::table)
.values(&e)
.execute(&c)?;
.execute(&mut c)?;
Ok(())
})
.await??;
@ -507,12 +510,12 @@ impl IntegrationTrait for Integration {
event_type: pl.event_type.clone(),
object: serde_json::to_value(&pl.object)?,
};
let c = self.pg_pool.get()?;
let mut c = self.pg_pool.get()?;
task::spawn_blocking(move || -> Result<()> {
diesel::insert_into(event_integration::table)
.values(&e)
.execute(&c)?;
.execute(&mut c)?;
Ok(())
})
.await??;

View File

@ -32,7 +32,7 @@ pub async fn handle(
pl.margin as i32,
pl.battery == 0,
if pl.battery > 0 && pl.battery < 255 {
let v: BigDecimal = ((pl.battery as f32) / 254.0 * 100.0).into();
let v: BigDecimal = ((pl.battery as f32) / 254.0 * 100.0).try_into()?;
Some(v.with_scale(2))
} else {
None

View File

@ -1,7 +1,6 @@
#![allow(dead_code)]
#[macro_use]
extern crate lazy_static;
#[macro_use]
extern crate diesel_migrations;
#[macro_use]
extern crate diesel;

View File

@ -11,7 +11,7 @@ use super::schema::api_key;
use super::{error, get_db_conn};
#[derive(Queryable, Insertable, AsChangeset, PartialEq, Debug)]
#[table_name = "api_key"]
#[diesel(table_name = api_key)]
pub struct ApiKey {
pub id: Uuid,
pub created_at: DateTime<Utc>,
@ -52,10 +52,10 @@ pub async fn create(ak: ApiKey) -> Result<ApiKey, Error> {
ak.validate()?;
let ak = task::spawn_blocking(move || -> Result<ApiKey, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
diesel::insert_into(api_key::table)
.values(&ak)
.get_result(&c)
.get_result(&mut c)
.map_err(|e| error::Error::from_diesel(e, ak.id.to_string()))
})
.await??;
@ -68,10 +68,10 @@ pub async fn get(id: &Uuid) -> Result<ApiKey, Error> {
let id = *id;
move || -> Result<ApiKey, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
api_key::dsl::api_key
.find(&id)
.first(&c)
.first(&mut c)
.map_err(|e| error::Error::from_diesel(e, id.to_string()))
}
})
@ -83,8 +83,8 @@ pub async fn delete(id: &Uuid) -> Result<(), Error> {
let id = *id;
move || -> Result<(), Error> {
let c = get_db_conn()?;
let ra = diesel::delete(api_key::dsl::api_key.find(&id)).execute(&c)?;
let mut c = get_db_conn()?;
let ra = diesel::delete(api_key::dsl::api_key.find(&id)).execute(&mut c)?;
if ra == 0 {
return Err(Error::NotFound(id.to_string()));
}
@ -100,7 +100,7 @@ pub async fn get_count(filters: &Filters) -> Result<i64, Error> {
let filters = filters.clone();
move || -> Result<i64, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let mut q = api_key::dsl::api_key
.select(dsl::count_star())
@ -111,7 +111,7 @@ pub async fn get_count(filters: &Filters) -> Result<i64, Error> {
q = q.filter(api_key::dsl::tenant_id.eq(tenant_id));
}
Ok(q.first(&c)?)
Ok(q.first(&mut c)?)
}
})
.await?
@ -122,7 +122,7 @@ pub async fn list(limit: i64, offset: i64, filters: &Filters) -> Result<Vec<ApiK
let filters = filters.clone();
move || -> Result<Vec<ApiKey>, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let mut q = api_key::dsl::api_key
.filter(api_key::dsl::is_admin.eq(filters.is_admin))
@ -136,7 +136,7 @@ pub async fn list(limit: i64, offset: i64, filters: &Filters) -> Result<Vec<ApiK
.order_by(api_key::dsl::name)
.limit(limit)
.offset(offset)
.load(&c)?;
.load(&mut c)?;
Ok(items)
}
})

View File

@ -1,16 +1,14 @@
use std::collections::HashMap;
use std::fmt;
use std::io::Write;
use std::str::FromStr;
use anyhow::Result;
use chrono::{DateTime, Utc};
use diesel::backend::Backend;
use diesel::backend::{self, Backend};
use diesel::dsl;
use diesel::pg::types::sql_types::Jsonb;
use diesel::pg::Pg;
use diesel::prelude::*;
use diesel::sql_types::Text;
use diesel::sql_types::{Jsonb, Text};
use diesel::{deserialize, serialize};
use serde::{Deserialize, Serialize};
use tokio::task;
@ -22,7 +20,7 @@ use super::get_db_conn;
use super::schema::{application, application_integration};
#[derive(Clone, Queryable, Insertable, AsChangeset, PartialEq, Debug)]
#[table_name = "application"]
#[diesel(table_name = application)]
pub struct Application {
pub id: Uuid,
pub tenant_id: Uuid,
@ -74,7 +72,7 @@ pub struct ApplicationListItem {
}
#[derive(Deserialize, Serialize, Copy, Clone, Debug, Eq, PartialEq, AsExpression, FromSqlRow)]
#[sql_type = "Text"]
#[diesel(sql_type = Text)]
pub enum IntegrationKind {
Http,
InfluxDb,
@ -116,29 +114,28 @@ impl FromStr for IntegrationKind {
}
}
impl<ST, DB> deserialize::FromSql<ST, DB> for IntegrationKind
impl<DB> deserialize::FromSql<Text, DB> for IntegrationKind
where
DB: Backend,
*const str: deserialize::FromSql<ST, DB>,
*const str: deserialize::FromSql<Text, DB>,
{
fn from_sql(bytes: Option<&DB::RawValue>) -> deserialize::Result<Self> {
let string = String::from_sql(bytes)?;
fn from_sql(value: backend::RawValue<DB>) -> deserialize::Result<Self> {
let string = String::from_sql(value)?;
Ok(IntegrationKind::from_str(&string)?)
}
}
impl<DB> serialize::ToSql<Text, DB> for IntegrationKind
impl serialize::ToSql<Text, Pg> for IntegrationKind
where
DB: Backend,
str: serialize::ToSql<Text, DB>,
str: serialize::ToSql<Text, Pg>,
{
fn to_sql<W: Write>(&self, out: &mut serialize::Output<W, DB>) -> serialize::Result {
self.to_string().as_str().to_sql(out)
fn to_sql<'b>(&self, out: &mut serialize::Output<'b, '_, Pg>) -> serialize::Result {
<str as serialize::ToSql<Text, Pg>>::to_sql(&self.to_string(), &mut out.reborrow())
}
}
#[derive(Debug, Clone, PartialEq, AsExpression, FromSqlRow, Serialize, Deserialize)]
#[sql_type = "Jsonb"]
#[diesel(sql_type = Jsonb)]
pub enum IntegrationConfiguration {
None,
Http(HttpConfiguration),
@ -154,16 +151,16 @@ pub enum IntegrationConfiguration {
}
impl deserialize::FromSql<Jsonb, Pg> for IntegrationConfiguration {
fn from_sql(bytes: Option<&[u8]>) -> deserialize::Result<Self> {
let value = <serde_json::Value as deserialize::FromSql<Jsonb, Pg>>::from_sql(bytes)?;
fn from_sql(value: backend::RawValue<Pg>) -> deserialize::Result<Self> {
let value = <serde_json::Value as deserialize::FromSql<Jsonb, Pg>>::from_sql(value)?;
Ok(serde_json::from_value(value)?)
}
}
impl serialize::ToSql<Jsonb, Pg> for IntegrationConfiguration {
fn to_sql<W: Write>(&self, out: &mut serialize::Output<W, Pg>) -> serialize::Result {
fn to_sql<'b>(&self, out: &mut serialize::Output<'b, '_, Pg>) -> serialize::Result {
let value = serde_json::to_value(self)?;
<serde_json::Value as serialize::ToSql<Jsonb, Pg>>::to_sql(&value, out)
<serde_json::Value as serialize::ToSql<Jsonb, Pg>>::to_sql(&value, &mut out.reborrow())
}
}
@ -259,7 +256,7 @@ pub struct IftttConfiguration {
}
#[derive(Clone, Queryable, Insertable, AsChangeset, PartialEq, Debug)]
#[table_name = "application_integration"]
#[diesel(table_name = application_integration)]
pub struct Integration {
pub application_id: Uuid,
pub kind: IntegrationKind,
@ -286,10 +283,10 @@ pub async fn create(a: Application) -> Result<Application, Error> {
a.validate()?;
task::spawn_blocking({
move || -> Result<Application, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let a: Application = diesel::insert_into(application::table)
.values(&a)
.get_result(&c)
.get_result(&mut c)
.map_err(|e| Error::from_diesel(e, a.id.to_string()))?;
info!(id = %a.id, "Application created");
@ -304,10 +301,10 @@ pub async fn get(id: &Uuid) -> Result<Application, Error> {
task::spawn_blocking({
let id = *id;
move || -> Result<Application, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let a = application::dsl::application
.find(&id)
.first(&c)
.first(&mut c)
.map_err(|e| Error::from_diesel(e, id.to_string()))?;
Ok(a)
}
@ -319,14 +316,14 @@ pub async fn update(a: Application) -> Result<Application, Error> {
a.validate()?;
task::spawn_blocking({
move || -> Result<Application, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let a: Application = diesel::update(application::dsl::application.find(&a.id))
.set((
application::updated_at.eq(Utc::now()),
application::name.eq(&a.name),
application::description.eq(&a.description),
))
.get_result(&c)
.get_result(&mut c)
.map_err(|e| Error::from_diesel(e, a.id.to_string()))?;
info!(
@ -345,10 +342,10 @@ pub async fn update_mqtt_cls_cert(id: &Uuid, cert: &[u8]) -> Result<Application,
let id = *id;
let cert = cert.to_vec();
move || -> Result<Application, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let app: Application = diesel::update(application::dsl::application.find(&id))
.set(application::mqtt_tls_cert.eq(cert))
.get_result(&c)
.get_result(&mut c)
.map_err(|e| Error::from_diesel(e, id.to_string()))?;
Ok(app)
}
@ -367,8 +364,8 @@ pub async fn delete(id: &Uuid) -> Result<(), Error> {
task::spawn_blocking({
let id = *id;
move || -> Result<(), Error> {
let c = get_db_conn()?;
let ra = diesel::delete(application::dsl::application.find(&id)).execute(&c)?;
let mut c = get_db_conn()?;
let ra = diesel::delete(application::dsl::application.find(&id)).execute(&mut c)?;
if ra == 0 {
return Err(Error::NotFound(id.to_string()));
}
@ -388,7 +385,7 @@ pub async fn get_count(filters: &Filters) -> Result<i64, Error> {
task::spawn_blocking({
let filters = filters.clone();
move || -> Result<i64, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let mut q = application::dsl::application
.select(dsl::count_star())
.into_boxed();
@ -401,7 +398,7 @@ pub async fn get_count(filters: &Filters) -> Result<i64, Error> {
q = q.filter(application::dsl::name.ilike(format!("%{}%", search)));
}
Ok(q.first(&c)?)
Ok(q.first(&mut c)?)
}
})
.await?
@ -415,7 +412,7 @@ pub async fn list(
task::spawn_blocking({
let filters = filters.clone();
move || -> Result<Vec<ApplicationListItem>, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let mut q = application::dsl::application
.select((
application::id,
@ -438,7 +435,7 @@ pub async fn list(
.order_by(application::dsl::name)
.limit(limit)
.offset(offset)
.load(&c)?;
.load(&mut c)?;
Ok(items)
}
})
@ -448,10 +445,10 @@ pub async fn list(
pub async fn create_integration(i: Integration) -> Result<Integration, Error> {
task::spawn_blocking({
move || -> Result<Integration, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let i: Integration = diesel::insert_into(application_integration::table)
.values(&i)
.get_result(&c)
.get_result(&mut c)
.map_err(|e| Error::from_diesel(e, i.kind.to_string()))?;
info!(application_id = %i.application_id, kind = %i.kind, "Integration created");
@ -468,14 +465,14 @@ pub async fn get_integration(
task::spawn_blocking({
let application_id = *application_id;
move || -> Result<Integration, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let i: Integration = application_integration::dsl::application_integration
.filter(
application_integration::dsl::application_id
.eq(application_id)
.and(application_integration::dsl::kind.eq(kind)),
)
.first(&c)
.first(&mut c)
.map_err(|e| Error::from_diesel(e, application_id.to_string()))?;
Ok(i)
}
@ -486,7 +483,7 @@ pub async fn get_integration(
pub async fn update_integration(i: Integration) -> Result<Integration, Error> {
task::spawn_blocking({
move || -> Result<Integration, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let i: Integration = diesel::update(
application_integration::dsl::application_integration.filter(
application_integration::dsl::application_id
@ -498,7 +495,7 @@ pub async fn update_integration(i: Integration) -> Result<Integration, Error> {
application_integration::updated_at.eq(Utc::now()),
application_integration::configuration.eq(&i.configuration),
))
.get_result(&c)
.get_result(&mut c)
.map_err(|e| Error::from_diesel(e, i.application_id.to_string()))?;
info!(application_id = %i.application_id, kind = %i.kind, "Integration updated");
@ -513,7 +510,7 @@ pub async fn delete_integration(application_id: &Uuid, kind: IntegrationKind) ->
task::spawn_blocking({
let application_id = *application_id;
move || -> Result<(), Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let ra = diesel::delete(
application_integration::dsl::application_integration.filter(
application_integration::dsl::application_id
@ -521,7 +518,7 @@ pub async fn delete_integration(application_id: &Uuid, kind: IntegrationKind) ->
.and(application_integration::dsl::kind.eq(&kind)),
),
)
.execute(&c)?;
.execute(&mut c)?;
if ra == 0 {
return Err(Error::NotFound(application_id.to_string()));
@ -540,11 +537,11 @@ pub async fn get_integrations_for_application(
task::spawn_blocking({
let application_id = *application_id;
move || -> Result<Vec<Integration>, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let items: Vec<Integration> = application_integration::dsl::application_integration
.filter(application_integration::dsl::application_id.eq(&application_id))
.order_by(application_integration::dsl::kind)
.load(&c)?;
.load(&mut c)?;
Ok(items)
}
})
@ -554,14 +551,14 @@ pub async fn get_integrations_for_application(
pub async fn get_measurement_keys(application_id: &Uuid) -> Result<Vec<String>, Error> {
#[derive(QueryableByName)]
struct Measurement {
#[sql_type = "diesel::sql_types::Text"]
#[diesel(sql_type = diesel::sql_types::Text)]
pub key: String,
}
task::spawn_blocking({
let application_id = *application_id;
move || -> Result<Vec<String>, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let keys: Vec<Measurement> = diesel::sql_query(
r#"
select
@ -576,8 +573,8 @@ pub async fn get_measurement_keys(application_id: &Uuid) -> Result<Vec<String>,
key
"#,
)
.bind::<diesel::pg::types::sql_types::Uuid, _>(application_id)
.load(&c)
.bind::<diesel::sql_types::Uuid, _>(application_id)
.load(&mut c)
.map_err(|e| Error::from_diesel(e, application_id.to_string()))?;
Ok(keys.iter().map(|k| k.key.clone()).collect())
}

View File

@ -16,7 +16,7 @@ use super::{error::Error, fields, get_db_conn, get_redis_conn, redis_key};
use crate::config;
#[derive(Queryable, QueryableByName, Insertable, AsChangeset, PartialEq, Debug, Clone)]
#[table_name = "device"]
#[diesel(table_name = device)]
pub struct Device {
pub dev_eui: EUI64,
pub application_id: Uuid,
@ -106,11 +106,11 @@ pub struct Filters {
#[derive(QueryableByName, PartialEq, Debug)]
pub struct DevicesActiveInactive {
#[sql_type = "diesel::sql_types::BigInt"]
#[diesel(sql_type = diesel::sql_types::BigInt)]
pub never_seen_count: i64,
#[sql_type = "diesel::sql_types::BigInt"]
#[diesel(sql_type = diesel::sql_types::BigInt)]
pub active_count: i64,
#[sql_type = "diesel::sql_types::BigInt"]
#[diesel(sql_type = diesel::sql_types::BigInt)]
pub inactive_count: i64,
}
@ -124,8 +124,8 @@ pub async fn create(d: Device) -> Result<Device, Error> {
d.validate()?;
let d = task::spawn_blocking({
move || -> Result<Device, Error> {
let c = get_db_conn()?;
c.transaction::<Device, Error, _>(|| {
let mut c = get_db_conn()?;
c.transaction::<Device, Error, _>(|c| {
// use for update to lock the tenant
let t: super::tenant::Tenant = tenant::dsl::tenant
.select((
@ -141,13 +141,13 @@ pub async fn create(d: Device) -> Result<Device, Error> {
))
.inner_join(application::table)
.filter(application::dsl::id.eq(&d.application_id))
.first(&c)?;
.first(c)?;
let dev_count: i64 = device::dsl::device
.select(dsl::count_star())
.inner_join(application::table)
.filter(application::dsl::tenant_id.eq(&t.id))
.first(&c)?;
.first(c)?;
if t.max_device_count != 0 && dev_count as i32 >= t.max_device_count {
return Err(Error::NotAllowed(
@ -157,7 +157,7 @@ pub async fn create(d: Device) -> Result<Device, Error> {
diesel::insert_into(device::table)
.values(&d)
.get_result(&c)
.get_result(c)
.map_err(|e| Error::from_diesel(e, d.dev_eui.to_string()))
})
}
@ -171,10 +171,10 @@ pub async fn get(dev_eui: &EUI64) -> Result<Device, Error> {
task::spawn_blocking({
let dev_eui = *dev_eui;
move || -> Result<Device, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let d = device::dsl::device
.find(&dev_eui)
.first(&c)
.first(&mut c)
.map_err(|e| Error::from_diesel(e, dev_eui.to_string()))?;
Ok(d)
}
@ -186,7 +186,7 @@ pub async fn update(d: Device) -> Result<Device, Error> {
d.validate()?;
let d = task::spawn_blocking({
move || -> Result<Device, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
diesel::update(device::dsl::device.find(&d.dev_eui))
.set((
device::updated_at.eq(Utc::now()),
@ -199,7 +199,7 @@ pub async fn update(d: Device) -> Result<Device, Error> {
device::tags.eq(&d.tags),
device::variables.eq(&d.variables),
))
.get_result(&c)
.get_result(&mut c)
.map_err(|e| Error::from_diesel(e, d.dev_eui.to_string()))
}
})
@ -213,10 +213,10 @@ pub async fn set_enabled_class(dev_eui: &EUI64, mode: &str) -> Result<Device, Er
let dev_eui = *dev_eui;
let mode = mode.to_string();
move || -> Result<Device, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
diesel::update(device::dsl::device.find(&dev_eui))
.set(device::enabled_class.eq(&mode))
.get_result(&c)
.get_result(&mut c)
.map_err(|e| Error::from_diesel(e, dev_eui.to_string()))
}
})
@ -236,10 +236,10 @@ pub async fn set_scheduler_run_after(
task::spawn_blocking({
let dev_eui = *dev_eui;
move || -> Result<Device, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
diesel::update(device::dsl::device.find(&dev_eui))
.set(device::scheduler_run_after.eq(&new_ts))
.get_result(&c)
.get_result(&mut c)
.map_err(|e| Error::from_diesel(e, dev_eui.to_string()))
}
})
@ -250,13 +250,13 @@ pub async fn set_last_seen_dr(dev_eui: &EUI64, dr: u8) -> Result<Device, Error>
let d = task::spawn_blocking({
let dev_eui = *dev_eui;
move || -> Result<Device, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
diesel::update(device::dsl::device.find(&dev_eui))
.set((
device::last_seen_at.eq(Utc::now()),
device::dr.eq(dr as i16),
))
.get_result(&c)
.get_result(&mut c)
.map_err(|e| Error::from_diesel(e, dev_eui.to_string()))
}
})
@ -274,14 +274,14 @@ pub async fn set_status(
let d = task::spawn_blocking({
let dev_eui = *dev_eui;
move || -> Result<Device, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
diesel::update(device::dsl::device.find(&dev_eui))
.set((
device::margin.eq(Some(margin)),
device::external_power_source.eq(external_power_source),
device::battery_level.eq(battery_level),
))
.get_result(&c)
.get_result(&mut c)
.map_err(|e| Error::from_diesel(e, dev_eui.to_string()))
}
})
@ -294,8 +294,8 @@ pub async fn delete(dev_eui: &EUI64) -> Result<(), Error> {
task::spawn_blocking({
let dev_eui = *dev_eui;
move || -> Result<(), Error> {
let c = get_db_conn()?;
let ra = diesel::delete(device::dsl::device.find(&dev_eui)).execute(&c)?;
let mut c = get_db_conn()?;
let ra = diesel::delete(device::dsl::device.find(&dev_eui)).execute(&mut c)?;
if ra == 0 {
return Err(Error::NotFound(dev_eui.to_string()));
}
@ -311,7 +311,7 @@ pub async fn get_count(filters: &Filters) -> Result<i64, Error> {
task::spawn_blocking({
let filters = filters.clone();
move || -> Result<i64, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let mut q = device::dsl::device
.select(dsl::count_star())
.distinct()
@ -331,7 +331,7 @@ pub async fn get_count(filters: &Filters) -> Result<i64, Error> {
.filter(multicast_group_device::dsl::multicast_group_id.eq(multicast_group_id));
}
Ok(q.first(&c)?)
Ok(q.first(&mut c)?)
}
})
.await?
@ -345,7 +345,7 @@ pub async fn list(
task::spawn_blocking({
let filters = filters.clone();
move || -> Result<Vec<DeviceListItem>, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let mut q = device::dsl::device
.inner_join(device_profile::table)
.left_join(multicast_group_device::table)
@ -381,7 +381,7 @@ pub async fn list(
q.order_by(device::dsl::name)
.limit(limit)
.offset(offset)
.load(&c)
.load(&mut c)
.map_err(|e| Error::from_diesel(e, "".into()))
}
})
@ -392,7 +392,7 @@ pub async fn get_active_inactive(tenant_id: &Option<Uuid>) -> Result<DevicesActi
task::spawn_blocking({
let tenant_id = *tenant_id;
move || -> Result<DevicesActiveInactive, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
diesel::sql_query(r#"
with device_active_inactive as (
select
@ -412,8 +412,8 @@ pub async fn get_active_inactive(tenant_id: &Option<Uuid>) -> Result<DevicesActi
from
device_active_inactive
"#)
.bind::<diesel::sql_types::Nullable<diesel::pg::types::sql_types::Uuid>, _>(tenant_id)
.get_result(&c)
.bind::<diesel::sql_types::Nullable<diesel::sql_types::Uuid>, _>(tenant_id)
.get_result(&mut c)
.map_err(|e| Error::from_diesel(e, "".into()))
}
})
@ -424,7 +424,7 @@ pub async fn get_data_rates(tenant_id: &Option<Uuid>) -> Result<Vec<DevicesDataR
task::spawn_blocking({
let tenant_id = *tenant_id;
move || -> Result<Vec<DevicesDataRate>, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let mut q = device::dsl::device
.inner_join(device_profile::table)
//.select((device::dr, dsl::count_star()))
@ -432,6 +432,7 @@ pub async fn get_data_rates(tenant_id: &Option<Uuid>) -> Result<Vec<DevicesDataR
device::dr,
diesel::dsl::sql::<diesel::sql_types::BigInt>("count(1)"),
))
.group_by(device::dr)
.filter(device::dsl::dr.is_not_null())
.into_boxed();
@ -439,9 +440,7 @@ pub async fn get_data_rates(tenant_id: &Option<Uuid>) -> Result<Vec<DevicesDataR
q = q.filter(device_profile::dsl::tenant_id.eq(id));
}
q.group_by(device::dr)
.load(&c)
.map_err(|e| Error::from_diesel(e, "".into()))
q.load(&mut c).map_err(|e| Error::from_diesel(e, "".into()))
}
})
.await?
@ -449,8 +448,8 @@ pub async fn get_data_rates(tenant_id: &Option<Uuid>) -> Result<Vec<DevicesDataR
pub async fn get_with_class_b_c_queue_items(limit: usize) -> Result<Vec<Device>> {
task::spawn_blocking(move || -> Result<Vec<Device>> {
let c = get_db_conn()?;
c.transaction::<Vec<Device>, Error, _>(|| {
let mut c = get_db_conn()?;
c.transaction::<Vec<Device>, Error, _>(|c| {
let conf = config::get();
diesel::sql_query(
r#"
@ -490,7 +489,7 @@ pub async fn get_with_class_b_c_queue_items(limit: usize) -> Result<Vec<Device>>
.bind::<diesel::sql_types::Timestamptz, _>(
Utc::now() + Duration::from_std(2 * conf.network.scheduler.interval).unwrap(),
)
.load(&c)
.load(c)
.map_err(|e| Error::from_diesel(e, "".into()))
})
.context("Get with Class B/C queue-items transaction")

View File

@ -11,14 +11,14 @@ use super::get_db_conn;
use super::schema::device_keys;
#[derive(Queryable, Insertable, AsChangeset, PartialEq, Debug, Clone)]
#[table_name = "device_keys"]
#[diesel(table_name = device_keys)]
pub struct DeviceKeys {
pub dev_eui: EUI64,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
pub nwk_key: AES128Key,
pub app_key: AES128Key,
pub dev_nonces: Vec<i32>,
pub dev_nonces: Vec<Option<i32>>,
pub join_nonce: i32,
}
@ -47,10 +47,10 @@ impl Default for DeviceKeys {
pub async fn create(dk: DeviceKeys) -> Result<DeviceKeys, Error> {
let dk = task::spawn_blocking({
move || -> Result<DeviceKeys, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
diesel::insert_into(device_keys::table)
.values(&dk)
.get_result(&c)
.get_result(&mut c)
.map_err(|e| Error::from_diesel(e, dk.dev_eui.to_string()))
}
})
@ -66,10 +66,10 @@ pub async fn get(dev_eui: &EUI64) -> Result<DeviceKeys, Error> {
task::spawn_blocking({
let dev_eui = *dev_eui;
move || -> Result<DeviceKeys, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let dk = device_keys::dsl::device_keys
.find(&dev_eui)
.first(&c)
.first(&mut c)
.map_err(|e| Error::from_diesel(e, dev_eui.to_string()))?;
Ok(dk)
}
@ -80,10 +80,10 @@ pub async fn get(dev_eui: &EUI64) -> Result<DeviceKeys, Error> {
pub async fn update(dk: DeviceKeys) -> Result<DeviceKeys, Error> {
let dk = task::spawn_blocking({
move || -> Result<DeviceKeys, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
diesel::update(device_keys::dsl::device_keys.find(&dk.dev_eui))
.set(&dk)
.get_result(&c)
.get_result(&mut c)
.map_err(|e| Error::from_diesel(e, dk.dev_eui.to_string()))
}
})
@ -99,8 +99,9 @@ pub async fn delete(dev_eui: &EUI64) -> Result<(), Error> {
task::spawn_blocking({
let dev_eui = *dev_eui;
move || -> Result<(), Error> {
let c = get_db_conn()?;
let ra = diesel::delete(device_keys::dsl::device_keys.find(&dev_eui)).execute(&c)?;
let mut c = get_db_conn()?;
let ra =
diesel::delete(device_keys::dsl::device_keys.find(&dev_eui)).execute(&mut c)?;
if ra == 0 {
return Err(Error::NotFound(dev_eui.to_string()));
}
@ -120,10 +121,10 @@ pub async fn set_dev_nonces(dev_eui: &EUI64, nonces: &[i32]) -> Result<DeviceKey
let dev_eui = *dev_eui;
let nonces = nonces.to_vec();
move || -> Result<DeviceKeys, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
diesel::update(device_keys::dsl::device_keys.find(&dev_eui))
.set(device_keys::dev_nonces.eq(&nonces))
.get_result(&c)
.get_result(&mut c)
.map_err(|e| Error::from_diesel(e, dev_eui.to_string()))
}
})
@ -139,13 +140,13 @@ pub async fn reset_nonces(dev_eui: &EUI64) -> Result<DeviceKeys, Error> {
let dk = task::spawn_blocking({
let dev_eui = *dev_eui;
move || -> Result<DeviceKeys, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
diesel::update(device_keys::dsl::device_keys.find(&dev_eui))
.set((
device_keys::dev_nonces.eq::<Vec<i32>>(Vec::new()),
device_keys::join_nonce.eq(0),
))
.get_result(&c)
.get_result(&mut c)
.map_err(|e| Error::from_diesel(e, dev_eui.to_string()))
}
})
@ -164,26 +165,26 @@ pub async fn validate_and_store_dev_nonce(
let dk = task::spawn_blocking({
let dev_eui = *dev_eui;
move || -> Result<DeviceKeys, Error> {
let c = get_db_conn()?;
c.transaction::<DeviceKeys, Error, _>(|| {
let mut c = get_db_conn()?;
c.transaction::<DeviceKeys, Error, _>(|c| {
let mut dk: DeviceKeys = device_keys::dsl::device_keys
.find(&dev_eui)
.for_update()
.first(&c)
.first(c)
.map_err(|e| Error::from_diesel(e, dev_eui.to_string()))?;
if dk.dev_nonces.contains(&(dev_nonce)) {
if dk.dev_nonces.contains(&(Some(dev_nonce))) {
return Err(Error::InvalidDevNonce);
}
dk.dev_nonces.push(dev_nonce);
dk.dev_nonces.push(Some(dev_nonce));
diesel::update(device_keys::dsl::device_keys.find(&dev_eui))
.set((
device_keys::updated_at.eq(Utc::now()),
device_keys::dev_nonces.eq(&dk.dev_nonces),
))
.get_result(&c)
.get_result(c)
.map_err(|e| Error::from_diesel(e, dev_eui.to_string()))
})
}

View File

@ -17,7 +17,7 @@ use crate::codec::Codec;
use chirpstack_api::internal;
#[derive(Clone, Queryable, Insertable, AsChangeset, Debug, PartialEq)]
#[table_name = "device_profile"]
#[diesel(table_name = device_profile)]
pub struct DeviceProfile {
pub id: Uuid,
pub tenant_id: Uuid,
@ -146,10 +146,10 @@ pub async fn create(dp: DeviceProfile) -> Result<DeviceProfile, Error> {
dp.validate()?;
let dp = task::spawn_blocking({
move || -> Result<DeviceProfile, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
diesel::insert_into(device_profile::table)
.values(&dp)
.get_result(&c)
.get_result(&mut c)
.map_err(|e| error::Error::from_diesel(e, dp.id.to_string()))
}
})
@ -162,10 +162,10 @@ pub async fn get(id: &Uuid) -> Result<DeviceProfile, Error> {
task::spawn_blocking({
let id = *id;
move || -> Result<DeviceProfile, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let dp = device_profile::dsl::device_profile
.find(&id)
.first(&c)
.first(&mut c)
.map_err(|e| error::Error::from_diesel(e, id.to_string()))?;
Ok(dp)
}
@ -177,7 +177,7 @@ pub async fn update(dp: DeviceProfile) -> Result<DeviceProfile, Error> {
dp.validate()?;
let dp = task::spawn_blocking({
move || -> Result<DeviceProfile, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
diesel::update(device_profile::dsl::device_profile.find(&dp.id))
.set((
@ -208,7 +208,7 @@ pub async fn update(dp: DeviceProfile) -> Result<DeviceProfile, Error> {
device_profile::tags.eq(&dp.tags),
device_profile::measurements.eq(&dp.measurements),
))
.get_result(&c)
.get_result(&mut c)
.map_err(|e| error::Error::from_diesel(e, dp.id.to_string()))
}
})
@ -221,10 +221,10 @@ pub async fn set_measurements(id: Uuid, m: &fields::Measurements) -> Result<Devi
let dp = task::spawn_blocking({
let m = m.clone();
move || -> Result<DeviceProfile, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
diesel::update(device_profile::dsl::device_profile.find(&id))
.set(device_profile::measurements.eq(m))
.get_result(&c)
.get_result(&mut c)
.map_err(|e| Error::from_diesel(e, id.to_string()))
}
})
@ -237,8 +237,9 @@ pub async fn delete(id: &Uuid) -> Result<(), Error> {
task::spawn_blocking({
let id = *id;
move || -> Result<(), Error> {
let c = get_db_conn()?;
let ra = diesel::delete(device_profile::dsl::device_profile.find(&id)).execute(&c)?;
let mut c = get_db_conn()?;
let ra =
diesel::delete(device_profile::dsl::device_profile.find(&id)).execute(&mut c)?;
if ra == 0 {
return Err(error::Error::NotFound(id.to_string()));
}
@ -254,7 +255,7 @@ pub async fn get_count(filters: &Filters) -> Result<i64, Error> {
task::spawn_blocking({
let filters = filters.clone();
move || -> Result<i64, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let mut q = device_profile::dsl::device_profile
.select(dsl::count_star())
.into_boxed();
@ -267,7 +268,7 @@ pub async fn get_count(filters: &Filters) -> Result<i64, Error> {
q = q.filter(device_profile::dsl::name.ilike(format!("%{}%", search)));
}
Ok(q.first(&c)?)
Ok(q.first(&mut c)?)
}
})
.await?
@ -281,7 +282,7 @@ pub async fn list(
task::spawn_blocking({
let filters = filters.clone();
move || -> Result<Vec<DeviceProfileListItem>, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let mut q = device_profile::dsl::device_profile
.select((
device_profile::id,
@ -309,7 +310,7 @@ pub async fn list(
.order_by(device_profile::dsl::name)
.limit(limit)
.offset(offset)
.load(&c)?;
.load(&mut c)?;
Ok(items)
}
})

View File

@ -16,7 +16,7 @@ use super::{error, fields, get_db_conn};
use crate::codec::Codec;
#[derive(Clone, Queryable, Insertable, AsChangeset, Debug, PartialEq)]
#[table_name = "device_profile_template"]
#[diesel(table_name = device_profile_template)]
pub struct DeviceProfileTemplate {
pub id: String,
pub created_at: DateTime<Utc>,
@ -134,10 +134,10 @@ pub async fn create(dp: DeviceProfileTemplate) -> Result<DeviceProfileTemplate,
dp.validate()?;
let dp = task::spawn_blocking({
move || -> Result<DeviceProfileTemplate, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
diesel::insert_into(device_profile_template::table)
.values(&dp)
.get_result(&c)
.get_result(&mut c)
.map_err(|e| error::Error::from_diesel(e, dp.id.to_string()))
}
})
@ -150,7 +150,7 @@ pub async fn upsert(dp: DeviceProfileTemplate) -> Result<DeviceProfileTemplate,
dp.validate()?;
let dp = task::spawn_blocking({
move || -> Result<DeviceProfileTemplate, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
diesel::insert_into(device_profile_template::table)
.values(&dp)
.on_conflict(device_profile_template::id)
@ -188,7 +188,7 @@ pub async fn upsert(dp: DeviceProfileTemplate) -> Result<DeviceProfileTemplate,
device_profile_template::tags.eq(&dp.tags),
device_profile_template::measurements.eq(&dp.measurements),
))
.get_result(&c)
.get_result(&mut c)
.map_err(|e| error::Error::from_diesel(e, dp.id.to_string()))
}
})
@ -201,10 +201,10 @@ pub async fn get(id: &str) -> Result<DeviceProfileTemplate, Error> {
task::spawn_blocking({
let id = id.to_string();
move || -> Result<DeviceProfileTemplate, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let dp = device_profile_template::dsl::device_profile_template
.find(&id)
.first(&c)
.first(&mut c)
.map_err(|e| error::Error::from_diesel(e, id.clone()))?;
Ok(dp)
}
@ -216,7 +216,7 @@ pub async fn update(dp: DeviceProfileTemplate) -> Result<DeviceProfileTemplate,
dp.validate()?;
let dp = task::spawn_blocking({
move || -> Result<DeviceProfileTemplate, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
diesel::update(device_profile_template::dsl::device_profile_template.find(&dp.id))
.set((
@ -251,7 +251,7 @@ pub async fn update(dp: DeviceProfileTemplate) -> Result<DeviceProfileTemplate,
device_profile_template::abp_rx2_freq.eq(&dp.abp_rx2_freq),
device_profile_template::tags.eq(&dp.tags),
))
.get_result(&c)
.get_result(&mut c)
.map_err(|e| error::Error::from_diesel(e, dp.id.clone()))
}
})
@ -264,10 +264,10 @@ pub async fn delete(id: &str) -> Result<(), Error> {
task::spawn_blocking({
let id = id.to_string();
move || -> Result<(), Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let ra =
diesel::delete(device_profile_template::dsl::device_profile_template.find(&id))
.execute(&c)?;
.execute(&mut c)?;
if ra == 0 {
return Err(error::Error::NotFound(id));
}
@ -282,10 +282,10 @@ pub async fn delete(id: &str) -> Result<(), Error> {
pub async fn get_count() -> Result<i64, Error> {
task::spawn_blocking({
move || -> Result<i64, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
Ok(device_profile_template::dsl::device_profile_template
.select(dsl::count_star())
.first(&c)?)
.first(&mut c)?)
}
})
.await?
@ -294,7 +294,7 @@ pub async fn get_count() -> Result<i64, Error> {
pub async fn list(limit: i64, offset: i64) -> Result<Vec<DeviceProfileTemplateListItem>, Error> {
task::spawn_blocking({
move || -> Result<Vec<DeviceProfileTemplateListItem>, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let items = device_profile_template::dsl::device_profile_template
.select((
device_profile_template::id,
@ -318,7 +318,7 @@ pub async fn list(limit: i64, offset: i64) -> Result<Vec<DeviceProfileTemplateLi
))
.limit(limit)
.offset(offset)
.load(&c)?;
.load(&mut c)?;
Ok(items)
}
})

View File

@ -11,7 +11,7 @@ use super::schema::device_queue_item;
use lrwn::EUI64;
#[derive(Queryable, Insertable, AsChangeset, PartialEq, Debug, Clone)]
#[table_name = "device_queue_item"]
#[diesel(table_name = device_queue_item)]
pub struct DeviceQueueItem {
pub id: Uuid,
pub dev_eui: EUI64,
@ -45,10 +45,10 @@ impl Default for DeviceQueueItem {
pub async fn enqueue_item(qi: DeviceQueueItem) -> Result<DeviceQueueItem, Error> {
let qi = task::spawn_blocking({
move || -> Result<DeviceQueueItem, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
diesel::insert_into(device_queue_item::table)
.values(&qi)
.get_result(&c)
.get_result(&mut c)
.map_err(|e| Error::from_diesel(e, qi.id.to_string()))
}
})
@ -61,10 +61,10 @@ pub async fn get_item(id: &Uuid) -> Result<DeviceQueueItem, Error> {
task::spawn_blocking({
let id = *id;
move || -> Result<DeviceQueueItem, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let qi = device_queue_item::dsl::device_queue_item
.find(&id)
.first(&c)
.first(&mut c)
.map_err(|e| Error::from_diesel(e, id.to_string()))?;
Ok(qi)
}
@ -75,14 +75,14 @@ pub async fn get_item(id: &Uuid) -> Result<DeviceQueueItem, Error> {
pub async fn update_item(qi: DeviceQueueItem) -> Result<DeviceQueueItem, Error> {
let qi = task::spawn_blocking({
move || -> Result<DeviceQueueItem, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
diesel::update(device_queue_item::dsl::device_queue_item.find(&qi.id))
.set((
device_queue_item::is_pending.eq(&qi.is_pending),
device_queue_item::f_cnt_down.eq(&qi.f_cnt_down),
device_queue_item::timeout_after.eq(&qi.timeout_after),
))
.get_result(&c)
.get_result(&mut c)
.map_err(|e| Error::from_diesel(e, qi.id.to_string()))
}
})
@ -95,9 +95,9 @@ pub async fn delete_item(id: &Uuid) -> Result<(), Error> {
task::spawn_blocking({
let id = *id;
move || -> Result<(), Error> {
let c = get_db_conn()?;
let ra =
diesel::delete(device_queue_item::dsl::device_queue_item.find(&id)).execute(&c)?;
let mut c = get_db_conn()?;
let ra = diesel::delete(device_queue_item::dsl::device_queue_item.find(&id))
.execute(&mut c)?;
if ra == 0 {
return Err(Error::NotFound(id.to_string()));
}
@ -114,12 +114,12 @@ pub async fn get_next_for_dev_eui(dev_eui: &EUI64) -> Result<(DeviceQueueItem, b
task::spawn_blocking({
let dev_eui = *dev_eui;
move || -> Result<(DeviceQueueItem, bool), Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let items: Vec<DeviceQueueItem> = device_queue_item::dsl::device_queue_item
.filter(device_queue_item::dev_eui.eq(&dev_eui))
.order_by(device_queue_item::created_at)
.limit(2)
.load(&c)
.load(&mut c)
.map_err(|e| Error::from_diesel(e, dev_eui.to_string()))?;
// Return NotFound on empty Vec.
@ -148,11 +148,11 @@ pub async fn get_for_dev_eui(dev_eui: &EUI64) -> Result<Vec<DeviceQueueItem>, Er
task::spawn_blocking({
let dev_eui = *dev_eui;
move || -> Result<Vec<DeviceQueueItem>, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let items = device_queue_item::dsl::device_queue_item
.filter(device_queue_item::dev_eui.eq(&dev_eui))
.order_by(device_queue_item::created_at)
.load(&c)
.load(&mut c)
.map_err(|e| Error::from_diesel(e, dev_eui.to_string()))?;
Ok(items)
}
@ -164,12 +164,12 @@ pub async fn flush_for_dev_eui(dev_eui: &EUI64) -> Result<(), Error> {
let count = task::spawn_blocking({
let dev_eui = *dev_eui;
move || -> Result<usize, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
diesel::delete(
device_queue_item::dsl::device_queue_item
.filter(device_queue_item::dev_eui.eq(&dev_eui)),
)
.execute(&c)
.execute(&mut c)
.map_err(|e| Error::from_diesel(e, dev_eui.to_string()))
}
})
@ -182,14 +182,14 @@ pub async fn get_pending_for_dev_eui(dev_eui: &EUI64) -> Result<DeviceQueueItem,
task::spawn_blocking({
let dev_eui = *dev_eui;
move || -> Result<DeviceQueueItem, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let qi = device_queue_item::dsl::device_queue_item
.filter(
device_queue_item::dev_eui
.eq(&dev_eui)
.and(device_queue_item::is_pending.eq(true)),
)
.first(&c)
.first(&mut c)
.map_err(|e| Error::from_diesel(e, dev_eui.to_string()))?;
Ok(qi)
}

View File

@ -1,14 +1,14 @@
use std::collections::HashMap;
use std::io::Write;
use std::ops::{Deref, DerefMut};
use diesel::pg::types::sql_types::Jsonb;
use diesel::backend;
use diesel::pg::Pg;
use diesel::sql_types::Jsonb;
use diesel::{deserialize, serialize};
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq, AsExpression, FromSqlRow)]
#[sql_type = "Jsonb"]
#[diesel(sql_type = Jsonb)]
pub struct KeyValue(HashMap<String, String>);
impl KeyValue {
@ -37,22 +37,22 @@ impl DerefMut for KeyValue {
}
impl deserialize::FromSql<Jsonb, Pg> for KeyValue {
fn from_sql(bytes: Option<&[u8]>) -> deserialize::Result<Self> {
let value = <serde_json::Value as deserialize::FromSql<Jsonb, Pg>>::from_sql(bytes)?;
fn from_sql(value: backend::RawValue<Pg>) -> deserialize::Result<Self> {
let value = <serde_json::Value as deserialize::FromSql<Jsonb, Pg>>::from_sql(value)?;
let kv: HashMap<String, String> = serde_json::from_value(value)?;
Ok(KeyValue(kv))
}
}
impl serialize::ToSql<Jsonb, Pg> for KeyValue {
fn to_sql<W: Write>(&self, out: &mut serialize::Output<W, Pg>) -> serialize::Result {
fn to_sql<'b>(&'b self, out: &mut serialize::Output<'b, '_, Pg>) -> serialize::Result {
let value = serde_json::to_value(&self.0)?;
<serde_json::Value as serialize::ToSql<Jsonb, Pg>>::to_sql(&value, out)
<serde_json::Value as serialize::ToSql<Jsonb, Pg>>::to_sql(&value, &mut out.reborrow())
}
}
#[derive(Debug, Clone, AsExpression, FromSqlRow, PartialEq)]
#[sql_type = "Jsonb"]
#[diesel(sql_type = Jsonb)]
pub struct Measurements(HashMap<String, Measurement>);
impl Measurements {
@ -81,17 +81,17 @@ impl DerefMut for Measurements {
}
impl deserialize::FromSql<Jsonb, Pg> for Measurements {
fn from_sql(bytes: Option<&[u8]>) -> deserialize::Result<Self> {
let value = <serde_json::Value as deserialize::FromSql<Jsonb, Pg>>::from_sql(bytes)?;
fn from_sql(value: backend::RawValue<Pg>) -> deserialize::Result<Self> {
let value = <serde_json::Value as deserialize::FromSql<Jsonb, Pg>>::from_sql(value)?;
let kv: HashMap<String, Measurement> = serde_json::from_value(value)?;
Ok(Measurements::new(kv))
}
}
impl serialize::ToSql<Jsonb, Pg> for Measurements {
fn to_sql<W: Write>(&self, out: &mut serialize::Output<W, Pg>) -> serialize::Result {
fn to_sql<'b>(&self, out: &mut serialize::Output<'b, '_, Pg>) -> serialize::Result {
let value = serde_json::to_value(&self.0)?;
<serde_json::Value as serialize::ToSql<Jsonb, Pg>>::to_sql(&value, out)
<serde_json::Value as serialize::ToSql<Jsonb, Pg>>::to_sql(&value, &mut out.reborrow())
}
}

View File

@ -14,7 +14,7 @@ use super::schema::{gateway, tenant};
use super::{error::Error, fields, get_db_conn};
#[derive(Queryable, Insertable, AsChangeset, PartialEq, Debug)]
#[table_name = "gateway"]
#[diesel(table_name = gateway)]
pub struct Gateway {
pub gateway_id: EUI64,
pub tenant_id: Uuid,
@ -74,11 +74,11 @@ pub struct Filters {
#[derive(QueryableByName, PartialEq, Debug)]
pub struct GatewaysActiveInactive {
#[sql_type = "diesel::sql_types::BigInt"]
#[diesel(sql_type = diesel::sql_types::BigInt)]
pub never_seen_count: i64,
#[sql_type = "diesel::sql_types::BigInt"]
#[diesel(sql_type = diesel::sql_types::BigInt)]
pub active_count: i64,
#[sql_type = "diesel::sql_types::BigInt"]
#[diesel(sql_type = diesel::sql_types::BigInt)]
pub inactive_count: i64,
}
@ -109,13 +109,13 @@ pub async fn create(gw: Gateway) -> Result<Gateway, Error> {
gw.validate()?;
let gw = task::spawn_blocking({
move || -> Result<Gateway, Error> {
let c = get_db_conn()?;
c.transaction::<Gateway, Error, _>(|| {
let mut c = get_db_conn()?;
c.transaction::<Gateway, Error, _>(|c| {
// use for_update to lock the tenant.
let t: super::tenant::Tenant = tenant::dsl::tenant
.find(&gw.tenant_id)
.for_update()
.get_result(&c)
.get_result(c)
.map_err(|e| Error::from_diesel(e, gw.tenant_id.to_string()))?;
if !t.can_have_gateways {
@ -125,7 +125,7 @@ pub async fn create(gw: Gateway) -> Result<Gateway, Error> {
let gw_count: i64 = gateway::dsl::gateway
.select(dsl::count_star())
.filter(gateway::dsl::tenant_id.eq(&gw.tenant_id))
.first(&c)?;
.first(c)?;
if t.max_gateway_count != 0 && gw_count as i32 >= t.max_gateway_count {
return Err(Error::NotAllowed(
@ -135,7 +135,7 @@ pub async fn create(gw: Gateway) -> Result<Gateway, Error> {
diesel::insert_into(gateway::table)
.values(&gw)
.get_result(&c)
.get_result(c)
.map_err(|e| Error::from_diesel(e, gw.gateway_id.to_string()))
})
}
@ -152,10 +152,10 @@ pub async fn get(gateway_id: &EUI64) -> Result<Gateway, Error> {
task::spawn_blocking({
let gateway_id = *gateway_id;
move || -> Result<Gateway, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let gw = gateway::dsl::gateway
.find(&gateway_id)
.first(&c)
.first(&mut c)
.map_err(|e| Error::from_diesel(e, gateway_id.to_string()))?;
Ok(gw)
}
@ -167,7 +167,7 @@ pub async fn update(gw: Gateway) -> Result<Gateway, Error> {
gw.validate()?;
let gw = task::spawn_blocking({
move || -> Result<Gateway, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
diesel::update(gateway::dsl::gateway.find(&gw.gateway_id))
.set((
gateway::updated_at.eq(Utc::now()),
@ -179,7 +179,7 @@ pub async fn update(gw: Gateway) -> Result<Gateway, Error> {
gateway::stats_interval_secs.eq(&gw.stats_interval_secs),
gateway::tags.eq(&gw.tags),
))
.get_result(&c)
.get_result(&mut c)
.map_err(|e| Error::from_diesel(e, gw.gateway_id.to_string()))
}
})
@ -196,13 +196,13 @@ pub async fn update_state(id: &EUI64, props: &HashMap<String, String>) -> Result
let id = *id;
let props = fields::KeyValue::new(props.clone());
move || -> Result<Gateway, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let gw: Gateway = diesel::update(gateway::dsl::gateway.find(&id))
.set((
gateway::last_seen_at.eq(Some(Utc::now())),
gateway::properties.eq(props),
))
.get_result(&c)
.get_result(&mut c)
.map_err(|e| Error::from_diesel(e, id.to_string()))?;
Ok(gw)
@ -229,7 +229,7 @@ pub async fn update_state_and_loc(
let id = *id;
let props = fields::KeyValue::new(props.clone());
move || -> Result<Gateway, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let gw: Gateway = diesel::update(gateway::dsl::gateway.find(&id))
.set((
gateway::last_seen_at.eq(Some(Utc::now())),
@ -238,7 +238,7 @@ pub async fn update_state_and_loc(
gateway::altitude.eq(alt),
gateway::properties.eq(props),
))
.get_result(&c)
.get_result(&mut c)
.map_err(|e| Error::from_diesel(e, id.to_string()))?;
Ok(gw)
@ -259,10 +259,10 @@ pub async fn update_tls_cert(id: &EUI64, cert: &[u8]) -> Result<Gateway, Error>
let id = *id;
let cert = cert.to_vec();
move || -> Result<Gateway, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let gw: Gateway = diesel::update(gateway::dsl::gateway.find(&id))
.set(gateway::tls_certificate.eq(cert))
.get_result(&c)
.get_result(&mut c)
.map_err(|e| Error::from_diesel(e, id.to_string()))?;
Ok(gw)
}
@ -281,8 +281,8 @@ pub async fn delete(gateway_id: &EUI64) -> Result<(), Error> {
task::spawn_blocking({
let gateway_id = *gateway_id;
move || -> Result<(), Error> {
let c = get_db_conn()?;
let ra = diesel::delete(gateway::dsl::gateway.find(&gateway_id)).execute(&c)?;
let mut c = get_db_conn()?;
let ra = diesel::delete(gateway::dsl::gateway.find(&gateway_id)).execute(&mut c)?;
if ra == 0 {
return Err(Error::NotFound(gateway_id.to_string()));
}
@ -301,7 +301,7 @@ pub async fn get_count(filters: &Filters) -> Result<i64, Error> {
task::spawn_blocking({
let filters = filters.clone();
move || -> Result<i64, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let mut q = gateway::dsl::gateway.select(dsl::count_star()).into_boxed();
if let Some(tenant_id) = &filters.tenant_id {
@ -312,7 +312,7 @@ pub async fn get_count(filters: &Filters) -> Result<i64, Error> {
q = q.filter(gateway::dsl::name.ilike(format!("%{}%", search)));
}
Ok(q.first(&c)?)
Ok(q.first(&mut c)?)
}
})
.await?
@ -326,7 +326,7 @@ pub async fn list(
task::spawn_blocking({
let filters = filters.clone();
move || -> Result<Vec<GatewayListItem>, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let mut q = gateway::dsl::gateway
.select((
gateway::tenant_id,
@ -355,7 +355,7 @@ pub async fn list(
.order_by(gateway::dsl::name)
.limit(limit)
.offset(offset)
.load(&c)?;
.load(&mut c)?;
Ok(items)
}
})
@ -366,7 +366,7 @@ pub async fn get_meta(gateway_id: &EUI64) -> Result<GatewayMeta, Error> {
task::spawn_blocking({
let gateway_id = *gateway_id;
move || -> Result<GatewayMeta, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let meta = gateway::dsl::gateway
.inner_join(tenant::table)
.select((
@ -378,7 +378,7 @@ pub async fn get_meta(gateway_id: &EUI64) -> Result<GatewayMeta, Error> {
tenant::private_gateways,
))
.filter(gateway::dsl::gateway_id.eq(&gateway_id))
.first(&c)
.first(&mut c)
.map_err(|e| Error::from_diesel(e, gateway_id.to_string()))?;
Ok(meta)
@ -393,7 +393,7 @@ pub async fn get_active_inactive(
task::spawn_blocking({
let tenant_id = *tenant_id;
move || -> Result<GatewaysActiveInactive, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let ai: GatewaysActiveInactive = diesel::sql_query(r#"
select
coalesce(sum(case when last_seen_at is null then 1 end), 0) as never_seen_count,
@ -403,7 +403,7 @@ pub async fn get_active_inactive(
gateway
where
$1 is null or tenant_id = $1
"#).bind::<diesel::sql_types::Nullable<diesel::pg::types::sql_types::Uuid>, _>(tenant_id).get_result(&c)?;
"#).bind::<diesel::sql_types::Nullable<diesel::sql_types::Uuid>, _>(tenant_id).get_result(&mut c)?;
Ok(ai)
}
}).await?

View File

@ -5,7 +5,7 @@ use anyhow::Context;
use anyhow::Result;
use diesel::pg::PgConnection;
use diesel::r2d2::{ConnectionManager, Pool, PooledConnection};
use diesel_migrations::embed_migrations;
use diesel_migrations::{embed_migrations, EmbeddedMigrations, MigrationHarness};
use tracing::info;
use crate::config;
@ -40,7 +40,7 @@ lazy_static! {
static ref REDIS_POOL: RwLock<Option<RedisPool>> = RwLock::new(None);
}
embed_migrations!("./migrations");
pub const MIGRATIONS: EmbeddedMigrations = embed_migrations!("./migrations");
pub enum RedisPool {
Client(Pool<redis::Client>),
@ -87,10 +87,12 @@ pub async fn setup() -> Result<()> {
.build(ConnectionManager::new(&conf.postgresql.dsn))
.context("Setup PostgreSQL connection pool error")?;
set_db_pool(pg_pool);
let pg_conn = get_db_conn()?;
let mut pg_conn = get_db_conn()?;
info!("Applying schema migrations");
embedded_migrations::run(&pg_conn).context("Run migrations error")?;
pg_conn
.run_pending_migrations(MIGRATIONS)
.map_err(|e| anyhow!("{}", e))?;
info!("Setting up Redis client");
if conf.redis.cluster {
@ -158,20 +160,11 @@ pub fn redis_key(s: String) -> String {
#[cfg(test)]
pub fn reset_db() -> Result<()> {
use diesel_migrations::{revert_latest_migration, run_pending_migrations};
let conn = get_db_conn()?;
loop {
match revert_latest_migration(&conn) {
Ok(_) => {}
Err(_) => {
break;
}
}
}
// and forward again
run_pending_migrations(&conn)?;
let mut conn = get_db_conn()?;
conn.revert_all_migrations(MIGRATIONS)
.map_err(|e| anyhow!("{}", e))?;
conn.run_pending_migrations(MIGRATIONS)
.map_err(|e| anyhow!("{}", e))?;
Ok(())
}

View File

@ -16,7 +16,7 @@ use crate::downlink::classb;
use crate::{config, gpstime::ToDateTime, gpstime::ToGpsTime};
#[derive(Clone, Queryable, Insertable, AsChangeset, Debug, PartialEq)]
#[table_name = "multicast_group"]
#[diesel(table_name = multicast_group)]
pub struct MulticastGroup {
pub id: Uuid,
pub application_id: Uuid,
@ -83,7 +83,7 @@ pub struct Filters {
}
#[derive(Clone, Queryable, QueryableByName, Insertable, AsChangeset, Debug, PartialEq)]
#[table_name = "multicast_group_queue_item"]
#[diesel(table_name = multicast_group_queue_item)]
pub struct MulticastGroupQueueItem {
pub id: Uuid,
pub created_at: DateTime<Utc>,
@ -118,10 +118,10 @@ pub async fn create(mg: MulticastGroup) -> Result<MulticastGroup, Error> {
mg.validate()?;
let mg = task::spawn_blocking({
move || -> Result<MulticastGroup, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
diesel::insert_into(multicast_group::table)
.values(&mg)
.get_result(&c)
.get_result(&mut c)
.map_err(|e| Error::from_diesel(e, mg.id.to_string()))
}
})
@ -134,10 +134,10 @@ pub async fn get(id: &Uuid) -> Result<MulticastGroup, Error> {
task::spawn_blocking({
let id = *id;
move || -> Result<MulticastGroup, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
multicast_group::dsl::multicast_group
.find(&id)
.first(&c)
.first(&mut c)
.map_err(|e| Error::from_diesel(e, id.to_string()))
}
})
@ -148,7 +148,7 @@ pub async fn update(mg: MulticastGroup) -> Result<MulticastGroup, Error> {
mg.validate()?;
let mg = task::spawn_blocking({
move || -> Result<MulticastGroup, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
diesel::update(multicast_group::dsl::multicast_group.find(&mg.id))
.set((
@ -164,7 +164,7 @@ pub async fn update(mg: MulticastGroup) -> Result<MulticastGroup, Error> {
multicast_group::frequency.eq(&mg.frequency),
multicast_group::class_b_ping_slot_period.eq(&mg.class_b_ping_slot_period),
))
.get_result(&c)
.get_result(&mut c)
.map_err(|e| Error::from_diesel(e, mg.id.to_string()))
}
})
@ -177,8 +177,9 @@ pub async fn delete(id: &Uuid) -> Result<(), Error> {
task::spawn_blocking({
let id = *id;
move || -> Result<(), Error> {
let c = get_db_conn()?;
let ra = diesel::delete(multicast_group::dsl::multicast_group.find(&id)).execute(&c)?;
let mut c = get_db_conn()?;
let ra =
diesel::delete(multicast_group::dsl::multicast_group.find(&id)).execute(&mut c)?;
if ra == 0 {
return Err(Error::NotFound(id.to_string()));
}
@ -194,7 +195,7 @@ pub async fn get_count(filters: &Filters) -> Result<i64, Error> {
task::spawn_blocking({
let filters = filters.clone();
move || -> Result<i64, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let mut q = multicast_group::dsl::multicast_group
.select(dsl::count_star())
.into_boxed();
@ -207,7 +208,8 @@ pub async fn get_count(filters: &Filters) -> Result<i64, Error> {
q = q.filter(multicast_group::dsl::name.ilike(format!("%{}%", search)));
}
q.first(&c).map_err(|e| Error::from_diesel(e, "".into()))
q.first(&mut c)
.map_err(|e| Error::from_diesel(e, "".into()))
}
})
.await?
@ -221,7 +223,7 @@ pub async fn list(
task::spawn_blocking({
let filters = filters.clone();
move || -> Result<Vec<MulticastGroupListItem>, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let mut q = multicast_group::dsl::multicast_group
.select((
multicast_group::id,
@ -244,7 +246,7 @@ pub async fn list(
q.order_by(multicast_group::dsl::name)
.limit(limit)
.offset(offset)
.load(&c)
.load(&mut c)
.map_err(|e| Error::from_diesel(e, "".into()))
}
})
@ -256,18 +258,18 @@ pub async fn add_device(group_id: &Uuid, dev_eui: &EUI64) -> Result<(), Error> {
let group_id = *group_id;
let dev_eui = *dev_eui;
move || -> Result<(), Error> {
let c = get_db_conn()?;
c.transaction::<(), Error, _>(|| {
let mut c = get_db_conn()?;
c.transaction::<(), Error, _>(|c| {
let d: super::device::Device = device::dsl::device
.find(&dev_eui)
.for_update()
.get_result(&c)
.get_result(c)
.map_err(|e| Error::from_diesel(e, dev_eui.to_string()))?;
let mg: MulticastGroup = multicast_group::dsl::multicast_group
.find(&group_id)
.for_update()
.get_result(&c)
.get_result(c)
.map_err(|e| Error::from_diesel(e, group_id.to_string()))?;
if d.application_id != mg.application_id {
@ -281,7 +283,7 @@ pub async fn add_device(group_id: &Uuid, dev_eui: &EUI64) -> Result<(), Error> {
multicast_group_device::dev_eui.eq(&dev_eui),
multicast_group_device::created_at.eq(Utc::now()),
))
.execute(&c)
.execute(c)
.map_err(|e| Error::from_diesel(e, "".into()))?;
Ok(())
})
@ -297,13 +299,13 @@ pub async fn remove_device(group_id: &Uuid, dev_eui: &EUI64) -> Result<(), Error
let group_id = *group_id;
let dev_eui = *dev_eui;
move || -> Result<(), Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let ra = diesel::delete(
multicast_group_device::dsl::multicast_group_device
.filter(multicast_group_device::multicast_group_id.eq(&group_id))
.filter(multicast_group_device::dev_eui.eq(&dev_eui)),
)
.execute(&c)?;
.execute(&mut c)?;
if ra == 0 {
return Err(Error::NotFound(format!(
"multicast-group: {}, device: {}",
@ -322,11 +324,11 @@ pub async fn get_dev_euis(group_id: &Uuid) -> Result<Vec<EUI64>, Error> {
task::spawn_blocking({
let group_id = *group_id;
move || -> Result<Vec<EUI64>, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
multicast_group_device::dsl::multicast_group_device
.select(multicast_group_device::dev_eui)
.filter(multicast_group_device::dsl::multicast_group_id.eq(&group_id))
.load(&c)
.load(&mut c)
.map_err(|e| Error::from_diesel(e, group_id.to_string()))
}
})
@ -344,14 +346,14 @@ pub async fn enqueue(
let (ids, f_cnt) = task::spawn_blocking({
let gateway_ids = gateway_ids.to_vec();
move || -> Result<(Vec<Uuid>, u32), Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let conf = config::get();
c.transaction::<(Vec<Uuid>, u32), Error, _>(|| {
c.transaction::<(Vec<Uuid>, u32), Error, _>(|c| {
let mut ids: Vec<Uuid> = Vec::new();
let mg: MulticastGroup = multicast_group::dsl::multicast_group
.find(&qi.multicast_group_id)
.for_update()
.get_result(&c)
.get_result(c)
.map_err(|e| Error::from_diesel(e, qi.multicast_group_id.to_string()))?;
match mg.group_type.as_ref() {
@ -373,7 +375,7 @@ pub async fn enqueue(
multicast_group_queue_item::dsl::multicast_group_id
.eq(&qi.multicast_group_id),
)
.first(&c)?;
.first(c)?;
// Get timestamp after which we must generate the next ping-slot.
let ping_slot_after_gps_time = match res {
@ -412,7 +414,7 @@ pub async fn enqueue(
let qi: MulticastGroupQueueItem =
diesel::insert_into(multicast_group_queue_item::table)
.values(&qi)
.get_result(&c)
.get_result(c)
.map_err(|e| Error::from_diesel(e, mg.id.to_string()))?;
ids.push(qi.id);
}
@ -428,7 +430,7 @@ pub async fn enqueue(
multicast_group_queue_item::dsl::multicast_group_id
.eq(&qi.multicast_group_id),
)
.first(&c)?;
.first(c)?;
let mut scheduler_run_after_ts = match res {
Some(v) => {
@ -470,7 +472,7 @@ pub async fn enqueue(
let qi: MulticastGroupQueueItem =
diesel::insert_into(multicast_group_queue_item::table)
.values(&qi)
.get_result(&c)
.get_result(c)
.map_err(|e| Error::from_diesel(e, mg.id.to_string()))?;
ids.push(qi.id);
@ -494,7 +496,7 @@ pub async fn enqueue(
diesel::update(multicast_group::dsl::multicast_group.find(&qi.multicast_group_id))
.set(multicast_group::f_cnt.eq(mg.f_cnt + 1))
.execute(&c)
.execute(c)
.map_err(|e| Error::from_diesel(e, qi.multicast_group_id.to_string()))?;
// Return value before it was incremented
@ -511,10 +513,10 @@ pub async fn get_queue_item(id: &Uuid) -> Result<MulticastGroupQueueItem, Error>
task::spawn_blocking({
let id = *id;
move || -> Result<MulticastGroupQueueItem, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
multicast_group_queue_item::dsl::multicast_group_queue_item
.find(&id)
.first(&c)
.first(&mut c)
.map_err(|e| Error::from_diesel(e, id.to_string()))
}
})
@ -525,11 +527,11 @@ pub async fn delete_queue_item(id: &Uuid) -> Result<(), Error> {
task::spawn_blocking({
let id = *id;
move || -> Result<(), Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let ra = diesel::delete(
multicast_group_queue_item::dsl::multicast_group_queue_item.find(&id),
)
.execute(&c)?;
.execute(&mut c)?;
if ra == 0 {
return Err(Error::NotFound(id.to_string()));
}
@ -545,12 +547,12 @@ pub async fn flush_queue(multicast_group_id: &Uuid) -> Result<(), Error> {
task::spawn_blocking({
let multicast_group_id = *multicast_group_id;
move || -> Result<(), Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let _ = diesel::delete(
multicast_group_queue_item::dsl::multicast_group_queue_item
.filter(multicast_group_queue_item::multicast_group_id.eq(&multicast_group_id)),
)
.execute(&c)
.execute(&mut c)
.map_err(|e| Error::from_diesel(e, multicast_group_id.to_string()))?;
Ok(())
}
@ -564,11 +566,11 @@ pub async fn get_queue(multicast_group_id: &Uuid) -> Result<Vec<MulticastGroupQu
task::spawn_blocking({
let multicast_group_id = *multicast_group_id;
move || -> Result<Vec<MulticastGroupQueueItem>, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
multicast_group_queue_item::dsl::multicast_group_queue_item
.filter(multicast_group_queue_item::dsl::multicast_group_id.eq(&multicast_group_id))
.order_by(multicast_group_queue_item::created_at)
.load(&c)
.load(&mut c)
.map_err(|e| Error::from_diesel(e, multicast_group_id.to_string()))
}
})
@ -578,8 +580,8 @@ pub async fn get_queue(multicast_group_id: &Uuid) -> Result<Vec<MulticastGroupQu
pub async fn get_schedulable_queue_items(limit: usize) -> Result<Vec<MulticastGroupQueueItem>> {
task::spawn_blocking({
move || -> Result<Vec<MulticastGroupQueueItem>> {
let c = get_db_conn()?;
c.transaction::<Vec<MulticastGroupQueueItem>, Error, _>(|| {
let mut c = get_db_conn()?;
c.transaction::<Vec<MulticastGroupQueueItem>, Error, _>(|c| {
let conf = config::get();
diesel::sql_query(
r#"
@ -607,7 +609,7 @@ pub async fn get_schedulable_queue_items(limit: usize) -> Result<Vec<MulticastGr
.bind::<diesel::sql_types::Timestamptz, _>(
Utc::now() + Duration::from_std(2 * conf.network.scheduler.interval).unwrap(),
)
.load(&c)
.load(c)
.map_err(|e| Error::from_diesel(e, "".into()))
})
.context("Get schedulable multicast-group queue items")

View File

@ -1,4 +1,6 @@
table! {
// @generated automatically by Diesel CLI.
diesel::table! {
api_key (id) {
id -> Uuid,
created_at -> Timestamptz,
@ -8,7 +10,7 @@ table! {
}
}
table! {
diesel::table! {
application (id) {
id -> Uuid,
tenant_id -> Uuid,
@ -20,7 +22,7 @@ table! {
}
}
table! {
diesel::table! {
application_integration (application_id, kind) {
application_id -> Uuid,
kind -> Varchar,
@ -30,7 +32,7 @@ table! {
}
}
table! {
diesel::table! {
device (dev_eui) {
dev_eui -> Bytea,
application_id -> Uuid,
@ -57,19 +59,19 @@ table! {
}
}
table! {
diesel::table! {
device_keys (dev_eui) {
dev_eui -> Bytea,
created_at -> Timestamptz,
updated_at -> Timestamptz,
nwk_key -> Bytea,
app_key -> Bytea,
dev_nonces -> Array<Int4>,
dev_nonces -> Array<Nullable<Int4>>,
join_nonce -> Int4,
}
}
table! {
diesel::table! {
device_profile (id) {
id -> Uuid,
tenant_id -> Uuid,
@ -103,7 +105,7 @@ table! {
}
}
table! {
diesel::table! {
device_profile_template (id) {
id -> Text,
created_at -> Timestamptz,
@ -138,7 +140,7 @@ table! {
}
}
table! {
diesel::table! {
device_queue_item (id) {
id -> Uuid,
dev_eui -> Bytea,
@ -152,7 +154,7 @@ table! {
}
}
table! {
diesel::table! {
gateway (gateway_id) {
gateway_id -> Bytea,
tenant_id -> Uuid,
@ -171,7 +173,7 @@ table! {
}
}
table! {
diesel::table! {
multicast_group (id) {
id -> Uuid,
application_id -> Uuid,
@ -190,7 +192,7 @@ table! {
}
}
table! {
diesel::table! {
multicast_group_device (multicast_group_id, dev_eui) {
multicast_group_id -> Uuid,
dev_eui -> Bytea,
@ -198,7 +200,7 @@ table! {
}
}
table! {
diesel::table! {
multicast_group_queue_item (id) {
id -> Uuid,
created_at -> Timestamptz,
@ -212,7 +214,7 @@ table! {
}
}
table! {
diesel::table! {
tenant (id) {
id -> Uuid,
created_at -> Timestamptz,
@ -226,7 +228,7 @@ table! {
}
}
table! {
diesel::table! {
tenant_user (tenant_id, user_id) {
tenant_id -> Uuid,
user_id -> Uuid,
@ -238,7 +240,7 @@ table! {
}
}
table! {
diesel::table! {
user (id) {
id -> Uuid,
external_id -> Nullable<Text>,
@ -253,24 +255,24 @@ table! {
}
}
joinable!(api_key -> tenant (tenant_id));
joinable!(application -> tenant (tenant_id));
joinable!(application_integration -> application (application_id));
joinable!(device -> application (application_id));
joinable!(device -> device_profile (device_profile_id));
joinable!(device_keys -> device (dev_eui));
joinable!(device_profile -> tenant (tenant_id));
joinable!(device_queue_item -> device (dev_eui));
joinable!(gateway -> tenant (tenant_id));
joinable!(multicast_group -> application (application_id));
joinable!(multicast_group_device -> device (dev_eui));
joinable!(multicast_group_device -> multicast_group (multicast_group_id));
joinable!(multicast_group_queue_item -> gateway (gateway_id));
joinable!(multicast_group_queue_item -> multicast_group (multicast_group_id));
joinable!(tenant_user -> tenant (tenant_id));
joinable!(tenant_user -> user (user_id));
diesel::joinable!(api_key -> tenant (tenant_id));
diesel::joinable!(application -> tenant (tenant_id));
diesel::joinable!(application_integration -> application (application_id));
diesel::joinable!(device -> application (application_id));
diesel::joinable!(device -> device_profile (device_profile_id));
diesel::joinable!(device_keys -> device (dev_eui));
diesel::joinable!(device_profile -> tenant (tenant_id));
diesel::joinable!(device_queue_item -> device (dev_eui));
diesel::joinable!(gateway -> tenant (tenant_id));
diesel::joinable!(multicast_group -> application (application_id));
diesel::joinable!(multicast_group_device -> device (dev_eui));
diesel::joinable!(multicast_group_device -> multicast_group (multicast_group_id));
diesel::joinable!(multicast_group_queue_item -> gateway (gateway_id));
diesel::joinable!(multicast_group_queue_item -> multicast_group (multicast_group_id));
diesel::joinable!(tenant_user -> tenant (tenant_id));
diesel::joinable!(tenant_user -> user (user_id));
allow_tables_to_appear_in_same_query!(
diesel::allow_tables_to_appear_in_same_query!(
api_key,
application,
application_integration,

View File

@ -16,25 +16,25 @@ lazy_static! {
#[derive(QueryableByName, PartialEq, Debug)]
pub struct SearchResult {
#[sql_type = "diesel::sql_types::Text"]
#[diesel(sql_type = diesel::sql_types::Text)]
pub kind: String,
#[sql_type = "diesel::sql_types::Float"]
#[diesel(sql_type = diesel::sql_types::Float)]
pub score: f32,
#[sql_type = "diesel::sql_types::Nullable<diesel::sql_types::Uuid>"]
#[diesel(sql_type = diesel::sql_types::Nullable<diesel::sql_types::Uuid>)]
pub tenant_id: Option<Uuid>,
#[sql_type = "diesel::sql_types::Nullable<diesel::sql_types::Text>"]
#[diesel(sql_type = diesel::sql_types::Nullable<diesel::sql_types::Text>)]
pub tenant_name: Option<String>,
#[sql_type = "diesel::sql_types::Nullable<diesel::sql_types::Uuid>"]
#[diesel(sql_type = diesel::sql_types::Nullable<diesel::sql_types::Uuid>)]
pub application_id: Option<Uuid>,
#[sql_type = "diesel::sql_types::Nullable<diesel::sql_types::Text>"]
#[diesel(sql_type = diesel::sql_types::Nullable<diesel::sql_types::Text>)]
pub application_name: Option<String>,
#[sql_type = "diesel::sql_types::Nullable<diesel::sql_types::Binary>"]
#[diesel(sql_type = diesel::sql_types::Nullable<diesel::sql_types::Binary>)]
pub device_dev_eui: Option<EUI64>,
#[sql_type = "diesel::sql_types::Nullable<diesel::sql_types::Text>"]
#[diesel(sql_type = diesel::sql_types::Nullable<diesel::sql_types::Text>)]
pub device_name: Option<String>,
#[sql_type = "diesel::sql_types::Nullable<diesel::sql_types::Binary>"]
#[diesel(sql_type = diesel::sql_types::Nullable<diesel::sql_types::Binary>)]
pub gateway_id: Option<EUI64>,
#[sql_type = "diesel::sql_types::Nullable<diesel::sql_types::Text>"]
#[diesel(sql_type = diesel::sql_types::Nullable<diesel::sql_types::Text>)]
pub gateway_name: Option<String>,
}
@ -53,7 +53,7 @@ pub async fn global_search(
let tags = serde_json::to_value(&tags).context("To serde_json value")?;
move || -> Result<Vec<SearchResult>, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let res = diesel::sql_query(
r#"
-- device
@ -163,7 +163,7 @@ pub async fn global_search(
.bind::<diesel::sql_types::BigInt, _>(limit as i64)
.bind::<diesel::sql_types::BigInt, _>(offset as i64)
.bind::<diesel::sql_types::Jsonb, _>(tags)
.load(&c)?;
.load(&mut c)?;
Ok(res)
}

View File

@ -11,7 +11,7 @@ use super::get_db_conn;
use super::schema::{tenant, tenant_user, user};
#[derive(Queryable, Insertable, AsChangeset, PartialEq, Debug, Clone)]
#[table_name = "tenant"]
#[diesel(table_name = tenant)]
pub struct Tenant {
pub id: Uuid,
pub created_at: DateTime<Utc>,
@ -52,7 +52,7 @@ impl Default for Tenant {
}
#[derive(Queryable, Insertable, AsChangeset, PartialEq, Debug)]
#[table_name = "tenant_user"]
#[diesel(table_name = tenant_user)]
pub struct TenantUser {
pub tenant_id: Uuid,
pub user_id: Uuid,
@ -101,10 +101,10 @@ pub async fn create(t: Tenant) -> Result<Tenant, Error> {
t.validate()?;
let t = task::spawn_blocking({
move || -> Result<Tenant, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
diesel::insert_into(tenant::table)
.values(&t)
.get_result(&c)
.get_result(&mut c)
.map_err(|e| Error::from_diesel(e, t.id.to_string()))
}
})
@ -117,10 +117,10 @@ pub async fn get(id: &Uuid) -> Result<Tenant, Error> {
task::spawn_blocking({
let id = *id;
move || -> Result<Tenant, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let t = tenant::dsl::tenant
.find(&id)
.first(&c)
.first(&mut c)
.map_err(|e| Error::from_diesel(e, id.to_string()))?;
Ok(t)
}
@ -132,7 +132,7 @@ pub async fn update(t: Tenant) -> Result<Tenant, Error> {
t.validate()?;
let t = task::spawn_blocking({
move || -> Result<Tenant, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
diesel::update(tenant::dsl::tenant.find(&t.id))
.set((
tenant::updated_at.eq(Utc::now()),
@ -143,7 +143,7 @@ pub async fn update(t: Tenant) -> Result<Tenant, Error> {
tenant::max_gateway_count.eq(&t.max_gateway_count),
tenant::private_gateways.eq(&t.private_gateways),
))
.get_result(&c)
.get_result(&mut c)
.map_err(|e| Error::from_diesel(e, t.id.to_string()))
}
})
@ -156,9 +156,9 @@ pub async fn delete(id: &Uuid) -> Result<(), Error> {
task::spawn_blocking({
let id = *id;
move || -> Result<(), Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let ra = diesel::delete(tenant::dsl::tenant.find(&id))
.execute(&c)
.execute(&mut c)
.map_err(|e| Error::from_diesel(e, id.to_string()))?;
if ra == 0 {
@ -176,10 +176,9 @@ pub async fn get_count(filters: &Filters) -> Result<i64, Error> {
task::spawn_blocking({
let filters = filters.clone();
move || -> Result<i64, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let mut q = tenant::dsl::tenant
.left_join(tenant_user::table)
.select(dsl::sql("count(distinct id)"))
.into_boxed();
if let Some(user_id) = &filters.user_id {
@ -190,7 +189,10 @@ pub async fn get_count(filters: &Filters) -> Result<i64, Error> {
q = q.filter(tenant::dsl::name.ilike(format!("%{}%", search)));
}
Ok(q.first(&c)?)
Ok(
q.select(dsl::sql::<diesel::sql_types::BigInt>("count(distinct id)"))
.first(&mut c)?,
)
}
})
.await?
@ -200,9 +202,14 @@ pub async fn list(limit: i64, offset: i64, filters: &Filters) -> Result<Vec<Tena
task::spawn_blocking({
let filters = filters.clone();
move || -> Result<Vec<Tenant>, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let mut q = tenant::dsl::tenant
.left_join(tenant_user::table)
.select(tenant::all_columns)
.group_by(tenant::dsl::id)
.order_by(tenant::dsl::name)
.limit(limit)
.offset(offset)
.into_boxed();
if let Some(user_id) = &filters.user_id {
@ -213,13 +220,7 @@ pub async fn list(limit: i64, offset: i64, filters: &Filters) -> Result<Vec<Tena
q = q.filter(tenant::dsl::name.ilike(format!("%{}%", search)));
}
let items = q
.select(tenant::all_columns)
.group_by(tenant::dsl::id)
.order_by(tenant::dsl::name)
.limit(limit)
.offset(offset)
.load(&c)?;
let items = q.load(&mut c)?;
Ok(items)
}
@ -230,10 +231,10 @@ pub async fn list(limit: i64, offset: i64, filters: &Filters) -> Result<Vec<Tena
pub async fn add_user(tu: TenantUser) -> Result<TenantUser, Error> {
let tu = task::spawn_blocking({
move || -> Result<TenantUser, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
diesel::insert_into(tenant_user::table)
.values(&tu)
.get_result(&c)
.get_result(&mut c)
.map_err(|e| Error::from_diesel(e, tu.user_id.to_string()))
}
})
@ -249,14 +250,14 @@ pub async fn add_user(tu: TenantUser) -> Result<TenantUser, Error> {
pub async fn update_user(tu: TenantUser) -> Result<TenantUser, Error> {
let tu = task::spawn_blocking({
move || -> Result<TenantUser, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
diesel::update(
tenant_user::dsl::tenant_user
.filter(tenant_user::dsl::tenant_id.eq(&tu.tenant_id))
.filter(tenant_user::dsl::user_id.eq(&tu.user_id)),
)
.set(&tu)
.get_result(&c)
.get_result(&mut c)
.map_err(|e| Error::from_diesel(e, tu.user_id.to_string()))
}
})
@ -274,11 +275,11 @@ pub async fn get_user(tenant_id: &Uuid, user_id: &Uuid) -> Result<TenantUser, Er
let tenant_id = *tenant_id;
let user_id = *user_id;
move || -> Result<TenantUser, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let tu: TenantUser = tenant_user::dsl::tenant_user
.filter(tenant_user::dsl::tenant_id.eq(&tenant_id))
.filter(tenant_user::dsl::user_id.eq(&user_id))
.first(&c)
.first(&mut c)
.map_err(|e| Error::from_diesel(e, user_id.to_string()))?;
Ok(tu)
}
@ -290,11 +291,11 @@ pub async fn get_user_count(tenant_id: &Uuid) -> Result<i64, Error> {
task::spawn_blocking({
let tenant_id = *tenant_id;
move || -> Result<i64, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let count = tenant_user::dsl::tenant_user
.select(dsl::count_star())
.filter(tenant_user::dsl::tenant_id.eq(&tenant_id))
.first(&c)?;
.first(&mut c)?;
Ok(count)
}
})
@ -309,7 +310,7 @@ pub async fn get_users(
task::spawn_blocking({
let tenant_id = *tenant_id;
move || -> Result<Vec<TenantUserListItem>, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let items = tenant_user::dsl::tenant_user
.inner_join(user::table)
.select((
@ -326,7 +327,7 @@ pub async fn get_users(
.order_by(user::dsl::email)
.limit(limit)
.offset(offset)
.load(&c)?;
.load(&mut c)?;
Ok(items)
}
@ -339,13 +340,13 @@ pub async fn delete_user(tenant_id: &Uuid, user_id: &Uuid) -> Result<(), Error>
let tenant_id = *tenant_id;
let user_id = *user_id;
move || -> Result<(), Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let ra = diesel::delete(
tenant_user::dsl::tenant_user
.filter(tenant_user::dsl::tenant_id.eq(&tenant_id))
.filter(tenant_user::dsl::user_id.eq(&user_id)),
)
.execute(&c)?;
.execute(&mut c)?;
if ra == 0 {
return Err(Error::NotFound(user_id.to_string()));
}
@ -365,10 +366,10 @@ pub async fn get_tenant_users_for_user(user_id: &Uuid) -> Result<Vec<TenantUser>
task::spawn_blocking({
let user_id = *user_id;
move || -> Result<Vec<TenantUser>, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let items = tenant_user::dsl::tenant_user
.filter(tenant_user::dsl::user_id.eq(&user_id))
.load(&c)?;
.load(&mut c)?;
Ok(items)
}
})

View File

@ -17,7 +17,7 @@ use super::get_db_conn;
use super::schema::user;
#[derive(Queryable, Insertable, AsChangeset, PartialEq, Debug, Clone)]
#[table_name = "user"]
#[diesel(table_name = user)]
pub struct User {
pub id: Uuid,
pub external_id: Option<String>,
@ -69,11 +69,11 @@ pub async fn create(u: User) -> Result<User, Error> {
u.validate()?;
let u = task::spawn_blocking({
move || -> Result<User, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
diesel::insert_into(user::table)
.values(&u)
.get_result(&c)
.get_result(&mut c)
.map_err(|e| Error::from_diesel(e, u.id.to_string()))
}
})
@ -86,10 +86,10 @@ pub async fn get(id: &Uuid) -> Result<User, Error> {
task::spawn_blocking({
let id = *id;
move || -> Result<User, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let u = user::dsl::user
.find(&id)
.first(&c)
.first(&mut c)
.map_err(|e| Error::from_diesel(e, id.to_string()))?;
Ok(u)
}
@ -101,10 +101,10 @@ pub async fn get_by_email(email: &str) -> Result<User, Error> {
task::spawn_blocking({
let email = email.to_string();
move || -> Result<User, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let u = user::dsl::user
.filter(user::dsl::email.eq(&email))
.first(&c)
.first(&mut c)
.map_err(|e| Error::from_diesel(e, email))?;
Ok(u)
}
@ -116,10 +116,10 @@ pub async fn get_by_external_id(external_id: &str) -> Result<User, Error> {
task::spawn_blocking({
let external_id = external_id.to_string();
move || -> Result<User, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let u = user::dsl::user
.filter(user::dsl::external_id.eq(&external_id))
.first(&c)
.first(&mut c)
.map_err(|e| Error::from_diesel(e, external_id))?;
Ok(u)
}
@ -132,10 +132,10 @@ pub async fn get_by_email_and_pw(email: &str, pw: &str) -> Result<User, Error> {
let email = email.to_string();
let pw = pw.to_string();
move || -> Result<User, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let u: User = match user::dsl::user
.filter(user::dsl::email.eq(&email))
.first(&c)
.first(&mut c)
.map_err(|e| Error::from_diesel(e, email))
{
Ok(v) => v,
@ -161,7 +161,7 @@ pub async fn update(u: User) -> Result<User, Error> {
u.validate()?;
let u = task::spawn_blocking({
move || -> Result<User, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
diesel::update(user::dsl::user.find(&u.id))
.set((
user::updated_at.eq(Utc::now()),
@ -172,7 +172,7 @@ pub async fn update(u: User) -> Result<User, Error> {
user::note.eq(&u.note),
user::external_id.eq(&u.external_id),
))
.get_result(&c)
.get_result(&mut c)
.map_err(|e| Error::from_diesel(e, u.id.to_string()))
}
})
@ -186,10 +186,10 @@ pub async fn set_password_hash(id: &Uuid, hash: &str) -> Result<User, Error> {
let id = *id;
let hash = hash.to_string();
move || -> Result<User, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
diesel::update(user::dsl::user.find(&id))
.set(user::password_hash.eq(&hash))
.get_result(&c)
.get_result(&mut c)
.map_err(|e| Error::from_diesel(e, id.to_string()))
}
})
@ -202,9 +202,9 @@ pub async fn delete(id: &Uuid) -> Result<(), Error> {
task::spawn_blocking({
let id = *id;
move || -> Result<(), Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let ra = diesel::delete(user::dsl::user.find(&id))
.execute(&c)
.execute(&mut c)
.map_err(|e| Error::from_diesel(e, id.to_string()))?;
if ra == 0 {
@ -221,8 +221,8 @@ pub async fn delete(id: &Uuid) -> Result<(), Error> {
pub async fn get_count() -> Result<i64, Error> {
task::spawn_blocking({
move || -> Result<i64, Error> {
let c = get_db_conn()?;
let count = user::dsl::user.select(dsl::count_star()).first(&c)?;
let mut c = get_db_conn()?;
let count = user::dsl::user.select(dsl::count_star()).first(&mut c)?;
Ok(count)
}
})
@ -232,12 +232,12 @@ pub async fn get_count() -> Result<i64, Error> {
pub async fn list(limit: i64, offset: i64) -> Result<Vec<User>, Error> {
task::spawn_blocking({
move || -> Result<Vec<User>, Error> {
let c = get_db_conn()?;
let mut c = get_db_conn()?;
let items = user::dsl::user
.order_by(user::dsl::email)
.limit(limit)
.offset(offset)
.load(&c)?;
.load(&mut c)?;
Ok(items)
}
})

View File

@ -98,7 +98,7 @@ async fn test_gateway_filtering() {
let dk = device_keys::create(device_keys::DeviceKeys {
dev_eui: dev.dev_eui.clone(),
nwk_key: AES128Key::from_bytes([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]),
dev_nonces: vec![258],
dev_nonces: vec![Some(258)],
..Default::default()
})
.await
@ -259,7 +259,7 @@ async fn test_lorawan_10() {
let dk = device_keys::create(device_keys::DeviceKeys {
dev_eui: dev.dev_eui.clone(),
nwk_key: AES128Key::from_bytes([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]),
dev_nonces: vec![258],
dev_nonces: vec![Some(258)],
..Default::default()
})
.await
@ -902,7 +902,7 @@ async fn test_lorawan_11() {
dev_eui: dev.dev_eui.clone(),
nwk_key: AES128Key::from_bytes([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]),
app_key: AES128Key::from_bytes([16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1]),
dev_nonces: vec![258],
dev_nonces: vec![Some(258)],
..Default::default()
})
.await

View File

@ -13,7 +13,7 @@ hex = "0.4"
cmac = "0.6"
aes = "0.7"
serde = { version = "1.0", features = ["derive"] }
diesel = { version = "1.4", features = [ "postgres" ] }
diesel = { version = "2.0.0-rc.0", features = [ "postgres" ] }
# Error handling
thiserror = "1.0"

View File

@ -1,9 +1,8 @@
use std::fmt;
use std::io::Write;
use std::str::FromStr;
use anyhow::Result;
use diesel::backend::Backend;
use diesel::backend::{self, Backend};
use diesel::sql_types::Binary;
use diesel::{deserialize, serialize};
use serde::de::{self, Visitor};
@ -12,7 +11,7 @@ use serde::{Deserialize, Deserializer, Serialize, Serializer};
use crate::Error;
#[derive(Copy, Clone, PartialEq, AsExpression, FromSqlRow, Default)]
#[sql_type = "diesel::sql_types::Binary"]
#[diesel(sql_type = diesel::sql_types::Binary)]
pub struct AES128Key([u8; 16]);
impl AES128Key {
@ -100,13 +99,13 @@ impl<'de> Visitor<'de> for Aes128KeyVisitor {
}
}
impl<ST, DB> deserialize::FromSql<ST, DB> for AES128Key
impl<DB> deserialize::FromSql<Binary, DB> for AES128Key
where
DB: Backend,
*const [u8]: deserialize::FromSql<ST, DB>,
*const [u8]: deserialize::FromSql<Binary, DB>,
{
fn from_sql(bytes: Option<&DB::RawValue>) -> deserialize::Result<Self> {
let bytes = Vec::<u8>::from_sql(bytes)?;
fn from_sql(value: backend::RawValue<DB>) -> deserialize::Result<Self> {
let bytes = Vec::<u8>::from_sql(value)?;
if bytes.len() != 16 {
return Err("AES128Key type expects exactly 16 bytes".into());
}
@ -118,13 +117,15 @@ where
}
}
impl<DB> serialize::ToSql<Binary, DB> for AES128Key
impl serialize::ToSql<Binary, diesel::pg::Pg> for AES128Key
where
DB: Backend,
[u8]: serialize::ToSql<Binary, DB>,
[u8]: serialize::ToSql<Binary, diesel::pg::Pg>,
{
fn to_sql<W: Write>(&self, out: &mut serialize::Output<W, DB>) -> serialize::Result {
(&self.to_bytes() as &[u8]).to_sql(out)
fn to_sql<'b>(&self, out: &mut serialize::Output<'b, '_, diesel::pg::Pg>) -> serialize::Result {
<[u8] as serialize::ToSql<Binary, diesel::pg::Pg>>::to_sql(
&self.to_bytes(),
&mut out.reborrow(),
)
}
}

View File

@ -8,7 +8,7 @@ use super::netid::NetID;
use crate::Error;
#[derive(PartialEq, Copy, Clone, AsExpression, FromSqlRow, Default)]
#[sql_type = "diesel::sql_types::Binary"]
#[diesel(sql_type = diesel::sql_types::Binary)]
pub struct DevAddr([u8; 4]);
impl DevAddr {
@ -174,19 +174,17 @@ impl Serialize for DevAddr {
}
}
use std::io::Write;
use diesel::backend::Backend;
use diesel::backend::{self, Backend};
use diesel::sql_types::Binary;
use diesel::{deserialize, serialize};
impl<ST, DB> deserialize::FromSql<ST, DB> for DevAddr
impl<DB> deserialize::FromSql<Binary, DB> for DevAddr
where
DB: Backend,
*const [u8]: deserialize::FromSql<ST, DB>,
*const [u8]: deserialize::FromSql<Binary, DB>,
{
fn from_sql(bytes: Option<&DB::RawValue>) -> deserialize::Result<Self> {
let bytes = Vec::<u8>::from_sql(bytes)?;
fn from_sql(value: backend::RawValue<DB>) -> deserialize::Result<Self> {
let bytes = Vec::<u8>::from_sql(value)?;
if bytes.len() != 4 {
return Err("DevAddr type expects exactly 4 bytes".into());
}
@ -198,13 +196,15 @@ where
}
}
impl<DB> serialize::ToSql<Binary, DB> for DevAddr
impl serialize::ToSql<Binary, diesel::pg::Pg> for DevAddr
where
DB: Backend,
[u8]: serialize::ToSql<Binary, DB>,
[u8]: serialize::ToSql<Binary, diesel::pg::Pg>,
{
fn to_sql<W: Write>(&self, out: &mut serialize::Output<W, DB>) -> serialize::Result {
(&self.to_be_bytes() as &[u8]).to_sql(out)
fn to_sql<'b>(&self, out: &mut serialize::Output<'b, '_, diesel::pg::Pg>) -> serialize::Result {
<[u8] as serialize::ToSql<Binary, diesel::pg::Pg>>::to_sql(
&self.to_be_bytes(),
&mut out.reborrow(),
)
}
}

View File

@ -8,7 +8,7 @@ use serde::{Deserialize, Deserializer, Serialize, Serializer};
use crate::Error;
#[derive(Copy, Clone, PartialEq, Eq, Hash, AsExpression, FromSqlRow, Default)]
#[sql_type = "diesel::sql_types::Binary"]
#[diesel(sql_type = diesel::sql_types::Binary)]
pub struct EUI64([u8; 8]);
impl EUI64 {
@ -104,19 +104,17 @@ impl<'de> Visitor<'de> for Eui64Visitor {
}
}
use std::io::Write;
use diesel::backend::Backend;
use diesel::backend::{self, Backend};
use diesel::sql_types::Binary;
use diesel::{deserialize, serialize};
impl<DB> deserialize::FromSql<diesel::sql_types::Binary, DB> for EUI64
impl<DB> deserialize::FromSql<Binary, DB> for EUI64
where
DB: Backend,
*const [u8]: deserialize::FromSql<diesel::sql_types::Binary, DB>,
*const [u8]: deserialize::FromSql<Binary, DB>,
{
fn from_sql(bytes: Option<&DB::RawValue>) -> deserialize::Result<Self> {
let bytes = Vec::<u8>::from_sql(bytes)?;
fn from_sql(value: backend::RawValue<DB>) -> deserialize::Result<Self> {
let bytes = Vec::<u8>::from_sql(value)?;
if bytes.len() != 8 {
return Err("EUI64 type expects exactly 8 bytes".into());
}
@ -128,17 +126,21 @@ where
}
}
impl<DB> serialize::ToSql<Binary, DB> for EUI64
impl serialize::ToSql<Binary, diesel::pg::Pg> for EUI64
where
DB: Backend,
[u8]: serialize::ToSql<Binary, DB>,
[u8]: serialize::ToSql<Binary, diesel::pg::Pg>,
{
fn to_sql<W: Write>(&self, out: &mut serialize::Output<W, DB>) -> serialize::Result {
(&self.to_be_bytes() as &[u8]).to_sql(out)
fn to_sql<'b>(&self, out: &mut serialize::Output<'b, '_, diesel::pg::Pg>) -> serialize::Result {
<[u8] as serialize::ToSql<Binary, diesel::pg::Pg>>::to_sql(
&self.to_be_bytes(),
&mut out.reborrow(),
)
}
}
impl diesel::sql_types::NotNull for EUI64 {}
impl diesel::sql_types::SqlType for EUI64 {
type IsNull = diesel::sql_types::is_nullable::NotNull;
}
#[cfg(test)]
mod tests {

View File

@ -1,11 +1,10 @@
use std::collections::{HashMap, HashSet};
use std::fmt;
use std::io::Write;
use std::str::FromStr;
use std::time::Duration;
use anyhow::{Context, Result};
use diesel::backend::Backend;
use diesel::backend::{self, Backend};
use diesel::sql_types::Text;
use diesel::{deserialize, serialize};
use serde::{Deserialize, Serialize};
@ -28,7 +27,7 @@ pub mod us915;
#[derive(Deserialize, Serialize, Copy, Clone, Debug, Eq, PartialEq, AsExpression, FromSqlRow)]
#[allow(non_camel_case_types)]
#[sql_type = "diesel::sql_types::Text"]
#[diesel(sql_type = diesel::sql_types::Text)]
pub enum CommonName {
EU868,
US915,
@ -52,24 +51,29 @@ impl fmt::Display for CommonName {
}
}
impl<ST, DB> deserialize::FromSql<ST, DB> for CommonName
impl<DB> deserialize::FromSql<Text, DB> for CommonName
where
DB: Backend,
*const str: deserialize::FromSql<ST, DB>,
*const str: deserialize::FromSql<Text, DB>,
{
fn from_sql(bytes: Option<&DB::RawValue>) -> deserialize::Result<Self> {
let string = String::from_sql(bytes)?;
fn from_sql(value: backend::RawValue<DB>) -> deserialize::Result<Self> {
let string = String::from_sql(value)?;
Ok(CommonName::from_str(&string)?)
}
}
impl<DB> serialize::ToSql<Text, DB> for CommonName
impl serialize::ToSql<Text, diesel::pg::Pg> for CommonName
where
DB: Backend,
str: serialize::ToSql<Text, DB>,
str: serialize::ToSql<Text, diesel::pg::Pg>,
{
fn to_sql<W: Write>(&self, out: &mut serialize::Output<W, DB>) -> serialize::Result {
self.to_string().as_str().to_sql(out)
fn to_sql<'b>(
&'b self,
out: &mut serialize::Output<'b, '_, diesel::pg::Pg>,
) -> serialize::Result {
<str as serialize::ToSql<Text, diesel::pg::Pg>>::to_sql(
&self.to_string(),
&mut out.reborrow(),
)
}
}
@ -101,7 +105,7 @@ impl FromStr for CommonName {
#[allow(non_camel_case_types)]
#[derive(Clone, Copy, PartialEq, Eq, Hash, AsExpression, FromSqlRow)]
#[sql_type = "diesel::sql_types::Text"]
#[diesel(sql_type = diesel::sql_types::Text)]
pub enum Revision {
Latest,
A,
@ -155,30 +159,35 @@ impl FromStr for Revision {
}
}
impl<ST, DB> deserialize::FromSql<ST, DB> for Revision
impl<DB> deserialize::FromSql<Text, DB> for Revision
where
DB: Backend,
*const str: deserialize::FromSql<ST, DB>,
*const str: deserialize::FromSql<Text, DB>,
{
fn from_sql(bytes: Option<&DB::RawValue>) -> deserialize::Result<Self> {
let string = String::from_sql(bytes)?;
fn from_sql(value: backend::RawValue<DB>) -> deserialize::Result<Self> {
let string = String::from_sql(value)?;
Ok(Revision::from_str(&string)?)
}
}
impl<DB> serialize::ToSql<Text, DB> for Revision
impl serialize::ToSql<Text, diesel::pg::Pg> for Revision
where
DB: Backend,
str: serialize::ToSql<Text, DB>,
str: serialize::ToSql<Text, diesel::pg::Pg>,
{
fn to_sql<W: Write>(&self, out: &mut serialize::Output<W, DB>) -> serialize::Result {
self.to_string().as_str().to_sql(out)
fn to_sql<'b>(
&'b self,
out: &mut serialize::Output<'b, '_, diesel::pg::Pg>,
) -> serialize::Result {
<str as serialize::ToSql<Text, diesel::pg::Pg>>::to_sql(
&self.to_string(),
&mut out.reborrow(),
)
}
}
#[allow(non_camel_case_types)]
#[derive(Copy, Clone, PartialEq, Eq, Hash, AsExpression, FromSqlRow)]
#[sql_type = "diesel::sql_types::Text"]
#[diesel(sql_type = diesel::sql_types::Text)]
pub enum MacVersion {
Latest,
LORAWAN_1_0_0,
@ -232,24 +241,29 @@ impl FromStr for MacVersion {
}
}
impl<ST, DB> deserialize::FromSql<ST, DB> for MacVersion
impl<DB> deserialize::FromSql<Text, DB> for MacVersion
where
DB: Backend,
*const str: deserialize::FromSql<ST, DB>,
*const str: deserialize::FromSql<Text, DB>,
{
fn from_sql(bytes: Option<&DB::RawValue>) -> deserialize::Result<Self> {
let string = String::from_sql(bytes)?;
fn from_sql(value: backend::RawValue<DB>) -> deserialize::Result<Self> {
let string = String::from_sql(value)?;
Ok(MacVersion::from_str(&string)?)
}
}
impl<DB> serialize::ToSql<Text, DB> for MacVersion
impl serialize::ToSql<Text, diesel::pg::Pg> for MacVersion
where
DB: Backend,
str: serialize::ToSql<Text, DB>,
str: serialize::ToSql<Text, diesel::pg::Pg>,
{
fn to_sql<W: Write>(&self, out: &mut serialize::Output<W, DB>) -> serialize::Result {
self.to_string().as_str().to_sql(out)
fn to_sql<'b>(
&'b self,
out: &mut serialize::Output<'b, '_, diesel::pg::Pg>,
) -> serialize::Result {
<str as serialize::ToSql<Text, diesel::pg::Pg>>::to_sql(
&self.to_string(),
&mut out.reborrow(),
)
}
}