1use crate::{
6 create_database, execute, execute_sql, get_postgres_client, install_postgres,
7 is_postgres_running, query_one, reset, PostgresInstallerConfig,
8};
9use postgres::types::ToSql;
10use rhai::{Array, Engine, EvalAltResult, Map};
11use sal_virt::nerdctl::Container;
12
13pub fn register_postgresclient_module(engine: &mut Engine) -> Result<(), Box<EvalAltResult>> {
23 engine.register_fn("pg_connect", pg_connect);
25 engine.register_fn("pg_ping", pg_ping);
26 engine.register_fn("pg_reset", pg_reset);
27
28 engine.register_fn("pg_execute", pg_execute);
30 engine.register_fn("pg_query", pg_query);
31 engine.register_fn("pg_query_one", pg_query_one);
32
33 engine.register_fn("pg_install", pg_install);
35 engine.register_fn("pg_create_database", pg_create_database);
36 engine.register_fn("pg_execute_sql", pg_execute_sql);
37 engine.register_fn("pg_is_running", pg_is_running);
38
39 Ok(())
42}
43
44pub fn pg_connect() -> Result<bool, Box<EvalAltResult>> {
50 match get_postgres_client() {
51 Ok(_) => Ok(true),
52 Err(e) => Err(Box::new(EvalAltResult::ErrorRuntime(
53 format!("PostgreSQL error: {}", e).into(),
54 rhai::Position::NONE,
55 ))),
56 }
57}
58
59pub fn pg_ping() -> Result<bool, Box<EvalAltResult>> {
65 match get_postgres_client() {
66 Ok(client) => match client.ping() {
67 Ok(result) => Ok(result),
68 Err(e) => Err(Box::new(EvalAltResult::ErrorRuntime(
69 format!("PostgreSQL error: {}", e).into(),
70 rhai::Position::NONE,
71 ))),
72 },
73 Err(e) => Err(Box::new(EvalAltResult::ErrorRuntime(
74 format!("PostgreSQL error: {}", e).into(),
75 rhai::Position::NONE,
76 ))),
77 }
78}
79
80pub fn pg_reset() -> Result<bool, Box<EvalAltResult>> {
86 match reset() {
87 Ok(_) => Ok(true),
88 Err(e) => Err(Box::new(EvalAltResult::ErrorRuntime(
89 format!("PostgreSQL error: {}", e).into(),
90 rhai::Position::NONE,
91 ))),
92 }
93}
94
95pub fn pg_execute(query: &str) -> Result<i64, Box<EvalAltResult>> {
105 let params: &[&(dyn ToSql + Sync)] = &[];
108
109 match execute(query, params) {
110 Ok(rows) => Ok(rows as i64),
111 Err(e) => Err(Box::new(EvalAltResult::ErrorRuntime(
112 format!("PostgreSQL error: {}", e).into(),
113 rhai::Position::NONE,
114 ))),
115 }
116}
117
118pub fn pg_query(query_str: &str) -> Result<Array, Box<EvalAltResult>> {
128 let params: &[&(dyn ToSql + Sync)] = &[];
131
132 match crate::query(query_str, params) {
133 Ok(rows) => {
134 let mut result = Array::new();
135 for row in rows {
136 let mut map = Map::new();
137 for column in row.columns() {
138 let name = column.name();
139 let value: Option<String> = row.get(name);
141 if let Some(val) = value {
142 map.insert(name.into(), val.into());
143 } else {
144 map.insert(name.into(), rhai::Dynamic::UNIT);
145 }
146 }
147 result.push(map.into());
148 }
149 Ok(result)
150 }
151 Err(e) => Err(Box::new(EvalAltResult::ErrorRuntime(
152 format!("PostgreSQL error: {}", e).into(),
153 rhai::Position::NONE,
154 ))),
155 }
156}
157
158pub fn pg_query_one(query: &str) -> Result<Map, Box<EvalAltResult>> {
168 let params: &[&(dyn ToSql + Sync)] = &[];
171
172 match query_one(query, params) {
173 Ok(row) => {
174 let mut map = Map::new();
175 for column in row.columns() {
176 let name = column.name();
177 let value: Option<String> = row.get(name);
179 if let Some(val) = value {
180 map.insert(name.into(), val.into());
181 } else {
182 map.insert(name.into(), rhai::Dynamic::UNIT);
183 }
184 }
185 Ok(map)
186 }
187 Err(e) => Err(Box::new(EvalAltResult::ErrorRuntime(
188 format!("PostgreSQL error: {}", e).into(),
189 rhai::Position::NONE,
190 ))),
191 }
192}
193
194pub fn pg_install(
208 container_name: &str,
209 version: &str,
210 port: i64,
211 username: &str,
212 password: &str,
213) -> Result<bool, Box<EvalAltResult>> {
214 let config = PostgresInstallerConfig::new()
216 .container_name(container_name)
217 .version(version)
218 .port(port as u16)
219 .username(username)
220 .password(password);
221
222 match install_postgres(config) {
224 Ok(_) => Ok(true),
225 Err(e) => Err(Box::new(EvalAltResult::ErrorRuntime(
226 format!("PostgreSQL installer error: {}", e).into(),
227 rhai::Position::NONE,
228 ))),
229 }
230}
231
232pub fn pg_create_database(container_name: &str, db_name: &str) -> Result<bool, Box<EvalAltResult>> {
243 let container = Container {
245 name: container_name.to_string(),
246 container_id: Some(container_name.to_string()), image: None,
248 config: std::collections::HashMap::new(),
249 ports: Vec::new(),
250 volumes: Vec::new(),
251 env_vars: std::collections::HashMap::new(),
252 network: None,
253 network_aliases: Vec::new(),
254 cpu_limit: None,
255 memory_limit: None,
256 memory_swap_limit: None,
257 cpu_shares: None,
258 restart_policy: None,
259 health_check: None,
260 detach: false,
261 snapshotter: None,
262 };
263
264 match create_database(&container, db_name) {
266 Ok(_) => Ok(true),
267 Err(e) => Err(Box::new(EvalAltResult::ErrorRuntime(
268 format!("PostgreSQL error: {}", e).into(),
269 rhai::Position::NONE,
270 ))),
271 }
272}
273
274pub fn pg_execute_sql(
286 container_name: &str,
287 db_name: &str,
288 sql: &str,
289) -> Result<String, Box<EvalAltResult>> {
290 let container = Container {
292 name: container_name.to_string(),
293 container_id: Some(container_name.to_string()), image: None,
295 config: std::collections::HashMap::new(),
296 ports: Vec::new(),
297 volumes: Vec::new(),
298 env_vars: std::collections::HashMap::new(),
299 network: None,
300 network_aliases: Vec::new(),
301 cpu_limit: None,
302 memory_limit: None,
303 memory_swap_limit: None,
304 cpu_shares: None,
305 restart_policy: None,
306 health_check: None,
307 detach: false,
308 snapshotter: None,
309 };
310
311 match execute_sql(&container, db_name, sql) {
313 Ok(output) => Ok(output),
314 Err(e) => Err(Box::new(EvalAltResult::ErrorRuntime(
315 format!("PostgreSQL error: {}", e).into(),
316 rhai::Position::NONE,
317 ))),
318 }
319}
320
321pub fn pg_is_running(container_name: &str) -> Result<bool, Box<EvalAltResult>> {
331 let container = Container {
333 name: container_name.to_string(),
334 container_id: Some(container_name.to_string()), image: None,
336 config: std::collections::HashMap::new(),
337 ports: Vec::new(),
338 volumes: Vec::new(),
339 env_vars: std::collections::HashMap::new(),
340 network: None,
341 network_aliases: Vec::new(),
342 cpu_limit: None,
343 memory_limit: None,
344 memory_swap_limit: None,
345 cpu_shares: None,
346 restart_policy: None,
347 health_check: None,
348 detach: false,
349 snapshotter: None,
350 };
351
352 match is_postgres_running(&container) {
354 Ok(running) => Ok(running),
355 Err(e) => Err(Box::new(EvalAltResult::ErrorRuntime(
356 format!("PostgreSQL error: {}", e).into(),
357 rhai::Position::NONE,
358 ))),
359 }
360}