fticopy
上传用户:blenddy
上传日期:2007-01-07
资源大小:6495k
文件大小:4k
源码类别:

数据库系统

开发平台:

Unix_Linux

  1. #!/usr/bin/perl
  2. #
  3. # This script substracts all substrings out of a specific column in a table
  4. # and generates output that can be loaded into a new table with the
  5. # psql 'copy' command. The new table should have the following structure:
  6. #
  7. # create table tab (
  8. # string text,
  9. # id oid
  10. # );
  11. #
  12. # Note that you cannot use 'copy' (the SQL-command) directly, because
  13. # there's no '.' included at the end of the output.
  14. #
  15. # The output can be fed through the UNIX commands 'uniq' and 'sort'
  16. # to generate the smallest and sorted output to populate the fti-table.
  17. #
  18. # Example:
  19. #
  20. #  fti.pl -u -d mydb -t mytable -c mycolumn -f myfile
  21. # sort -o myoutfile myfile
  22. # uniq myoutfile sorted-file
  23. #
  24. #  psql -u mydb
  25. #
  26. # copy my_fti_table from myfile
  27. #
  28. #   create index fti_idx on my_fti_table (string,id);
  29. #
  30. # create function fti() returns opaque as
  31. # '/path/to/fti/file/fti.so'
  32. # language 'C';
  33. #
  34. # create trigger my_fti_trigger after update or insert or delete
  35. # on mytable
  36. # for each row execute procedure fti(my_fti_table, mycolumn);
  37. #
  38. # Make sure you have an index on mytable(oid) to be able to do somewhat
  39. # efficient substring searches.
  40. #use lib '/usr/local/pgsql/lib/perl5/';
  41. use lib '/mnt/web/guide/postgres/lib/perl5/site_perl';
  42. use Pg;
  43. use Getopt::Std;
  44. $PGRES_EMPTY_QUERY    = 0 ;
  45. $PGRES_COMMAND_OK     = 1 ;
  46. $PGRES_TUPLES_OK      = 2 ;
  47. $PGRES_COPY_OUT       = 3 ;
  48. $PGRES_COPY_IN        = 4 ;
  49. $PGRES_BAD_RESPONSE   = 5 ;
  50. $PGRES_NONFATAL_ERROR = 6 ;
  51. $PGRES_FATAL_ERROR    = 7 ;
  52. $[ = 0; # make sure string offsets start at 0
  53. sub break_up {
  54. my $string = pop @_;
  55. @strings = split(/W+/, $string);
  56. @subs = ();
  57. foreach $s (@strings) {
  58. $len = length($s);
  59. next if ($len < 4);
  60. $lpos = $len-1;
  61. while ($lpos >= 3) {
  62. $fpos = $lpos - 3;
  63. while ($fpos >= 0) {
  64. $sub = substr($s, $fpos, $lpos - $fpos + 1);
  65. push(@subs, $sub);
  66. $fpos = $fpos - 1;
  67. }
  68. $lpos = $lpos - 1;
  69. }
  70. }
  71. return @subs;
  72. }
  73. sub connect_db {
  74. my $dbname = shift @_;
  75. my $user   = shift @_;
  76. my $passwd = shift @_;
  77. if (!defined($dbname) || $dbname eq "") {
  78. return 1;
  79. }
  80. $connect_string = "dbname=$dbname";
  81. if ($user ne "") {
  82. if ($passwd eq "") {
  83. return 0;
  84. }
  85. $connect_string = "$connect_string user=$user password=$passwd ".
  86.   "authtype=password";
  87. }
  88. $PG_CONN = PQconnectdb($connect_string);
  89. if (PQstatus($PG_CONN)) {
  90. print STDERR "Couldn't make connection with database!n";
  91. print STDERR PQerrorMessage($PG_CONN), "n";
  92. return 0;
  93. }
  94. return 1;
  95. }
  96. sub quit_prog {
  97. close(OUT);
  98. unlink $opt_f;
  99. if (defined($PG_CONN)) {
  100. PQfinish($PG_CONN);
  101. }
  102. exit 1;
  103. }
  104. sub get_username {
  105. print "Username: ";
  106. chop($n = <STDIN>);
  107.     return $n;;
  108. }
  109. sub get_password {
  110. print "Password: ";
  111. system("stty -echo < /dev/tty");
  112. chop($pwd = <STDIN>);
  113. print "n";
  114. system("stty echo < /dev/tty");
  115. return $pwd;
  116. }
  117. sub main {
  118. getopts('d:t:c:f:u');
  119. if (!$opt_d || !$opt_t || !$opt_c || !$opt_f) {
  120. print STDERR "usage: $0 [-u] -d database -t table -c column ".
  121.   "-f output-filen";
  122. return 1;
  123. }
  124. if (defined($opt_u)) {
  125. $uname = get_username();
  126. $pwd   = get_password();
  127. } else {
  128. $uname = "";
  129. $pwd   = "";
  130. }
  131. $SIG{'INT'} = 'quit_prog';
  132. if (!connect_db($opt_d, $uname, $pwd)) {
  133. print STDERR "Connecting to database failed!n";
  134. return 1;
  135. }
  136. if (!open(OUT, ">$opt_f")) {
  137. print STDERR "Couldnt' open file '$opt_f' for output!n";
  138. return 1;
  139. }
  140. PQexec($PG_CONN, "begin");
  141. $query = "declare C cursor for select $opt_c, oid from $opt_t";
  142. $res = PQexec($PG_CONN, $query);
  143. if (!$res || (PQresultStatus($res) != $PGRES_COMMAND_OK)) {
  144. print STDERR "Error declaring cursor!n";
  145. print STDERR PQerrorMessage($PG_CONN), "n";
  146. PQfinish($PG_CONN);
  147. return 1;
  148. }
  149. PQclear($res);
  150. $query = "fetch in C";
  151. while (($res = PQexec($PG_CONN, $query)) &&
  152.    (PQresultStatus($res) == $PGRES_TUPLES_OK) &&
  153.    (PQntuples($res) == 1)) {
  154. $col = PQgetvalue($res, 0, 0);
  155. $oid = PQgetvalue($res, 0, 1);
  156. @subs = break_up($col);
  157. foreach $i (@subs) {
  158. print OUT "$it$oidn";
  159. }
  160. }
  161. if (!$res || (PQresultStatus($res) != PGRES_TUPLES_OK)) {
  162. print STDERR "Error retrieving data from backend!n";
  163. print STDERR PQerrorMEssage($PG_CONN), "n";
  164. PQfinish($PG_CONN);
  165. return 1;
  166. }
  167. PQclear($res);
  168. PQfinish($PG_CONN);
  169. return 0;
  170. }
  171. exit main();