1fn main() -> libpq::errors::Result {
8 let mut args = std::env::args();
9
10 if args.len() < 4 {
11 panic!(
12 "usage: {} database_name in_filename out_filename",
13 args.next().unwrap()
14 );
15 }
16
17 let database = args.nth(1).unwrap();
18 let in_filename = args.next().unwrap();
19 let out_filename = args.next().unwrap();
20
21 let conn = libpq::Connection::set_db(None, None, None, None, Some(&database))?;
25
26 let res = conn.exec("SELECT pg_catalog.set_config('search_path', '', false)");
28 if res.status() != libpq::Status::TuplesOk {
29 panic!("SET failed: {:?}", conn.error_message());
30 }
31
32 conn.exec("begin");
33 println!("importing file \"{in_filename}\" ...");
34 let lobj_oid = libpq::lo::import(&conn, &in_filename);
35
36 println!("\tas large object {lobj_oid}.");
37
38 println!("picking out bytes 1000-2000 of the large object");
39 pickout(&conn, lobj_oid, 1_000, 1_000)?;
40
41 println!("overwriting bytes 1000-2000 of the large object with X's");
42 overwrite(&conn, lobj_oid, 1_000, 1_000)?;
43
44 println!("exporting large object to file \"{out_filename}\" ...");
45 libpq::lo::export(&conn, &out_filename, lobj_oid)?;
46
47 conn.exec("end");
48
49 Ok(())
50}
51
52fn pickout(
53 conn: &libpq::Connection,
54 lobj_id: libpq::Oid,
55 start: i32,
56 len: usize,
57) -> libpq::errors::Result {
58 let lobj = libpq::lo::open(conn, lobj_id, libpq::lo::Inv::READ)?;
59
60 lobj.lseek(start, libpq::lo::Seek::Set)?;
61
62 let mut nread = 0;
63
64 while len - nread > 0 {
65 let mut buf = lobj.read(len - nread)?;
66 let nbytes = buf.len();
67 buf.insert(nbytes, '\0');
68 eprint!(">>> {buf}");
69 nread += nbytes;
70 if nbytes == 0 {
71 break; }
73 }
74 eprintln!();
75
76 Ok(())
77}
78
79fn overwrite(
80 conn: &libpq::Connection,
81 lobj_id: libpq::Oid,
82 start: i32,
83 len: usize,
84) -> libpq::errors::Result {
85 let lobj = libpq::lo::open(conn, lobj_id, libpq::lo::Inv::WRITE)?;
86
87 lobj.lseek(start, libpq::lo::Seek::Set)?;
88 let mut buf = "X".repeat(len);
89 buf.insert(len - 1, '\0');
90
91 let mut nwritten = 0;
92 while len - nwritten > 0 {
93 let nbytes = lobj.write(&buf[nwritten..len - nwritten])?;
94 nwritten += nbytes;
95 }
96 eprintln!();
97
98 Ok(())
99}