Added a dict parameter to data_in and dealt with the consequences.
[pspp-builds.git] / src / language / data-io / get-data.c
index 7b38d62233e1d0ff76500c201f773a6141df5625..32202babdea8848f5c3a06b6431b0db3c4b007ff 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 2007 Free Software Foundation, Inc.
+   Copyright (C) 2007, 2008, 2009 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
 #include <stdlib.h>
 
 #include <data/gnumeric-reader.h>
+#include <data/psql-reader.h>
 
 #include <data/dictionary.h>
 #include <data/format.h>
 #include <data/procedure.h>
+#include <data/settings.h>
 #include <language/command.h>
 #include <language/data-io/data-parser.h>
 #include <language/data-io/data-reader.h>
 #include <language/lexer/lexer.h>
 #include <libpspp/message.h>
 
+#include "xalloc.h"
+
 #include "gettext.h"
 #define _(msgid) gettext (msgid)
 #define N_(msgid) (msgid)
 
 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)
@@ -53,11 +58,85 @@ 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);
+  else if (lex_match_id (lexer, "PSQL"))
+    return parse_get_psql (lexer, ds);
 
   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;
+  psql.bsize = -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 = xstrdup (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, "BSIZE"))
+       {
+         lex_match (lexer, '=');
+         psql.bsize = 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)
@@ -74,7 +153,7 @@ parse_get_gnm (struct lexer *lexer, struct dataset *ds)
   if (!lex_force_string (lexer))
     goto error;
 
-  gri.file_name = strdup (ds_cstr (lex_tokstr (lexer)));
+  gri.file_name = xstrdup (ds_cstr (lex_tokstr (lexer)));
 
   lex_get (lexer);
 
@@ -93,7 +172,7 @@ parse_get_gnm (struct lexer *lexer, struct dataset *ds)
              if ( ! lex_force_string (lexer) )
                goto error;
 
-             gri.sheet_name = strdup (ds_cstr (lex_tokstr (lexer)));
+             gri.sheet_name = xstrdup (ds_cstr (lex_tokstr (lexer)));
              gri.sheet_index = -1;
            }
          else if (lex_match_id (lexer, "INDEX"))
@@ -117,7 +196,7 @@ parse_get_gnm (struct lexer *lexer, struct dataset *ds)
              if ( ! lex_force_string (lexer) )
                goto error;
 
-             gri.cell_range = strdup (ds_cstr (lex_tokstr (lexer)));
+             gri.cell_range = xstrdup (ds_cstr (lex_tokstr (lexer)));
            }
          else
            goto error;
@@ -192,7 +271,7 @@ static int
 parse_get_txt (struct lexer *lexer, struct dataset *ds)
 {
   struct data_parser *parser = NULL;
-  struct dictionary *dict = NULL;
+  struct dictionary *dict = dict_create ();
   struct file_handle *fh = NULL;
   struct dfm_reader *reader = NULL;
 
@@ -209,7 +288,7 @@ parse_get_txt (struct lexer *lexer, struct dataset *ds)
   if (fh == NULL)
     goto error;
 
-  parser = data_parser_create ();
+  parser = data_parser_create (dict);
   has_type = false;
   data_parser_set_type (parser, DP_DELIMITED);
   data_parser_set_span (parser, false);
@@ -353,18 +432,29 @@ parse_get_txt (struct lexer *lexer, struct dataset *ds)
 
           lex_get (lexer);
         }
-      else if (lex_match_id (lexer, "QUALIFIER"))
+      else if (lex_match_id (lexer, "QUALIFIERS"))
         {
-          if (!set_type (parser, "QUALIFIER", DP_DELIMITED, &has_type))
+          if (!set_type (parser, "QUALIFIERS", DP_DELIMITED, &has_type))
             goto error;
           lex_match (lexer, '=');
 
           if (!lex_force_string (lexer))
             goto error;
 
+          if (settings_get_syntax () == COMPATIBLE
+              && ds_length (lex_tokstr (lexer)) != 1)
+            {
+              msg (SE, _("In compatible syntax mode, the QUALIFIER string "
+                         "must contain exactly one character."));
+              goto error;
+            }
+
           data_parser_set_quotes (parser, ds_ss (lex_tokstr (lexer)));
           lex_get (lexer);
         }
+      else if (settings_get_syntax () == ENHANCED
+               && lex_match_id (lexer, "ESCAPE"))
+        data_parser_set_quote_escape (parser, true);
       else if (lex_match_id (lexer, "VARIABLES"))
         break;
       else
@@ -375,7 +465,7 @@ parse_get_txt (struct lexer *lexer, struct dataset *ds)
     }
   lex_match (lexer, '=');
 
-  dict = dict_create ();
+
   record = 1;
   type = data_parser_get_type (parser);
   do