diff --git a/Cargo.toml b/Cargo.toml index 5356a03..96bc4a9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,6 +4,7 @@ version = "0.1.0" edition = "2021" + # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] @@ -13,6 +14,6 @@ tokio = { version = "1.23.0", features = ["full"] } serde = { version = "1.0.130", features = ["derive", "default"] } serde_json = "1.0" google-bigquery2 = "4.0.1" -async-trait = "0.1.60" google_bigquery_derive = { path = "./google_bigquery_derive" } -chrono = "0.4.23" \ No newline at end of file +chrono = "0.4.23" +async-trait = "0.1.65" diff --git a/google_bigquery_derive/Cargo.toml b/google_bigquery_derive/Cargo.toml index 7ee88aa..185088b 100644 --- a/google_bigquery_derive/Cargo.toml +++ b/google_bigquery_derive/Cargo.toml @@ -4,7 +4,7 @@ version = "0.0.1" authors = ["OMGeeky "] description = "A `cargo generate` template for quick-starting a procedural macro crate" keywords = ["template", "proc_macro", "procmacro"] -edition = "2018" +edition = "2021" [lib] proc-macro = true @@ -12,4 +12,4 @@ proc-macro = true [dependencies] quote = "1" proc-macro2 = "1.0" -syn = { version = "1.0", features = ["extra-traits", "parsing", "full"] } +syn = { version = "1.0", features = ["extra-traits", "parsing", "full"] } \ No newline at end of file diff --git a/src/data/big_data_table_base_convenience.rs b/src/data/big_data_table_base_convenience.rs index 54e9778..09ef66d 100644 --- a/src/data/big_data_table_base_convenience.rs +++ b/src/data/big_data_table_base_convenience.rs @@ -2,6 +2,7 @@ use std::collections::HashMap; use std::error::Error; use std::fmt::Debug; use std::str::FromStr; +use async_trait::async_trait; use google_bigquery2::api::{QueryParameter, QueryParameterType, QueryParameterValue, QueryRequest}; use google_bigquery2::hyper::{Body, Response}; @@ -10,9 +11,11 @@ use crate::client::BigqueryClient; use crate::data::BigDataTableBase; use crate::utils::BigDataValueType; +#[async_trait] pub trait BigDataTableBaseConvenience<'a, TABLE, TPK> : BigDataTableBase<'a, TABLE, TPK> - where TPK: BigDataValueType + FromStr + Debug + Clone { + where TPK: BigDataValueType + FromStr + Debug + Clone, + TABLE: Sync { fn get_pk_param(&self) -> google_bigquery2::api::QueryParameter; fn get_query_fields_str() -> String; fn get_query_fields_insert_str() -> String; @@ -42,13 +45,15 @@ pub trait BigDataTableBaseConvenience<'a, TABLE, TPK> query: &str, parameters: Vec, project_id: &str) - -> Result>; + -> Result> + where TABLE: 'async_trait; //endregion // async fn get_identifier_and_base_where(&self) -> Result<(String, String), Box>; async fn get_identifier(&self) -> Result>; - async fn get_identifier_from_client(client: &'a BigqueryClient) -> Result>; + async fn get_identifier_from_client(client: &'a BigqueryClient) -> Result> + where TABLE: 'async_trait; fn get_base_where() -> String; // async fn get_identifier_and_base_where_from_client(client: &'a BigqueryClient, pk_name: &str, table_name: &str) -> Result<(String, String), Box>; @@ -67,9 +72,10 @@ pub trait BigDataTableBaseConvenience<'a, TABLE, TPK> // Self: Sized; } +#[async_trait] impl<'a, TABLE, TPK> BigDataTableBaseConvenience<'a, TABLE, TPK> for TABLE where - TABLE: BigDataTableBase<'a, TABLE, TPK>, + TABLE: BigDataTableBase<'a, TABLE, TPK> + Sync, TPK: BigDataValueType + FromStr + Debug + Clone, ::Err: Debug, { @@ -221,7 +227,7 @@ impl<'a, TABLE, TPK> BigDataTableBaseConvenience<'a, TABLE, TPK> for TABLE Self::get_where_part(&pk_name, false) } - default fn get_query_param>(field_name: &str, field_value: &Option) -> google_bigquery2::api::QueryParameter + fn get_query_param>(field_name: &str, field_value: &Option) -> google_bigquery2::api::QueryParameter { let type_to_string: String = TField::to_bigquery_type(); let value: Option = Some(google_bigquery2::api::QueryParameterValue { diff --git a/src/data/mod.rs b/src/data/mod.rs index 22f4f04..c94d9d6 100644 --- a/src/data/mod.rs +++ b/src/data/mod.rs @@ -3,6 +3,7 @@ use std::error::Error; use std::fmt::{Debug, Display}; use std::str::FromStr; +use async_trait::async_trait; use google_bigquery2::api::{QueryParameter, TableSchema}; pub use big_data_table_base::BigDataTableBase; @@ -16,42 +17,52 @@ mod big_data_table_base_convenience; mod big_data_table_base; // pub trait BigDataTable<'a, TABLE, TPK: BigDataValueType + FromStr + Debug>: HasBigQueryClient<'a> + BigDataTableBaseConvenience<'a, TABLE, TPK> + BigDataTableBase<'a, TABLE, TPK> { +#[async_trait] pub trait BigDataTable<'a, TABLE, TPK> : HasBigQueryClient<'a> + BigDataTableHasPk + BigDataTableBaseConvenience<'a, TABLE, TPK> + BigDataTableBase<'a, TABLE, TPK> + Default - where TPK: BigDataValueType + FromStr + Debug + Clone { + where TPK: BigDataValueType + FromStr + Debug + Clone + Send, + TABLE: Sync + Send { async fn create_and_load_from_pk( client: &'a BigqueryClient, pk: TPK, ) -> Result> where - Self: Sized; - async fn load_from_pk(client: &'a BigqueryClient, pk: TPK) -> Result, Box> where Self: Sized; + Self: Sized, + TPK: 'async_trait; + async fn load_from_pk(client: &'a BigqueryClient, pk: TPK) -> Result, Box> where Self: Sized, + TPK: 'async_trait; async fn save_to_bigquery(&self) -> Result<(), Box>; async fn load_from_bigquery(&mut self) -> Result<(), Box>; - async fn load_by_field>(client: &'a BigqueryClient, field_name: &str, field_value: Option, max_amount: usize) - -> Result, Box>; + async fn load_by_field + Send>(client: &'a BigqueryClient, field_name: &str, field_value: Option, max_amount: usize) + -> Result, Box> + where TABLE: 'async_trait; async fn load_by_custom_query(client: &'a BigqueryClient, query: &str, parameters: Vec, max_amount: usize) - -> Result, Box>; + -> Result, Box> + where TABLE: 'async_trait; } +#[async_trait] impl<'a, TABLE, TPK> BigDataTable<'a, TABLE, TPK> for TABLE -where - TABLE: HasBigQueryClient<'a> + BigDataTableBaseConvenience<'a, TABLE, TPK> + Default + BigDataTableHasPk, - TPK: BigDataValueType + FromStr + Debug + Clone, - ::Err: Debug + where + TABLE: HasBigQueryClient<'a> + BigDataTableBaseConvenience<'a, TABLE, TPK> + Default + BigDataTableHasPk + Sync + Send, + TPK: BigDataValueType + FromStr + Debug + Clone + Send, + ::Err: Debug { - async fn create_and_load_from_pk(client: &'a BigqueryClient, pk: TPK) -> Result> where Self: Sized { + async fn create_and_load_from_pk(client: &'a BigqueryClient, pk: TPK) -> Result> where Self: Sized, + TPK: 'async_trait { let mut res = Self::create_with_pk(client, pk); res.load_from_bigquery().await?; Ok(res) } - async fn load_from_pk(client: &'a BigqueryClient, pk: TPK) -> Result, Box> where Self: Sized { + async fn load_from_pk(client: &'a BigqueryClient, pk: TPK) -> Result, Box> + where Self: Sized, + TPK: 'async_trait { let x = Self::load_by_field(client, &Self::get_pk_name(), Some(pk), 1).await .map(|mut v| v.pop())?; Ok(x) @@ -144,7 +155,7 @@ where async fn load_from_bigquery(&mut self) -> Result<(), Box> { let project_id = self.get_client().get_project_id(); - let table_identifier = self.get_identifier().await?; + let table_identifier = self.get_identifier().await?; let where_clause = Self::get_base_where(); let query = format!("select {} from {} where {} limit 1", Self::get_query_fields_str(), table_identifier, where_clause); @@ -166,14 +177,15 @@ where self.write_from_table_row(row, &index_to_name_mapping) } - async fn load_by_field>(client: &'a BigqueryClient, field_name: &str, field_value: Option, max_amount: usize) - -> Result, Box> { + async fn load_by_field + Send>(client: &'a BigqueryClient, field_name: &str, field_value: Option, max_amount: usize) + -> Result, Box> + { let field_name: String = field_name.into(); let field_name = Self::get_field_name(&field_name).expect(format!("Field '{}' not found!", field_name).as_str()); let where_clause = Self::get_where_part(&field_name, field_value.is_none()); // let where_clause = format!(" {} = @__{}", field_name, field_name); let table_identifier = Self::get_identifier_from_client(client).await?; - let query = format!("select {} from {} where {} limit {}", Self::get_query_fields_str(), table_identifier, where_clause, max_amount); + let query = format!("select {} from {} where {} limit {}", Self::get_query_fields_str(), table_identifier, where_clause, max_amount); let mut params = vec![]; if !(field_value.is_none()) { @@ -184,7 +196,6 @@ where async fn load_by_custom_query(client: &'a BigqueryClient, query: &str, parameters: Vec, max_amount: usize) -> Result, Box> { - let project_id = client.get_project_id(); let query_res: google_bigquery2::api::QueryResponse = Self::run_get_query_with_params_on_client(client, &query, parameters, project_id).await?; diff --git a/src/lib.rs b/src/lib.rs index 9463501..75d2147 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,3 @@ -#![feature(async_fn_in_trait)] -#![feature(specialization)] #![allow(unused)] #![allow(incomplete_features)]