mirror of
https://github.com/chirpstack/chirpstack.git
synced 2025-06-01 07:20:44 +00:00
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:
parent
11d433a394
commit
634aea6a71
86
Cargo.lock
generated
86
Cargo.lock
generated
@ -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",
|
||||
|
@ -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
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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?
|
||||
|
@ -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(())
|
||||
|
@ -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())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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??;
|
||||
|
@ -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
|
||||
|
@ -1,7 +1,6 @@
|
||||
#![allow(dead_code)]
|
||||
#[macro_use]
|
||||
extern crate lazy_static;
|
||||
#[macro_use]
|
||||
extern crate diesel_migrations;
|
||||
#[macro_use]
|
||||
extern crate diesel;
|
||||
|
@ -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)
|
||||
}
|
||||
})
|
||||
|
@ -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())
|
||||
}
|
||||
|
@ -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")
|
||||
|
@ -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()))
|
||||
})
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
})
|
||||
|
@ -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)
|
||||
}
|
||||
})
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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?
|
||||
|
@ -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(())
|
||||
}
|
||||
|
@ -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")
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
})
|
||||
|
@ -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)
|
||||
}
|
||||
})
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
|
@ -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(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user