Dnia 2013-11-13, śro o godzinie 10:26 -0500, Bruce Momjian pisze:
> On Wed, Nov 13, 2013 at 08:58:07AM +0530, Amit Kapila wrote:
> > On Tue, Nov 12, 2013 at 9:37 PM, Bruce Momjian <br...@momjian.us> wrote:
> > > On Wed, Oct 23, 2013 at 10:31:39AM +0530, Amit Kapila wrote:
> > >> On Tue, Oct 22, 2013 at 3:04 AM, Piotr Marcinczyk <pmarc...@gmail.com> 
> > >> wrote:
> > >> > Hi,
> > >> >
> > >> > I would like to implement item from TODO marked as easy: "Add \i option
> > >> > to bring in the specified file as a quoted literal". I understand 
> > >> > intent
> > >> > of this item, to be able to have parts of query written in separate
> > >> > files (now it is impossible, because \i tries to execute content of 
> > >> > file
> > >> > as a separate command by function process_file).
> > >>
> > >> For the usecase discussed in the mail chain of that TODO item, Robert
> > >> Haas has provided an alternative to achieve it, please check below
> > >> link:
> > >> http://www.postgresql.org/message-id/AANLkTi=7c8xfyf7uqw0y+si8ondkoy2nx8jc4bu0g...@mail.gmail.com
> > >>
> > >> If you think that alternative is not sufficient for the use case, then
> > >> adding new option/syntax is worth, otherwise it might be a shortcut or
> > >> other form of some existing way which can be useful depending on how
> > >> frequently users use this syntax.
> > >
> > > So, can we remove this TODO item?
> >   TODO item is created before Robert Haas has provided an alternative
> > way to achieve the same thing. In some cases there are multiple ways
> > to
> >   achieve the same thing (example: shortcut options in psql) if it is
> > used quite frequently and people want some easy way of doing it. In
> > this case I
> >   don't think this is used frequently, so I don't see the need of
> > doing it. We should remove this TODO item.
> 
> OK, removed.
> 
Well, I wrote it few days ago. I'm sure it is not critical, but I
suppose it may be useful. This is my first patch, so I think that it is
good idea to sent it and have it reviewed anyway. First argument to send
it, is to see what kind of errors I made, to not do them in the next
patches. Second, if it (flexible appending file to buffer) appears
interesting for reviewer, it may be committed.
*** a/doc/src/sgml/ref/psql-ref.sgml
--- b/doc/src/sgml/ref/psql-ref.sgml
***************
*** 1731,1736 **** hello 10
--- 1731,1749 ----
  
  
        <varlistentry>
+         <term><literal>\ib <replaceable class="parameter">filename</replaceable> [ <replaceable class="parameter">quote_string</replaceable> ] </literal></term>
+         <listitem>
+         <para>
+         The <literal>\ib</> command appends content of file <literal>filename</literal> 
+         to current query buffer. If parameter <literal>quote_string</literal> 
+         is not set, no quotation is used. If it is set, content of file will be
+         quoted by <literal>quote_string</literal> enclosed in <literal>$</literal>.
+         </para>
+         </listitem>
+       </varlistentry>
+ 
+ 
+       <varlistentry>
          <term><literal>\ir <replaceable class="parameter">filename</replaceable></literal></term>
          <listitem>
          <para>
*** a/src/bin/psql/command.c
--- b/src/bin/psql/command.c
***************
*** 59,64 **** static backslashResult exec_command(const char *cmd,
--- 59,65 ----
  			 PQExpBuffer query_buf);
  static bool do_edit(const char *filename_arg, PQExpBuffer query_buf,
  		int lineno, bool *edited);
+ static bool do_append(const char *filename_arg, const char *quote_string, PQExpBuffer query_buf);
  static bool do_connect(char *dbname, char *user, char *host, char *port);
  static bool do_shell(const char *command);
  static bool do_watch(PQExpBuffer query_buf, long sleep);
***************
*** 798,806 **** exec_command(const char *cmd,
  	}
  
  
! 	/* \i and \ir include files */
  	else if (strcmp(cmd, "i") == 0 || strcmp(cmd, "include") == 0
! 		   || strcmp(cmd, "ir") == 0 || strcmp(cmd, "include_relative") == 0)
  	{
  		char	   *fname = psql_scan_slash_option(scan_state,
  												   OT_NORMAL, NULL, true);
--- 799,808 ----
  	}
  
  
! 	/* \i, \ib and \ir include files */
  	else if (strcmp(cmd, "i") == 0 || strcmp(cmd, "include") == 0
! 		   || strcmp(cmd, "ir") == 0 || strcmp(cmd, "include_relative") == 0
! 		   || strcmp(cmd, "ib") == 0 || strcmp(cmd, "include_buffer") == 0)
  	{
  		char	   *fname = psql_scan_slash_option(scan_state,
  												   OT_NORMAL, NULL, true);
***************
*** 812,823 **** exec_command(const char *cmd,
  		}
  		else
  		{
! 			bool		include_relative;
  
- 			include_relative = (strcmp(cmd, "ir") == 0
- 								|| strcmp(cmd, "include_relative") == 0);
- 			expand_tilde(&fname);
- 			success = (process_file(fname, false, include_relative) == EXIT_SUCCESS);
  			free(fname);
  		}
  	}
--- 814,845 ----
  		}
  		else
  		{
! 			bool	   include_buffer;
! 
! 			include_buffer = (strcmp(cmd, "ib") == 0
! 								|| strcmp(cmd, "include_buffer") == 0);
! 
! 
! 			if (include_buffer)
! 			{
! 				char *quote_string = psql_scan_slash_option(scan_state,
! 															OT_NORMAL, NULL, true);
! 				expand_tilde(&fname);
! 				success = !do_append(fname, quote_string, query_buf);
! 				if (success) {
! 					status = PSQL_CMD_NEWEDIT;
! 				} else {
! 					status = PSQL_CMD_ERROR;
! 				}
! 			} else {
! 				bool	   include_relative;
! 
! 				include_relative = (strcmp(cmd, "ir") == 0
! 									|| strcmp(cmd, "include_relative") == 0);
! 				expand_tilde(&fname);
! 				success = (process_file(fname, false, include_relative) == EXIT_SUCCESS);
! 			}
  
  			free(fname);
  		}
  	}
***************
*** 2099,2104 **** do_edit(const char *filename_arg, PQExpBuffer query_buf,
--- 2121,2175 ----
  }
  
  
+ /*
+  * do_append
+  *
+  * Read content from file and append it to query_buffer.
+  */
+ static bool
+ do_append(const char *fname, const char *quote_string, PQExpBuffer query_buf)
+ {
+ 	FILE	   *stream = NULL;
+ 	bool		error = false;
+ 	stream = fopen(fname, PG_BINARY_R);
+ 	if (!stream)
+ 	{
+ 		psql_error("%s: %s\n", fname, strerror(errno));
+ 		error = true;
+ 	}
+ 	else
+ 	{
+ 		/* read file back into query_buf */
+ 		char		line[1024];
+ 
+ 		/* insert newline to separate buffer from file input */
+ 		appendPQExpBufferStr(query_buf, "\n");
+ 		/* if quote_string exists add it before file content */
+ 		if (quote_string != NULL) {
+ 			appendPQExpBufferStr(query_buf, "$");
+ 			appendPQExpBufferStr(query_buf, quote_string);
+ 			appendPQExpBufferStr(query_buf, "$\n");
+ 		}
+ 		while (fgets(line, sizeof(line), stream) != NULL)
+ 			appendPQExpBufferStr(query_buf, line);
+ 
+ 		if (ferror(stream))
+ 		{
+ 			psql_error("%s: %s\n", fname, strerror(errno));
+ 			error = true;
+ 		}
+ 
+ 		fclose(stream);
+ 		/* if quote_string exists add it after file content */
+ 		if (quote_string != NULL) {
+ 			appendPQExpBufferStr(query_buf, "$");
+ 			appendPQExpBufferStr(query_buf, quote_string);
+ 			appendPQExpBufferStr(query_buf, "$");
+ 		}
+ 	}
+ 	return error;
+ }
+ 
  
  /*
   * process_file
*** a/src/bin/psql/help.c
--- b/src/bin/psql/help.c
***************
*** 187,192 **** slashUsage(unsigned short int pager)
--- 187,193 ----
  	fprintf(output, _("  \\s [FILE]              display history or save it to file\n"));
  #endif
  	fprintf(output, _("  \\w FILE                write query buffer to file\n"));
+ 	fprintf(output, _("  \\ib FILE [QUOTE_STR]   append file to query buffer\n"));
  	fprintf(output, "\n");
  
  	fprintf(output, _("Input/Output\n"));
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to