-
Notifications
You must be signed in to change notification settings - Fork 117
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: 完成支持把nacos mysql数据(包含配置、命名空间、用户数据)导出为中间数据文件功能开发; #138
- Loading branch information
Showing
13 changed files
with
864 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,167 @@ | ||
use serde_json::Value; | ||
use sqlx::database::HasArguments; | ||
use sqlx::mysql::MySqlRow; | ||
use sqlx::query::Query; | ||
use sqlx::{Executor, MySql, MySqlConnection, Transaction}; | ||
|
||
pub fn build_mysql_query<'a>( | ||
sql: &'a str, | ||
args: &'a [serde_json::Value], | ||
) -> Query<'a, MySql, <MySql as HasArguments<'a>>::Arguments> { | ||
let mut q = sqlx::query(sql); | ||
for arg in args { | ||
match arg { | ||
Value::Number(v) => { | ||
if v.is_f64() { | ||
q = q.bind(v.as_f64().unwrap()) | ||
} else { | ||
q = q.bind(v.as_i64().unwrap()) | ||
} | ||
} | ||
Value::Bool(v) => q = q.bind(Some(v.to_owned())), | ||
Value::Null => q = q.bind(Option::<String>::None), | ||
Value::String(v) => { | ||
q = q.bind(Some(v.to_owned())); | ||
} | ||
_ => { | ||
q = q.bind(Some(arg.to_string())); | ||
} | ||
} | ||
} | ||
q | ||
} | ||
|
||
pub enum MySqlExecutor<'c> { | ||
Pool(&'c mut sqlx::Pool<MySql>), | ||
Conn(&'c mut MySqlConnection), | ||
Transaction(&'c mut Transaction<'c, MySql>), | ||
} | ||
|
||
#[derive(Debug, Clone)] | ||
pub struct ExecuteResult { | ||
pub rows_affected: u64, | ||
pub last_insert_id: u64, | ||
} | ||
|
||
impl ExecuteResult { | ||
pub fn new(rows_affected: u64, last_insert_id: u64) -> ExecuteResult { | ||
Self { | ||
rows_affected, | ||
last_insert_id, | ||
} | ||
} | ||
} | ||
|
||
impl<'c> MySqlExecutor<'c> { | ||
pub fn new_by_pool(pool: &'c mut sqlx::Pool<MySql>) -> Self { | ||
Self::Pool(pool) | ||
} | ||
pub fn new_by_conn(conn: &'c mut MySqlConnection) -> Self { | ||
Self::Conn(conn) | ||
} | ||
pub fn new_by_transaction(tx: &'c mut Transaction<'c, MySql>) -> Self { | ||
Self::Transaction(tx) | ||
} | ||
|
||
pub async fn fetch<T>( | ||
&mut self, | ||
sql: &str, | ||
args: &[serde_json::Value], | ||
) -> anyhow::Result<Vec<T>> | ||
where | ||
T: for<'r> sqlx::FromRow<'r, MySqlRow> + Send + Unpin, | ||
{ | ||
let q = build_mysql_query(sql, args); | ||
match self { | ||
MySqlExecutor::Pool(executor) => { | ||
let res = executor.fetch_all(q).await?; | ||
let rlist: Vec<T> = res.into_iter().map(|e| T::from_row(&e).unwrap()).collect(); | ||
Ok(rlist) | ||
} | ||
MySqlExecutor::Conn(executor) => { | ||
let res = executor.fetch_all(q).await?; | ||
let rlist: Vec<T> = res.into_iter().map(|e| T::from_row(&e).unwrap()).collect(); | ||
Ok(rlist) | ||
} | ||
MySqlExecutor::Transaction(executor) => { | ||
let res = executor.fetch_all(q).await?; | ||
let rlist: Vec<T> = res.into_iter().map(|e| T::from_row(&e).unwrap()).collect(); | ||
Ok(rlist) | ||
} | ||
} | ||
} | ||
|
||
pub async fn fetch_one<T>(&mut self, sql: &str, args: &[serde_json::Value]) -> anyhow::Result<T> | ||
where | ||
T: for<'r> sqlx::FromRow<'r, MySqlRow> + Send + Unpin, | ||
{ | ||
let q = build_mysql_query(sql, args); | ||
match self { | ||
MySqlExecutor::Pool(executor) => { | ||
let res = executor.fetch_one(q).await?; | ||
Ok(T::from_row(&res)?) | ||
} | ||
MySqlExecutor::Conn(executor) => { | ||
let res = executor.fetch_one(q).await?; | ||
Ok(T::from_row(&res)?) | ||
} | ||
MySqlExecutor::Transaction(executor) => { | ||
let res = executor.fetch_one(q).await?; | ||
Ok(T::from_row(&res)?) | ||
} | ||
} | ||
} | ||
|
||
pub async fn fetch_row( | ||
&mut self, | ||
sql: &str, | ||
args: &[serde_json::Value], | ||
) -> anyhow::Result<MySqlRow> { | ||
let q = build_mysql_query(sql, args); | ||
match self { | ||
MySqlExecutor::Pool(executor) => { | ||
let res = executor.fetch_one(q).await?; | ||
Ok(res) | ||
} | ||
MySqlExecutor::Conn(executor) => { | ||
let res = executor.fetch_one(q).await?; | ||
Ok(res) | ||
} | ||
MySqlExecutor::Transaction(executor) => { | ||
let res = executor.fetch_one(q).await?; | ||
Ok(res) | ||
} | ||
} | ||
} | ||
|
||
pub async fn execute( | ||
&mut self, | ||
sql: &str, | ||
args: &[serde_json::Value], | ||
) -> anyhow::Result<ExecuteResult> { | ||
let q = build_mysql_query(sql, args); | ||
match self { | ||
MySqlExecutor::Pool(executor) => { | ||
let res = executor.execute(q).await?; | ||
Ok(ExecuteResult::new( | ||
res.rows_affected(), | ||
res.last_insert_id(), | ||
)) | ||
} | ||
MySqlExecutor::Conn(executor) => { | ||
let res = executor.execute(q).await?; | ||
Ok(ExecuteResult::new( | ||
res.rows_affected(), | ||
res.last_insert_id(), | ||
)) | ||
} | ||
MySqlExecutor::Transaction(executor) => { | ||
let res = executor.execute(q).await?; | ||
Ok(ExecuteResult::new( | ||
res.rows_affected(), | ||
res.last_insert_id(), | ||
)) | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
use crate::common::sqlx_utils::MySqlExecutor; | ||
use rsql_builder::B; | ||
use serde::{Deserialize, Serialize}; | ||
use sqlx::Row; | ||
|
||
#[derive(Debug, Default, Serialize, Deserialize, sqlx::FromRow)] | ||
pub struct ConfigInfoDO { | ||
pub id: Option<i64>, | ||
pub data_id: Option<String>, | ||
pub group_id: Option<String>, | ||
pub content: Option<String>, | ||
pub md5: Option<String>, | ||
pub gmt_modified_timestamp: Option<i64>, | ||
pub src_user: Option<String>, | ||
pub src_ip: Option<String>, | ||
pub app_name: Option<String>, | ||
pub tenant_id: Option<String>, | ||
pub c_desc: Option<String>, | ||
pub c_use: Option<String>, | ||
pub effect: Option<String>, | ||
pub r#type: Option<String>, | ||
pub c_schema: Option<String>, | ||
pub encrypted_data_key: Option<String>, | ||
} | ||
|
||
#[derive(Debug, Default)] | ||
pub struct ConfigInfoParam { | ||
pub id: Option<i64>, | ||
pub limit: Option<i64>, | ||
pub offset: Option<i64>, | ||
} | ||
pub struct ConfigInfoSql {} | ||
|
||
impl ConfigInfoSql { | ||
fn conditions(&self, param: &ConfigInfoParam) -> B { | ||
let mut whr = B::new_where(); | ||
if let Some(id) = ¶m.id { | ||
whr.eq("id", id); | ||
} | ||
whr | ||
} | ||
|
||
pub fn query_prepare(&self, param: &ConfigInfoParam) -> (String, Vec<serde_json::Value>) { | ||
B::prepare( | ||
B::new_sql("select id, data_id, group_id, content, md5, UNIX_TIMESTAMP(gmt_modified) \ | ||
as gmt_modified_timestamp, src_user, src_ip, app_name, tenant_id, c_desc, c_use, effect, \ | ||
type, c_schema, encrypted_data_key from config_info") | ||
.push_build(&mut self.conditions(param)) | ||
.push_fn(||{ | ||
let mut b= B::new(); | ||
if let Some(limit) = ¶m.limit{ | ||
b.limit(limit); | ||
} | ||
if let Some(offset ) = ¶m.offset{ | ||
b.offset(offset); | ||
} | ||
b | ||
}) | ||
) | ||
} | ||
|
||
pub fn query_count_prepare(&self, param: &ConfigInfoParam) -> (String, Vec<serde_json::Value>) { | ||
B::prepare( | ||
B::new_sql("select count(1) from config_info").push_build(&mut self.conditions(param)), | ||
) | ||
} | ||
} | ||
|
||
pub struct ConfigInfoDao<'a> { | ||
executor: MySqlExecutor<'a>, | ||
inner: ConfigInfoSql, | ||
} | ||
|
||
impl<'a> ConfigInfoDao<'a> { | ||
pub fn new(executor: MySqlExecutor<'a>) -> Self { | ||
Self { | ||
executor, | ||
inner: ConfigInfoSql {}, | ||
} | ||
} | ||
|
||
pub async fn fetch( | ||
&mut self, | ||
sql: &str, | ||
args: &[serde_json::Value], | ||
) -> anyhow::Result<Vec<ConfigInfoDO>> { | ||
self.executor.fetch(sql, args).await | ||
} | ||
|
||
pub async fn fetch_count( | ||
&mut self, | ||
sql: &str, | ||
args: &[serde_json::Value], | ||
) -> anyhow::Result<i64> { | ||
let v = self.executor.fetch_row(sql, args).await?; | ||
v.try_get(0).map_err(anyhow::Error::msg) | ||
} | ||
|
||
pub async fn query(&mut self, param: &ConfigInfoParam) -> anyhow::Result<Vec<ConfigInfoDO>> { | ||
let (sql, args) = self.inner.query_prepare(param); | ||
self.fetch(&sql, &args).await | ||
} | ||
|
||
pub async fn query_count(&mut self, param: &ConfigInfoParam) -> anyhow::Result<i64> { | ||
let (sql, args) = self.inner.query_count_prepare(param); | ||
self.fetch_count(&sql, &args).await | ||
} | ||
} |
Oops, something went wrong.