File: prompt.ml

package info (click to toggle)
postgresql-ocaml 5.2.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 444 kB
  • sloc: ml: 2,783; ansic: 1,379; makefile: 28
file content (102 lines) | stat: -rw-r--r-- 2,848 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
(* A simple replacement for psql *)

open Printf
open! Postgresql

let _ =
  if Array.length Sys.argv <> 2 then (
    eprintf "\n Usage:  %s conninfo\n" Sys.argv.(0);
    exit 1)

let conninfo = Sys.argv.(1)

let print_conn_info conn =
  printf "db      = %s\n" conn#db;
  printf "user    = %s\n" conn#user;
  printf "pass    = %s\n" conn#pass;
  printf "host    = %s\n" conn#host;
  printf "port    = %s\n" conn#port;
  printf "tty     = %s\n" conn#tty;
  printf "option  = %s\n" conn#options;
  printf "pid     = %i\n" conn#backend_pid

let print_res conn res =
  match res#status with
  | Empty_query -> printf "Empty query\n"
  | Command_ok -> printf "Command ok [%s]\n" res#cmd_status
  | Tuples_ok ->
      printf "Tuples ok\n";
      printf "%i tuples with %i fields\n" res#ntuples res#nfields;
      print_endline (String.concat ";" res#get_fnames_lst);
      for tuple = 0 to res#ntuples - 1 do
        for field = 0 to res#nfields - 1 do
          printf "%s, " (res#getvalue tuple field)
        done;
        print_newline ()
      done
  | Copy_out ->
      printf "Copy out:\n";
      conn#copy_out print_endline
  | Copy_in ->
      printf "Copy in, not handled!\n";
      exit 1
  | Bad_response ->
      printf "Bad response: %s\n" res#error;
      conn#reset
  | Nonfatal_error -> printf "Non fatal error: %s\n" res#error
  | Fatal_error -> printf "Fatal error: %s\n" res#error
  | Copy_both ->
      printf "Copy in/out, not handled!\n";
      exit 1
  | Single_tuple ->
      printf "Single tuple, not handled!\n";
      exit 1

let rec dump_res conn =
  match conn#get_result with
  | Some res ->
      print_res conn res;
      flush stdout;
      dump_res conn
  | None -> ()

let rec dump_notification conn =
  match conn#notifies with
  | Some { Notification.name; pid; extra } ->
      printf "Notication from backend %i: [%s] [%s]\n" pid name extra;
      flush stdout;
      dump_notification conn
  | None -> ()

let listener conn =
  try
    while true do
      let socket : Unix.file_descr = Obj.magic conn#socket in
      let _ = Unix.select [ socket ] [] [] 1. in
      conn#consume_input;
      dump_notification conn
    done
  with
  | Error e -> prerr_endline (string_of_error e)
  | e -> prerr_endline (Printexc.to_string e)

let main () =
  if Obj.is_block (Obj.repr Unix.stdin) then failwith "cannot run on Windows";
  let conn = new connection ~conninfo () in
  print_conn_info conn;
  flush stdout;
  conn#set_notice_processor (fun s -> eprintf "postgresql error [%s]\n" s);
  let _ = Thread.create listener conn in
  try
    while true do
      print_string "> ";
      let s = read_line () in
      conn#send_query s;
      dump_res conn
    done
  with End_of_file -> conn#finish

let _ =
  try main () with
  | Error e -> prerr_endline (string_of_error e)
  | e -> prerr_endline (Printexc.to_string e)