Added the postgres reader. Closes patch #6388
authorJohn Darrington <john@darrington.wattle.id.au>
Mon, 4 Feb 2008 01:24:00 +0000 (01:24 +0000)
committerJohn Darrington <john@darrington.wattle.id.au>
Mon, 4 Feb 2008 01:24:00 +0000 (01:24 +0000)
configure.ac
doc/ChangeLog
doc/data-io.texi
doc/files.texi
src/data/ChangeLog
src/data/automake.mk
src/language/data-io/ChangeLog
src/language/data-io/get-data.c
src/ui/gui/automake.mk
src/ui/terminal/automake.mk
tests/automake.mk

index 5b8e1a933c99c0dec9e00149df042cd0e9a36ea8..cbf3d557f792391689927d69d74928e07cfb06b1 100644 (file)
@@ -47,6 +47,20 @@ fi
 AM_CONDITIONAL(WITHGUI, test x"$with_gui" != x"no")
 
 
 AM_CONDITIONAL(WITHGUI, test x"$with_gui" != x"no")
 
 
+dnl Checks needed for psql reader
+AC_CHECK_PROG(psql_support, pg_config, yes, no)
+if test x"$psql_support" = x"yes" ; then 
+   AC_DEFINE([PSQL_SUPPORT], 1,
+   [Define to 1 if building in support for reading from postgres databases.])
+   PG_CFLAGS=-I`pg_config --includedir` 
+   AC_SUBST(PG_CFLAGS)
+   PG_LDFLAGS=-L`pg_config --libdir`
+   AC_SUBST(PG_LDFLAGS)
+   PG_LIBS=-lpq
+   AC_SUBST(PG_LIBS)
+fi
+AM_CONDITIONAL(PSQL_SUPPORT, test x"$psql_support" = x"yes")
+
 dnl Checks needed for gnumeric reader
 gnm_support=yes;
 PKG_CHECK_MODULES(LIBXML2, libxml-2.0,,
 dnl Checks needed for gnumeric reader
 gnm_support=yes;
 PKG_CHECK_MODULES(LIBXML2, libxml-2.0,,
index c1fa40eb6c587b759847e7ef36a59b5dbf42a6b1..021e234345832587d5b76ce3bdbe4aa0453d0aae 100644 (file)
@@ -1,3 +1,9 @@
+2008-02-04 John Darrington <john@darrington.wattle.id.au>
+
+       * files.texi data-io.texi: Document the GET DATA TYPE=PSQL
+       option.  Thanks to Ben Pfaff for reviewing this text.
+
+
 2007-11-10  Ben Pfaff  <blp@gnu.org>
 
        * not-implemented.texi: Fix @include command so that it works
 2007-11-10  Ben Pfaff  <blp@gnu.org>
 
        * not-implemented.texi: Fix @include command so that it works
index 8ca251085df691f1cd7bef535e0c6f615f4f28b6..b6a3a6d2a4a5754f7962ca8ceb21bbd45cbc7a0f 100644 (file)
@@ -14,6 +14,8 @@ their sex, age, etc.@: and their responses are all data and the data
 pertaining to single respondent is a case.
 This chapter examines
 the PSPP commands for defining variables and reading and writing data.
 pertaining to single respondent is a case.
 This chapter examines
 the PSPP commands for defining variables and reading and writing data.
+There are alternative commands to  read data from predefined sources
+such as system files or databases (@xref{GET, GET DATA}.)
 
 @quotation Note
 These commands tell PSPP how to read data, but the data will not
 
 @quotation Note
 These commands tell PSPP how to read data, but the data will not
index a00d113d1fbc8d9c7e81cf15860f5fc88c6bb9fe..df01567eb956efd64df16ca7feff2e4fba3e93e9 100644 (file)
@@ -163,8 +163,7 @@ extension.
 
 @display
 GET DATA
 
 @display
 GET DATA
-        /TYPE=@{GNM,TXT@}
-        /FILE=@{'file-name',file_handle@}
+        /TYPE=@{GNM,PSQL,TXT@}
         @dots{}additional subcommands depending on TYPE@dots{}
 @end display
 
         @dots{}additional subcommands depending on TYPE@dots{}
 @end display
 
@@ -181,19 +180,19 @@ PSPP currently supports the following file types:
 @item GNM
 Spreadsheet files created by Gnumeric (@url{http://gnumeric.org}).
 
 @item GNM
 Spreadsheet files created by Gnumeric (@url{http://gnumeric.org}).
 
+@item PSQL
+Relations from PostgreSQL databases (@url{http://postgresql.org}).
+
 @item TXT
 Textual data files in columnar and delimited formats.
 @end table
 
 @item TXT
 Textual data files in columnar and delimited formats.
 @end table
 
-The FILE subcommand is mandatory for all implemented file types.
-Specify the file to be read as a string file name or (for textual data
-only) a file handle (@pxref{File Handles}).
-
 Each supported file type has additional subcommands, explained in
 separate sections below.
 
 @menu
 * GET DATA /TYPE=GNM::
 Each supported file type has additional subcommands, explained in
 separate sections below.
 
 @menu
 * GET DATA /TYPE=GNM::
+* GET DATA /TYPE=PSQL::
 * GET DATA /TYPE=TXT::
 @end menu
 
 * GET DATA /TYPE=TXT::
 @end menu
 
@@ -222,6 +221,10 @@ If this cell is of string (text) format, then the width of the variable is
 determined from the length of the string it contains, unless the 
 ASSUMEDVARWIDTH subcommand is given.
 
 determined from the length of the string it contains, unless the 
 ASSUMEDVARWIDTH subcommand is given.
 
+
+The FILE subcommand is mandatory. Specify the name of the file
+to be read.
+
 The SHEET subcommand specifies the sheet within the spreadsheet file to read.
 There are two forms of the SHEET subcommand.
 In the first form,
 The SHEET subcommand specifies the sheet within the spreadsheet file to read.
 There are two forms of the SHEET subcommand.
 In the first form,
@@ -253,6 +256,61 @@ variables read  from the file.
 If omitted, the default value is determined from the length of the 
 string in the first spreadsheet cell for each variable.
 
 If omitted, the default value is determined from the length of the 
 string in the first spreadsheet cell for each variable.
 
+
+@node GET DATA /TYPE=PSQL
+@subsection Postgres Database Queries
+
+@display
+GET DATA /TYPE=PSQL
+         /CONNECT=@{connection info@}
+         /SQL=@{query@}
+         [/ASSUMEDVARWIDTH=n]
+         [/UNENCRYPTED].
+@end display
+
+@cindex postgres
+@cindex databases
+
+The PSQL type is used to import data from a postgres database server.
+The server may be located locally or remotely.
+Variables are automatically created based on the table column names 
+or the names specified in the SQL query.
+Postgres data types of high precision, will loose precision when 
+imported into PSPP.
+Not all the postgres data types are able to be represented in PSPP.
+If a datum cannot be represented a warning will be issued and that 
+datum will be set to SYSMIS.
+
+The CONNECT subcommand is mandatory.
+It is a string specifying the parameters of the database server from
+which the data should be fetched.
+The format of the string is given in the postgres manual
+@url{http://www.postgresql.org/docs/8.0/static/libpq.html#LIBPQ-CONNECT}.
+
+The SQL subcommand is mandatory.
+It must be a valid SQL string to retrieve data from the database.
+
+The ASSUMEDVARWIDTH subcommand specifies the maximum width of string
+variables read  from the database.
+If omitted, the default value is determined from the length of the 
+string in the first value read for each variable.
+
+The UNENCRYPTED subcommand allows data to be retrieved over an insecure
+connection.
+If the connection is not encrypted, and the UNENCRYPTED subcommand is not
+given, then an error will occur.
+Whether or not the connection is
+encrypted depends upon the underlying psql library and the 
+capabilities of the database server.
+
+The following syntax is an example:
+@example
+GET DATA /TYPE=PSQL
+     /CONNECT='host=example.com port=5432 dbname=product user=fred passwd=xxxx'
+     /SQL='select * from manufacturer'.
+@end example
+
+
 @node GET DATA /TYPE=TXT
 @subsection Textual Data Files
 
 @node GET DATA /TYPE=TXT
 @subsection Textual Data Files
 
@@ -268,9 +326,11 @@ GET DATA /TYPE=TXT
 @cindex text files
 @cindex data files
 When TYPE=TXT is specified, GET DATA reads data in a delimited or
 @cindex text files
 @cindex data files
 When TYPE=TXT is specified, GET DATA reads data in a delimited or
-fixed columnar format, much like DATA LIST (@pxref{DATA LIST}).  The
-FILE subcommand must be specified indicate the name or the file handle
-of the file to be read.
+fixed columnar format, much like DATA LIST (@pxref{DATA LIST}).
+
+The FILE subcommand is mandatory.  Specify the file to be read as 
+a string file name or (for textual data
+only) a file handle (@pxref{File Handles}).
 
 The ARRANGEMENT subcommand determines the file's basic format.
 DELIMITED, the default setting, specifies that fields in the input
 
 The ARRANGEMENT subcommand determines the file's basic format.
 DELIMITED, the default setting, specifies that fields in the input
index c1dd098a7cec668be7a2d43671627fe74ad7d7a4..012ffaf52a9c8e02de42ec0ea71a8c23c6531a95 100644 (file)
@@ -1,3 +1,8 @@
+2008-02-02  John Darrington <john@darrington.wattle.id.au>
+
+       psql-reader.c psql-reader.h: New files.  Thanks to Ben Pfaff
+       for reviewing this code.
+       
 2008-02-02  Ben Pfaff  <blp@gnu.org>
 
        Patch #6347.
 2008-02-02  Ben Pfaff  <blp@gnu.org>
 
        Patch #6347.
index e06798671236214607fabfc9fd5f99302b1e4e50..a432e300ca114049524a3a6839045a153358df4b 100644 (file)
@@ -1,7 +1,7 @@
 
 noinst_LIBRARIES += src/data/libdata.a
 
 
 noinst_LIBRARIES += src/data/libdata.a
 
-src_data_libdata_a_CPPFLAGS = $(LIBXML2_CFLAGS) $(AM_CPPFLAGS)
+src_data_libdata_a_CPPFLAGS = $(LIBXML2_CFLAGS) $(PG_CFLAGS) $(AM_CPPFLAGS) 
 
 
 src_data_libdata_a_SOURCES = \
 
 
 src_data_libdata_a_SOURCES = \
@@ -69,6 +69,8 @@ src_data_libdata_a_SOURCES = \
        src/data/por-file-reader.h \
        src/data/por-file-writer.c \
        src/data/por-file-writer.h \
        src/data/por-file-reader.h \
        src/data/por-file-writer.c \
        src/data/por-file-writer.h \
+       src/data/psql-reader.c \
+       src/data/psql-reader.h \
        src/data/scratch-handle.c \
        src/data/scratch-handle.h \
        src/data/scratch-reader.c \
        src/data/scratch-handle.c \
        src/data/scratch-handle.h \
        src/data/scratch-reader.c \
index 112efefba10c1030b518c45a712ada0c03cefac2..187d6464bab0e2db6f33ccfc960fe05338e46777 100644 (file)
@@ -1,3 +1,7 @@
+2008-02-02 John Darrington <john@darrington.wattle.id.au>
+
+       * get-data.c (cmd_get_data): Support PSQL type.
+
 2007-12-07  Ben Pfaff  <blp@gnu.org>
 
        Patch #6302.
 2007-12-07  Ben Pfaff  <blp@gnu.org>
 
        Patch #6302.
index 7b38d62233e1d0ff76500c201f773a6141df5625..189054a507058c38b17b1ba027d0f69b5a995613 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 2007 Free Software Foundation, Inc.
+   Copyright (C) 2007, 2008 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -19,6 +19,7 @@
 #include <stdlib.h>
 
 #include <data/gnumeric-reader.h>
 #include <stdlib.h>
 
 #include <data/gnumeric-reader.h>
+#include <data/psql-reader.h>
 
 #include <data/dictionary.h>
 #include <data/format.h>
 
 #include <data/dictionary.h>
 #include <data/format.h>
@@ -38,6 +39,7 @@
 
 static int parse_get_gnm (struct lexer *lexer, struct dataset *);
 static int parse_get_txt (struct lexer *lexer, struct dataset *);
 
 static int parse_get_gnm (struct lexer *lexer, struct dataset *);
 static int parse_get_txt (struct lexer *lexer, struct dataset *);
+static int parse_get_psql (struct lexer *lexer, struct dataset *);
 
 int
 cmd_get_data (struct lexer *lexer, struct dataset *ds)
 
 int
 cmd_get_data (struct lexer *lexer, struct dataset *ds)
@@ -53,11 +55,78 @@ cmd_get_data (struct lexer *lexer, struct dataset *ds)
     return parse_get_gnm (lexer, ds);
   else if (lex_match_id (lexer, "TXT"))
     return parse_get_txt (lexer, ds);
     return parse_get_gnm (lexer, ds);
   else if (lex_match_id (lexer, "TXT"))
     return parse_get_txt (lexer, ds);
+  else if (lex_match_id (lexer, "PSQL"))
+    return parse_get_psql (lexer, ds);
 
   msg (SE, _("Unsupported TYPE %s"), lex_tokid (lexer));
   return CMD_FAILURE;
 }
 
 
   msg (SE, _("Unsupported TYPE %s"), lex_tokid (lexer));
   return CMD_FAILURE;
 }
 
+static int
+parse_get_psql (struct lexer *lexer, struct dataset *ds)
+{
+  struct psql_read_info psql;
+  psql.allow_clear = false;
+  psql.conninfo = NULL;
+  psql.str_width = -1;
+  ds_init_empty (&psql.sql);
+
+  lex_force_match (lexer, '/');
+
+  if (!lex_force_match_id (lexer, "CONNECT"))
+    goto error;
+
+  lex_force_match (lexer, '=');
+
+  if (!lex_force_string (lexer))
+    goto error;
+
+  psql.conninfo = strdup (ds_cstr (lex_tokstr (lexer)));
+
+  lex_get (lexer);
+
+  while (lex_match (lexer, '/') )
+    {
+      if ( lex_match_id (lexer, "ASSUMEDSTRWIDTH"))
+       {
+         lex_match (lexer, '=');
+         psql.str_width = lex_integer (lexer);
+         lex_get (lexer);
+       }
+      else if ( lex_match_id (lexer, "UNENCRYPTED"))
+       {
+         psql.allow_clear = true;
+       }
+      else if (lex_match_id (lexer, "SQL"))
+       {
+         lex_match (lexer, '=');
+         if ( ! lex_force_string (lexer) )
+           goto error;
+
+         ds_put_substring (&psql.sql,  lex_tokstr (lexer)->ss);
+         lex_get (lexer);
+       }
+     }
+  {
+    struct dictionary *dict = NULL;
+    struct casereader *reader = psql_open_reader (&psql, &dict);
+
+    if ( reader )
+      proc_set_active_file (ds, reader, dict);
+  }
+
+  ds_destroy (&psql.sql);
+  free (psql.conninfo);
+
+  return CMD_SUCCESS;
+
+ error:
+
+  ds_destroy (&psql.sql);
+  free (psql.conninfo);
+
+  return CMD_FAILURE;
+}
 
 static int
 parse_get_gnm (struct lexer *lexer, struct dataset *ds)
 
 static int
 parse_get_gnm (struct lexer *lexer, struct dataset *ds)
index 70cfefdbb04b1b2a91a0da35536554895361ed31..dfbc578574e1475cc9d69cf18978b21e7a20c6ef 100644 (file)
@@ -41,6 +41,7 @@ src_ui_gui_psppire_LDADD = \
        src/libpspp/libpspp.a \
        $(GTK_LIBS) \
        $(GLADE_LIBS) \
        src/libpspp/libpspp.a \
        $(GTK_LIBS) \
        $(GLADE_LIBS) \
+       $(PG_LIBS) \
        gl/libgl.la \
        @LIBINTL@ @LIBREADLINE@
 
        gl/libgl.la \
        @LIBINTL@ @LIBREADLINE@
 
index 65cd23a33818f4b7b9f37e2c71ca33e8efd3e03e..0684e313caa0638369df94207516d0990a3ac97f 100644 (file)
@@ -33,6 +33,7 @@ src_ui_terminal_pspp_LDADD = \
        src/data/libdata.a \
        src/libpspp/libpspp.a \
        $(LIBXML2_LIBS) \
        src/data/libdata.a \
        src/libpspp/libpspp.a \
        $(LIBXML2_LIBS) \
+       $(PG_LIBS) \
        $(LIBICONV) \
        gl/libgl.la \
        @LIBINTL@ @LIBREADLINE@
        $(LIBICONV) \
        gl/libgl.la \
        @LIBINTL@ @LIBREADLINE@
index aa9a92ffb35b685054f970dbdddb133eb97ba70b..6d0fd670e8142343e0879488648a84d240dac656 100644 (file)
@@ -154,6 +154,10 @@ if GNM_SUPPORT
 dist_TESTS += tests/command/get-data-gnm.sh 
 endif
 
 dist_TESTS += tests/command/get-data-gnm.sh 
 endif
 
+if PSQL_SUPPORT
+dist_TESTS += tests/command/get-data-psql.sh 
+endif
+
 nodist_TESTS = \
        tests/libpspp/abt-test \
        tests/libpspp/bt-test \
 nodist_TESTS = \
        tests/libpspp/abt-test \
        tests/libpspp/bt-test \