// use super::*;

// use mysql::*;
// use mysql::prelude::*;

// pub trait DbConnect{
//     fn save_nriso_to_win_dist_id<'a>(nriso_to_win_dist_id: Box<dyn Fn(u32) -> u32 + 'a>, n : u32, street_sentinel : i32) -> std::result::Result<(), Box<dyn std::error::Error>>;
//     fn save_nriso_to_ptl_dist_id<'a>(nriso_to_ptl_dist_id: Box<dyn Fn(u32) -> u32 + 'a>, n : u32, street_sentinel : i32) -> std::result::Result<(), Box<dyn std::error::Error>>;
//     fn query_win_dist_id_with_nriso(&self, nriso : u32, street_sentinel : i32) -> std::result::Result<u32, Box<dyn std::error::Error>>;

//     fn save_priso_to_ptl_trc_dist_id<'a>(priso_to_trc_dist_id: Box<dyn Fn(u32) -> u32 + 'a>, n: u32, street_sentinel : i32, recall_from_sentinel : i32) -> std::result::Result<(), Box<dyn std::error::Error>>;
//     fn save_priso_to_win_trc_dist_id<'a>(priso_to_trc_dist_id: Box<dyn Fn(u32) -> u32 + 'a>, n: u32, street_sentinel : i32, recall_from_sentinel : i32) -> std::result::Result<(), Box<dyn std::error::Error>>;
// }

// const MYSQL_URL: &str = "mysql://root:root@localhost:3306/poker";

// impl<T> DbConnect for Featurizer<T> 
//     where T : Singleton
// {
//     fn save_nriso_to_win_dist_id<'a>(nriso_to_win_dist_id: Box<dyn Fn(u32) -> u32 + 'a>, n : u32, street_sentinel : i32) -> std::result::Result<(), Box<dyn std::error::Error>>
//     {
//         let url = MYSQL_URL;
//         let pool = Pool::new(url)?;
//         let mut conn = pool.get_conn()?;
//         let table_name = format!("{}_{}_nriso_to_winning_distribution_id", T::GAME_NAME, street_sentinel);

//         #[cfg(feature = "test_print")]
//         println!("construct table : {}", table_name);
//         conn.query_drop(&format!("DROP TABLE IF EXISTS {}", table_name))?;
//         conn.query_drop(&format!("CREATE TABLE `{}` (
//             `id` int NOT NULL AUTO_INCREMENT COMMENT '自增id',
//             `nriso` INT UNSIGNED NOT NULL DEFAULT '{}' COMMENT '同构id',
//             `win_dist_id` INT UNSIGNED NOT NULL DEFAULT '{}' COMMENT '胜率分布id',
//             PRIMARY KEY (`id`),
//             UNIQUE KEY  (`nriso`)
//           ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COMMENT='{}'", table_name, u32::MAX, u32::MAX,T::GAME_NAME))?;

//         // conn.query_drop(format!("TRUNCATE TABLE {}", table_name))?; //删除数据的语句
        
//         conn.exec_batch(format!("INSERT INTO {} (nriso, win_dist_id)
//             VALUES (:nriso, :win_dist_id)", table_name),
//             (0..n).into_iter().map(|nriso| params!{
//                 "nriso" => nriso, // buiso
//                 "win_dist_id" => nriso_to_win_dist_id(nriso), // closure(nriso)
//             })
//         )?;

//         Ok(())
//     }

//     fn query_win_dist_id_with_nriso(&self, nriso : u32, street_sentinel : i32) -> std::result::Result<u32, Box<dyn std::error::Error>>{
//         let table_name = format!("{}_{}_nriso_to_winning_distribution_id", T::GAME_NAME, street_sentinel);
//         let query_sql = format!(
//             "select win_dist_id from {} where nriso={}", table_name, nriso
//         );

//         let url = MYSQL_URL;
//         let mut conn = self.pool.get_conn().map_err(|e| format!("line:{}, err:{}\n 出错时的查询语句:{}\n",1, e, query_sql.clone()))?;
//         let selected: Vec<u32>  = conn.query(query_sql.clone()).map_err(|e| format!("line:{}, err:{}\n 出错时的查询语句:{}\n",2, e, query_sql.clone()))?;
//         return Ok(selected[0]);
//         //let pool;// = Pool::new(url)?;//.map_err(|e| format!("line:{}, err:{}\n 出错时的查询语句:{}\n",0, e, query_sql.clone()))?;
//         //for i in 0..=2{
//             /*
//             if let Ok(pool) = Pool::new(url){
//                 let mut conn = pool.get_conn().map_err(|e| format!("line:{}, err:{}\n 出错时的查询语句:{}\n",1, e, query_sql.clone()))?;
    
//                 let selected: Vec<u32>  = conn.query(query_sql.clone()).map_err(|e| format!("line:{}, err:{}\n 出错时的查询语句:{}\n",2, e, query_sql.clone()))?;
//                 return Ok(selected[0]);
//             }else{
//                 #[cfg(feature = "test_print")]
//                 println!("err:{} {}", i, query_sql.clone());
//             } */
//         //}
        
//         //panic!("err");
//     }

//     fn save_nriso_to_ptl_dist_id<'a>(nriso_to_ptl_dist_id: Box<dyn Fn(u32) -> u32 + 'a>, n : u32, street_sentinel : i32) -> std::result::Result<(), Box<dyn std::error::Error>> 
//     {
//         let url = MYSQL_URL;
//         let pool = Pool::new(url)?;
//         let mut conn = pool.get_conn()?;
//         let table_name = format!("{}_{}_nriso_to_potential_distribution_id", T::GAME_NAME, street_sentinel);

//         #[cfg(feature = "test_print")]
//         println!("construct table : {}", table_name);
//         conn.query_drop(&format!("DROP TABLE IF EXISTS {}", table_name))?;
//         conn.query_drop(&format!("CREATE TABLE `{}` (
//             `id` int NOT NULL AUTO_INCREMENT COMMENT '自增id',
//             `nriso` INT UNSIGNED NOT NULL DEFAULT '{}' COMMENT '同构id',
//             `ptl_dist_id` INT UNSIGNED NOT NULL DEFAULT '{}' COMMENT '胜率分布id',
//             PRIMARY KEY (`id`),
//             UNIQUE KEY  (`nriso`)
//         ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COMMENT='{}'", table_name, u32::MAX, u32::MAX,T::GAME_NAME))?;

//         // conn.query_drop(format!("TRUNCATE TABLE {}", table_name))?; //删除数据的语句
        
//         conn.exec_batch(format!("INSERT INTO {} (nriso, ptl_dist_id)
//             VALUES (:nriso, :ptl_dist_id)", table_name),
//             (0..n).into_iter().map(|nriso| params!{
//                 "nriso" => nriso, // buiso
//                 "ptl_dist_id" => nriso_to_ptl_dist_id(nriso), // closure(nriso)
//             })
//         )?;

//         Ok(())
//     }

//     fn save_priso_to_ptl_trc_dist_id<'a>(priso_to_trc_dist_id: Box<dyn Fn(u32) -> u32 + 'a>, n: u32, street_sentinel : i32, recall_from_sentinel : i32) -> std::result::Result<(), Box<dyn std::error::Error>>
//     {
//         let url = MYSQL_URL;
//         let pool = Pool::new(url)?;
//         let mut conn = pool.get_conn()?;
//         let table_name = format!("{}_{}_priso_from_{}_potential_trace_distribution_id", T::GAME_NAME, street_sentinel, recall_from_sentinel);

//         #[cfg(feature = "test_print")]
//         println!("construct table : {}", table_name);
//         conn.query_drop(&format!("DROP TABLE IF EXISTS {}", table_name))?;
//         conn.query_drop(&format!("CREATE TABLE `{}` (
//             `id` int NOT NULL AUTO_INCREMENT COMMENT '自增id',
//             `priso` INT UNSIGNED NOT NULL DEFAULT '{}' COMMENT '同构id',
//             `trc_dist_id` INT UNSIGNED NOT NULL DEFAULT '{}' COMMENT '胜率分布id',
//             PRIMARY KEY (`id`),
//             UNIQUE KEY  (`priso`)
//         ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COMMENT='{}'", table_name, u32::MAX, u32::MAX,T::GAME_NAME))?;

//         // conn.query_drop(format!("TRUNCATE TABLE {}", table_name))?; //删除数据的语句
        
//         conn.exec_batch(format!("INSERT INTO {} (priso, trc_dist_id)
//             VALUES (:priso, :trc_dist_id)", table_name),
//             (0..n).into_iter().map(|nriso| params!{
//                 "priso" => nriso, // buiso
//                 "trc_dist_id" => priso_to_trc_dist_id(nriso), 
//             })
//         )?;
//         Ok(())
//     }

//     fn save_priso_to_win_trc_dist_id<'a>(priso_to_trc_dist_id: Box<dyn Fn(u32) -> u32 + 'a>, n: u32, street_sentinel : i32, recall_from_sentinel : i32) -> std::result::Result<(), Box<dyn std::error::Error>>
//     {
//         let url = MYSQL_URL;
//         let pool = Pool::new(url)?;
//         let mut conn = pool.get_conn()?;
//         let table_name = format!("{}_{}_priso_from_{}_winning_trace_distribution_id", T::GAME_NAME, street_sentinel, recall_from_sentinel);

//         #[cfg(feature = "test_print")]
//         println!("construct table : {}", table_name);
//         conn.query_drop(&format!("DROP TABLE IF EXISTS {}", table_name))?;
//         conn.query_drop(&format!("CREATE TABLE `{}` (
//             `id` int NOT NULL AUTO_INCREMENT COMMENT '自增id',
//             `priso` INT UNSIGNED NOT NULL DEFAULT '{}' COMMENT '同构id',
//             `trc_dist_id` INT UNSIGNED NOT NULL DEFAULT '{}' COMMENT '胜率分布id',
//             PRIMARY KEY (`id`),
//             UNIQUE KEY  (`priso`)
//         ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COMMENT='{}'", table_name, u32::MAX, u32::MAX,T::GAME_NAME))?;

//         // conn.query_drop(format!("TRUNCATE TABLE {}", table_name))?; //删除数据的语句
        
//         conn.exec_batch(format!("INSERT INTO {} (priso, trc_dist_id)
//             VALUES (:priso, :trc_dist_id)", table_name),
//             (0..n).into_iter().map(|nriso| params!{
//                 "priso" => nriso, // buiso
//                 "trc_dist_id" => priso_to_trc_dist_id(nriso), 
//             })
//         )?;
//         Ok(())
//     }
// }

// // struct SaveDbCallable<FS, FR, 'a, 'b>
// //     where FS: Fn(u32)->u32 + 'a,
// //           FR: Fn(Box<dyn FS>, u32) -> std::result::Result<(), Box<dyn std::error::Error>> + 'b
// // {
// //     callback: Option<Box<dyn FR>>
// // }

// // impl<FS, FR, 'a, 'b> Container<FS, FR, 'a, 'b> 
// //     where FS: Fn(u32)->u32 + 'a,
// //           FR: Fn(Box<dyn FS>, u32) -> std::result::Result<(), Box<dyn std::error::Error>> + 'b
// // {
// //     pub fn new() -> Container {
// //         Container {
// //             callback: None,
// //         }
// //     }

// //     pub fn set(&mut self, cb: impl FR) {
// //         self.callback = Some(Box::new(cb));
// //     }
// // }