Обсуждение: Small problem in contrib/dbase/dbf2pg.c
Your name : Thomas Behr
Your email address : ------.----@bnv-bamberg.de
System Configuration
---------------------
Architecture (example: Intel Pentium) : ALL
Operating System (example: Linux 2.0.26 ELF) : ALL
PostgreSQL version (example: PostgreSQL-7.3.3): PostgreSQL-7.3.3
Compiler used (example: gcc 2.95.2) : WorkShop Compilers 5.0 98/12/15 C 5.0
Please enter a FULL description of your problem:
------------------------------------------------
dbf2pg - Insert xBase-style .dbf-files into a PostgreSQL-table
There is an option "-s oldname=newname", which changes the old field name of
the dbf-file to the newname in PostgeSQL. If the length of the new name is 0,
the field is skiped. If you want to skip the first field of the dbf-file,
you get the wildest error-messages from the backend.
dbf2pg load the dbf-file via "COPY tablename FROM STDIN". If you skip the
first field, it is an \t to much in STDIN.
Please describe a way to repeat the problem. Please try to provide a
concise reproducible example, if at all possible:
----------------------------------------------------------------------
dbf2pg -s first_field_name=,other_fieldname=,reserved_fieldname=new_fieldname
-c -d testdb -t testtable -h dbhost -U testuser -F IBM437 -T ISO-8859-1 -vv
test.dbf
If you know how this problem might be fixed, list the solution below:
---------------------------------------------------------------------
440 /* build line and submit */
441 result = dbf_get_record(dbh, fields, i);
442 if (result == DBF_VALID)
443 {
444 query[0] = '\0';
445 for (h = 0; h < dbh->db_nfields; h++)
446 {
447 if (!strlen(fields[h].db_name))
448 continue;
449
450 if (h != 0) /* not for the first field! */
451 strcat(query, "\t"); /* COPY statement field
452 * separator */
A fix could be an counter j=0, which increments only, if a field is imported
(IF (strlen(fields[h].db_name)> 0) j++. And only if j > 1 (if an other field is
imported) the \t is printed.
...
int j;
...
if (result == DBF_VALID)
{
query[0] = '\0';
j = 0;
for (h = 0; h < dbh->db_nfields; h++)
{
if (!strlen(fields[h].db_name))
{
continue;
}
else
{
j++;
}
if (j > 1) /* not for the first field! */
strcat(query, "\t"); /* COPY statement field
* separator */
An other small bug in the README:
-s start
Specify the first record-number in the xBase-file
we will insert.
should be
-e start
Specify the first record-number in the xBase-file
we will insert.
Thomas, would you send me a context diff (diff -c) of the change and I
will get into 7.4. Thanks.
---------------------------------------------------------------------------
Thomas Behr wrote:
> Your name : Thomas Behr
> Your email address : ------.----@bnv-bamberg.de
> System Configuration
> ---------------------
> Architecture (example: Intel Pentium) : ALL
> Operating System (example: Linux 2.0.26 ELF) : ALL
> PostgreSQL version (example: PostgreSQL-7.3.3): PostgreSQL-7.3.3
> Compiler used (example: gcc 2.95.2) : WorkShop Compilers 5.0 98/12/15 C 5.0
> Please enter a FULL description of your problem:
> ------------------------------------------------
> dbf2pg - Insert xBase-style .dbf-files into a PostgreSQL-table
> There is an option "-s oldname=newname", which changes the old field name of
> the dbf-file to the newname in PostgeSQL. If the length of the new name is 0,
> the field is skiped. If you want to skip the first field of the dbf-file,
> you get the wildest error-messages from the backend.
> dbf2pg load the dbf-file via "COPY tablename FROM STDIN". If you skip the
> first field, it is an \t to much in STDIN.
> Please describe a way to repeat the problem. Please try to provide a
> concise reproducible example, if at all possible:
> ----------------------------------------------------------------------
> dbf2pg -s first_field_name=,other_fieldname=,reserved_fieldname=new_fieldname
> -c -d testdb -t testtable -h dbhost -U testuser -F IBM437 -T ISO-8859-1 -vv
> test.dbf
>
> If you know how this problem might be fixed, list the solution below:
> ---------------------------------------------------------------------
>
> 440 /* build line and submit */
> 441 result = dbf_get_record(dbh, fields, i);
> 442 if (result == DBF_VALID)
> 443 {
> 444 query[0] = '\0';
> 445 for (h = 0; h < dbh->db_nfields; h++)
> 446 {
> 447 if (!strlen(fields[h].db_name))
> 448 continue;
> 449
> 450 if (h != 0) /* not for the first field! */
> 451 strcat(query, "\t"); /* COPY statement field
> 452 * separator */
>
>
>
> A fix could be an counter j=0, which increments only, if a field is imported
> (IF (strlen(fields[h].db_name)> 0) j++. And only if j > 1 (if an other field is
> imported) the \t is printed.
>
> ...
> int j;
> ...
>
> if (result == DBF_VALID)
> {
> query[0] = '\0';
> j = 0;
> for (h = 0; h < dbh->db_nfields; h++)
> {
> if (!strlen(fields[h].db_name))
> {
> continue;
> }
> else
> {
> j++;
> }
>
> if (j > 1) /* not for the first field! */
> strcat(query, "\t"); /* COPY statement field
> * separator */
>
>
> An other small bug in the README:
> -s start
> Specify the first record-number in the xBase-file
> we will insert.
> should be
> -e start
> Specify the first record-number in the xBase-file
> we will insert.
>
>
> ---------------------------(end of broadcast)---------------------------
> TIP 8: explain analyze is your friend
>
--
Bruce Momjian | http://candle.pha.pa.us
pgman@candle.pha.pa.us | (610) 359-1001
+ If your life is a hard drive, | 13 Roberts Road
+ Christ can be your backup. | Newtown Square, Pennsylvania 19073
Hej!
select version();
version
--------------------------------------------------------------
PostgreSQL 7.3.3 on sparc-sun-solaris2.7, compiled by cc -Xa
On 23 Jul 2003, Bruce Momjian wrote:
> Thomas, would you send me a context diff (diff -c) of the change and I
> will get into 7.4. Thanks.
I hope, it is OK.
Thomas
----8<-------------8<--------------8<----------
*** dbf2pg.c Thu Oct 31 20:11:48 2002
--- dbf2pg.c.TB Thu Jul 24 13:09:48 2003
***************
*** 194,200 ****
printf("dbf2pg\n"
"usage: dbf2pg [-u | -l] [-h hostname] [-W] [-U username]\n"
" [-B transaction_size] [-F charset_from [-T charset_to]]\n"
! " [-s oldname=newname[,oldname=newname[...]]] [-d dbase]\n"
" [-t table] [-c | -D] [-f] [-v[v]] dbf-file\n");
}
--- 194,200 ----
printf("dbf2pg\n"
"usage: dbf2pg [-u | -l] [-h hostname] [-W] [-U username]\n"
" [-B transaction_size] [-F charset_from [-T charset_to]]\n"
! " [-s oldname=[newname][,oldname=[newname][...]]] [-d dbase]\n"
" [-t table] [-c | -D] [-f] [-v[v]] dbf-file\n");
}
***************
*** 359,364 ****
--- 359,365 ----
field *fields;
int i,
h,
+ j,
result;
char *query,
*foo;
***************
*** 442,453 ****
if (result == DBF_VALID)
{
query[0] = '\0';
for (h = 0; h < dbh->db_nfields; h++)
{
! if (!strlen(fields[h].db_name))
continue;
! if (h != 0) /* not for the first field! */
strcat(query, "\t"); /* COPY statement field
* separator */
--- 443,461 ----
if (result == DBF_VALID)
{
query[0] = '\0';
+ j = 0; /* counter for fields in the output */
for (h = 0; h < dbh->db_nfields; h++)
{
! if (!strlen(fields[h].db_name)) /* When the new fieldname is empty, the field is skipped */
! {
continue;
+ }
+ else
+ {
+ j++;
+ }
! if (j > 1) /* not for the first field! */
strcat(query, "\t"); /* COPY statement field
* separator */
----8<-------------8<--------------8<----------
*** README.dbf2pg Fri Dec 21 06:29:46 2001
--- README.dbf2pg.TB Thu Jul 24 13:28:35 2003
***************
*** 12,18 ****
"dbf2pg [options] dbf-file"
Options:
[-v[v]] [-f] [-u | -l] [-c | -D] [-d database] [-t table]
! [-h host] [-s oldname=newname[,oldname=newname]] [-s
start] [-e end] [-W] [-U username] [-B transaction_size]
[-F charset_from [-T charset_to]]
--- 12,18 ----
"dbf2pg [options] dbf-file"
Options:
[-v[v]] [-f] [-u | -l] [-c | -D] [-d database] [-t table]
! [-h host] [-s oldname=[newname][,oldname=[newname]]] [-b
start] [-e end] [-W] [-U username] [-B transaction_size]
[-F charset_from [-T charset_to]]
***************
*** 70,84 ****
dbf2sql(1L) dbf2sql(1L)
! -s oldname=newname[,oldname=newname]
Change the name of a field from oldname to newname.
This is mainly used to avoid using reserved SQL-
! keywords. Example:
! -s SELECT=SEL,COMMIT=doit
This is done before the -f operator has taken
effect!
! -s start
Specify the first record-number in the xBase-file
we will insert.
--- 70,88 ----
dbf2sql(1L) dbf2sql(1L)
! -s oldname=[newname][,oldname=[newname]]
Change the name of a field from oldname to newname.
This is mainly used to avoid using reserved SQL-
! keywords. When the new fieldname is empty, the field
! is skipped in both the CREATE-clause and the
! INSERT-clauses, in common words: it will not be present
! in the SQL-table.
! Example:
! -s SELECT=SEL,remark=,COMMIT=doit
This is done before the -f operator has taken
effect!
! -b start
Specify the first record-number in the xBase-file
we will insert.
----8<-------------8<--------------8<----------
*** dbf2pg.1 Thu May 10 16:41:23 2001
--- dbf2pg.1.TB Thu Jul 24 13:33:08 2003
***************
*** 8,15 ****
Options:
.br
[-v[v]] [-f] [-u | -l] [-c | -D] [-d database] [-t table]
! [-h host] [-s oldname=newname[,oldname=newname]]
! [-s start] [-e end] [-W] [-U username] [-B transaction_size]
[-F charset_from [-T charset_to]]
.SH DESCRIPTION
--- 8,15 ----
Options:
.br
[-v[v]] [-f] [-u | -l] [-c | -D] [-d database] [-t table]
! [-h host] [-s oldname=[newname][,oldname=[newname]]]
! [-b start] [-e end] [-W] [-U username] [-B transaction_size]
[-F charset_from [-T charset_to]]
.SH DESCRIPTION
***************
*** 78,84 ****
.IR -f
operator has taken effect!
.TP
! .I "-s start"
Specify the first record-number in the xBase-file we will insert.
.TP
.I "-e end"
--- 78,84 ----
.IR -f
operator has taken effect!
.TP
! .I "-b start"
Specify the first record-number in the xBase-file we will insert.
.TP
.I "-e end"
----8<-------------8<--------------8<----------
Patch applied. Thanks.
---------------------------------------------------------------------------
Thomas Behr wrote:
> Hej!
>
> select version();
> version
> --------------------------------------------------------------
> PostgreSQL 7.3.3 on sparc-sun-solaris2.7, compiled by cc -Xa
>
> On 23 Jul 2003, Bruce Momjian wrote:
> > Thomas, would you send me a context diff (diff -c) of the change and I
> > will get into 7.4. Thanks.
>
> I hope, it is OK.
>
> Thomas
>
>
> ----8<-------------8<--------------8<----------
>
> *** dbf2pg.c Thu Oct 31 20:11:48 2002
> --- dbf2pg.c.TB Thu Jul 24 13:09:48 2003
> ***************
> *** 194,200 ****
> printf("dbf2pg\n"
> "usage: dbf2pg [-u | -l] [-h hostname] [-W] [-U username]\n"
> " [-B transaction_size] [-F charset_from [-T charset_to]]\n"
> ! " [-s oldname=newname[,oldname=newname[...]]] [-d dbase]\n"
> " [-t table] [-c | -D] [-f] [-v[v]] dbf-file\n");
> }
>
> --- 194,200 ----
> printf("dbf2pg\n"
> "usage: dbf2pg [-u | -l] [-h hostname] [-W] [-U username]\n"
> " [-B transaction_size] [-F charset_from [-T charset_to]]\n"
> ! " [-s oldname=[newname][,oldname=[newname][...]]] [-d dbase]\n"
> " [-t table] [-c | -D] [-f] [-v[v]] dbf-file\n");
> }
>
> ***************
> *** 359,364 ****
> --- 359,365 ----
> field *fields;
> int i,
> h,
> + j,
> result;
> char *query,
> *foo;
> ***************
> *** 442,453 ****
> if (result == DBF_VALID)
> {
> query[0] = '\0';
> for (h = 0; h < dbh->db_nfields; h++)
> {
> ! if (!strlen(fields[h].db_name))
> continue;
>
> ! if (h != 0) /* not for the first field! */
> strcat(query, "\t"); /* COPY statement field
> * separator */
>
> --- 443,461 ----
> if (result == DBF_VALID)
> {
> query[0] = '\0';
> + j = 0; /* counter for fields in the output */
> for (h = 0; h < dbh->db_nfields; h++)
> {
> ! if (!strlen(fields[h].db_name)) /* When the new fieldname is empty, the field is skipped */
> ! {
> continue;
> + }
> + else
> + {
> + j++;
> + }
>
> ! if (j > 1) /* not for the first field! */
> strcat(query, "\t"); /* COPY statement field
> * separator */
>
>
> ----8<-------------8<--------------8<----------
>
> *** README.dbf2pg Fri Dec 21 06:29:46 2001
> --- README.dbf2pg.TB Thu Jul 24 13:28:35 2003
> ***************
> *** 12,18 ****
> "dbf2pg [options] dbf-file"
> Options:
> [-v[v]] [-f] [-u | -l] [-c | -D] [-d database] [-t table]
> ! [-h host] [-s oldname=newname[,oldname=newname]] [-s
> start] [-e end] [-W] [-U username] [-B transaction_size]
> [-F charset_from [-T charset_to]]
>
> --- 12,18 ----
> "dbf2pg [options] dbf-file"
> Options:
> [-v[v]] [-f] [-u | -l] [-c | -D] [-d database] [-t table]
> ! [-h host] [-s oldname=[newname][,oldname=[newname]]] [-b
> start] [-e end] [-W] [-U username] [-B transaction_size]
> [-F charset_from [-T charset_to]]
>
> ***************
> *** 70,84 ****
> dbf2sql(1L) dbf2sql(1L)
>
>
> ! -s oldname=newname[,oldname=newname]
> Change the name of a field from oldname to newname.
> This is mainly used to avoid using reserved SQL-
> ! keywords. Example:
> ! -s SELECT=SEL,COMMIT=doit
> This is done before the -f operator has taken
> effect!
>
> ! -s start
> Specify the first record-number in the xBase-file
> we will insert.
>
> --- 70,88 ----
> dbf2sql(1L) dbf2sql(1L)
>
>
> ! -s oldname=[newname][,oldname=[newname]]
> Change the name of a field from oldname to newname.
> This is mainly used to avoid using reserved SQL-
> ! keywords. When the new fieldname is empty, the field
> ! is skipped in both the CREATE-clause and the
> ! INSERT-clauses, in common words: it will not be present
> ! in the SQL-table.
> ! Example:
> ! -s SELECT=SEL,remark=,COMMIT=doit
> This is done before the -f operator has taken
> effect!
>
> ! -b start
> Specify the first record-number in the xBase-file
> we will insert.
>
>
> ----8<-------------8<--------------8<----------
>
> *** dbf2pg.1 Thu May 10 16:41:23 2001
> --- dbf2pg.1.TB Thu Jul 24 13:33:08 2003
> ***************
> *** 8,15 ****
> Options:
> .br
> [-v[v]] [-f] [-u | -l] [-c | -D] [-d database] [-t table]
> ! [-h host] [-s oldname=newname[,oldname=newname]]
> ! [-s start] [-e end] [-W] [-U username] [-B transaction_size]
> [-F charset_from [-T charset_to]]
>
> .SH DESCRIPTION
> --- 8,15 ----
> Options:
> .br
> [-v[v]] [-f] [-u | -l] [-c | -D] [-d database] [-t table]
> ! [-h host] [-s oldname=[newname][,oldname=[newname]]]
> ! [-b start] [-e end] [-W] [-U username] [-B transaction_size]
> [-F charset_from [-T charset_to]]
>
> .SH DESCRIPTION
> ***************
> *** 78,84 ****
> .IR -f
> operator has taken effect!
> .TP
> ! .I "-s start"
> Specify the first record-number in the xBase-file we will insert.
> .TP
> .I "-e end"
> --- 78,84 ----
> .IR -f
> operator has taken effect!
> .TP
> ! .I "-b start"
> Specify the first record-number in the xBase-file we will insert.
> .TP
> .I "-e end"
>
>
>
> ----8<-------------8<--------------8<----------
>
> ---------------------------(end of broadcast)---------------------------
> TIP 6: Have you searched our list archives?
>
> http://archives.postgresql.org
>
--
Bruce Momjian | http://candle.pha.pa.us
pgman@candle.pha.pa.us | (610) 359-1001
+ If your life is a hard drive, | 13 Roberts Road
+ Christ can be your backup. | Newtown Square, Pennsylvania 19073