PATCH [0/12]: Guile-DBI and Guile-DBD-Postgres

2008-09-19 Thread Linas Vepstas
Hi,

Below follows a series of 12 patches against Guile-DBI and DBD-Postgres.

Guile DBI is a wrapper for accessing SQL databases.

https://gna.org/projects/guile-dbi/

I'm posting here -- although there used to be guile-dbi-user and guile-dbi-devel
mailing lists, these had no subscribers, and quickly filled with spam, as
evidenced by their mail archives. I've applied to get an account on gna.org
to post the patches there, but its been a week, and my account application
still hasn't gone through :-( It also appears that the original maintainer,
Maurizio Boriani, is not responding to email. Bummer.

The patches fix a variety of different crashes and hangs, and also fix
problems with missing data (e.g. for a query with N records, only N-1
were being returned -- bad news when N=1)

--linas




[PATCH 1/12] Guile-DBI: Avoid multiple init

2008-09-19 Thread Linas Vepstas


If (use-modules (dbi dbi)) is called multiple times, then guile
will crash in various strange ways, often during garbage-collection.
Thus, avoid initializaing more than once.

From: Linas Vepstas <[EMAIL PROTECTED]>

---
 src/guile-dbi.c |3 +++
 1 file changed, 3 insertions(+)

Index: guile-dbi-2.0.0/src/guile-dbi.c
===
--- guile-dbi-2.0.0.orig/src/guile-dbi.c2008-09-15 13:03:05.0 
-0500
+++ guile-dbi-2.0.0/src/guile-dbi.c 2008-09-15 13:19:36.0 -0500
@@ -295,6 +295,9 @@ init_db_handle_type(void)
 void 
 init_dbi(void)
 {
+  static int is_inited = 0;
+  if (is_inited) return;
+  is_inited = 1;
   init_db_handle_type();
 
 #ifndef SCM_MAGIC_SNARFER


signature.asc
Description: Digital signature


[PATCH 2/12] Guile-DBI: minor cleanup

2008-09-19 Thread Linas Vepstas


Minor cleanup:
-- avoid forward decarations
-- rename confusingly named function
-- free function should return zero, per current guile specs.
-- remove deprecated header 
-- fix typo

Signed-off-by: Linas Vepstas <[EMAIL PROTECTED]>

---
 include/guile-dbi/guile-dbi.h |   10 +++---
 src/guile-dbi.c   |   14 --
 2 files changed, 7 insertions(+), 17 deletions(-)

Index: guile-dbi-2.0.0/src/guile-dbi.c
===
--- guile-dbi-2.0.0.orig/src/guile-dbi.c2008-09-16 17:26:58.0 
-0500
+++ guile-dbi-2.0.0/src/guile-dbi.c 2008-09-16 19:54:42.0 -0500
@@ -29,11 +29,6 @@
 
 
 static scm_t_bits g_db_handle_tag;
-static SCM mark_db_handle (SCM g_db_handle_smob);
-static size_t free_db_handle (SCM g_db_handle_smob);
-static int print_db_handle (SCM g_db_handle_smob, SCM port,
-   scm_print_state* pstate);
-
 
 #define DBI_SMOB_P(obj) ((SCM_NIMP(obj)) && (SCM_TYP16(obj)==g_db_handle_tag))
 
@@ -154,7 +149,7 @@ SCM_DEFINE (close_g_db_handle, "dbi-clos
 #define FUNC_NAME s_close_db_handle
 {
   struct g_db_handle *g_db_handle = NULL;
-  void (*dbi_close)(gdbi_db_handle_t*);
+  void (*dbd_close)(gdbi_db_handle_t*);
 
   SCM_ASSERT (DBI_SMOB_P(db_handle), db_handle, SCM_ARG1, "close_g_db_handle");
   g_db_handle = (struct g_db_handle*)SCM_SMOB_DATA(db_handle);
@@ -164,12 +159,12 @@ SCM_DEFINE (close_g_db_handle, "dbi-clos
   return  SCM_UNSPECIFIED;
 }
 
-  __gdbi_dbd_wrap(g_db_handle,(char*) __FUNCTION__,(void**) &dbi_close);  
+  __gdbi_dbd_wrap(g_db_handle,(char*) __FUNCTION__,(void**) &dbd_close);  
   if (scm_equal_p (SCM_CAR(g_db_handle->status),scm_from_int(0)) == SCM_BOOL_F)
 {
   return  SCM_UNSPECIFIED;
 }
-  (*dbi_close)(g_db_handle);
+  (*dbd_close)(g_db_handle);
   if (g_db_handle->handle)
 {
   dlclose(g_db_handle->handle);
@@ -185,7 +180,6 @@ static size_t 
 free_db_handle (SCM g_db_handle_smob)
 {
   struct g_db_handle *g_db_handle = NULL;
-  size_t size = sizeof(struct g_db_handle);
 
   g_db_handle = (struct g_db_handle*)SCM_SMOB_DATA(g_db_handle_smob);
   close_g_db_handle(g_db_handle_smob);
@@ -196,7 +190,7 @@ free_db_handle (SCM g_db_handle_smob)
 }
 
   SCM_SETCDR (g_db_handle_smob, (SCM)NULL);
-  return (size);
+  return 0;
 }
 
 
Index: guile-dbi-2.0.0/include/guile-dbi/guile-dbi.h
===
--- guile-dbi-2.0.0.orig/include/guile-dbi/guile-dbi.h  2008-09-16 
19:03:18.0 -0500
+++ guile-dbi-2.0.0/include/guile-dbi/guile-dbi.h   2008-09-16 
19:53:09.0 -0500
@@ -17,17 +17,13 @@
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- *
- * Process this file with autoconf to produce a configure script. */
+ */
 
 
 #ifndef __GUILE_DBI_H__
 #define __GUILE_DBI_H__
 
-
 #include 
-#include 
-
 
 /* guile smob struct */
 typedef struct g_db_handle
@@ -50,8 +46,8 @@ void init_dbi(void);
 
 
 
-/* dbd dynamyc wrapper stuff */
+/* dbd dynamic wrapper stuff */
 void __gdbi_dbd_wrap(gdbi_db_handle_t* dbh, char* function_name,
 void** function_pointer);
-/* end dbd dynamyc wrapper stuff */
+/* end dbd dynamic wrapper stuff */
 #endif


signature.asc
Description: Digital signature


[PATCH 3/12] Guile-DBI: Fix memory leak

2008-09-19 Thread Linas Vepstas


Fix memory leak; various allocated strins are not freed
in assorted error paths.

Signed-off-by: Linas Vepstas <[EMAIL PROTECTED]>

---
 src/guile-dbi.c |7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

Index: guile-dbi-2.0.0/src/guile-dbi.c
===
--- guile-dbi-2.0.0.orig/src/guile-dbi.c2008-09-16 20:52:25.0 
-0500
+++ guile-dbi-2.0.0/src/guile-dbi.c 2008-09-16 20:53:13.0 -0500
@@ -55,12 +55,13 @@ SCM_DEFINE (make_g_db_handle, "dbi-open"
   g_db_handle->handle  = NULL;
   g_db_handle->db_info = NULL;
 
-  bcknd_str = (char*) gh_scm2newstr(bcknd,NULL);
+  bcknd_str = scm_to_locale_string (bcknd);
 
   sodbd=(char*) malloc (sizeof(char)*(strlen("libguile-dbd-") +
  strlen(bcknd_str) + 10));
   if (sodbd == NULL)
 {
+  free(bcknd_str);
   g_db_handle->status = scm_cons(scm_from_int(errno),
 scm_makfrom0str(strerror(errno)));
   SCM_RETURN_NEWSMOB (g_db_handle_tag, g_db_handle);
@@ -70,6 +71,8 @@ SCM_DEFINE (make_g_db_handle, "dbi-open"
   g_db_handle->handle = dlopen(sodbd,RTLD_NOW);
   if ( g_db_handle->handle == NULL)
 {
+  free(bcknd_str);
+  free(sodbd);
   g_db_handle->status =  scm_cons(scm_from_int(1),
  scm_makfrom0str(dlerror()));  
   SCM_RETURN_NEWSMOB (g_db_handle_tag, g_db_handle);
@@ -78,6 +81,8 @@ SCM_DEFINE (make_g_db_handle, "dbi-open"
   __gdbi_dbd_wrap(g_db_handle,(char*) __FUNCTION__,(void**) &connect);  
   if (scm_equal_p (SCM_CAR(g_db_handle->status),scm_from_int(0)) == SCM_BOOL_F)
 {
+  free(bcknd_str);
+  free(sodbd);
   SCM_RETURN_NEWSMOB (g_db_handle_tag, g_db_handle);
 }
   


signature.asc
Description: Digital signature


[PATCH 4/12] Guile-DBII: replace deprecated gh_ functions

2008-09-19 Thread Linas Vepstas


Replace deprecated gh_ functions with modern scm_ functions
Also, another memory leak.

Signed-off-by: Linas Vepstas <[EMAIL PROTECTED]>

---
 src/guile-dbi.c |6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

Index: guile-dbi-2.0.0/src/guile-dbi.c
===
--- guile-dbi-2.0.0.orig/src/guile-dbi.c2008-09-16 18:44:31.0 
-0500
+++ guile-dbi-2.0.0/src/guile-dbi.c 2008-09-16 18:47:11.0 -0500
@@ -214,7 +214,7 @@ SCM_DEFINE (query_g_db_handle, "dbi-quer
   SCM_ASSERT (scm_is_string (query), query, SCM_ARG2, "query_g_db_handle");
 
   g_db_handle = (struct g_db_handle*)SCM_SMOB_DATA(db_handle);
-  query_str = (char*) gh_scm2newstr(query,NULL);
+  query_str = scm_to_locale_string(query);
 
   __gdbi_dbd_wrap(g_db_handle,(char*) __FUNCTION__,(void**) &dbi_query);  
   if (scm_equal_p (SCM_CAR(g_db_handle->status),scm_from_int(0)) == SCM_BOOL_F)
@@ -315,11 +315,12 @@ __gdbi_dbd_wrap(gdbi_db_handle_t* dbh, c
   char *func  = NULL;
   char *bcknd = NULL;
 
-  bcknd = (char*) gh_scm2newstr(dbh->bcknd,NULL);
+  bcknd = scm_to_locale_string(dbh->bcknd);
 
   if((func=malloc(sizeof(char)*(strlen(function_name)+
  20))) == NULL)
 {
+  free(bcknd);
   dbh->status = (SCM) scm_cons(scm_from_int(errno),
   scm_makfrom0str(strerror(errno)));
   return;
@@ -329,6 +330,7 @@ __gdbi_dbd_wrap(gdbi_db_handle_t* dbh, c
   *(void **) (function_pointer) = dlsym(dbh->handle,func);
   if((ret = dlerror()) != NULL)
 {
+  free(bcknd);
   dbh->status = (SCM) scm_cons(scm_from_int(1),
   scm_makfrom0str(ret));
   return;


signature.asc
Description: Digital signature


[PATCH 6/12] Guile-DBI: Fix crash, avoid recursive free

2008-09-19 Thread Linas Vepstas


There is a particularly nasty crash scenario invloving the 
garbage collector. The problem is that the dbi free routine
calls the dbi close routine, which tries to alloc new SCM
nodes. This is bad, because one should not alloc while 
the garbage collector is running. So add a flag, incidating
that a free is in progress. 

The DBD layers will have to honour this flag.

(also fixes one more mem leak).

Signed-off-by: Linas Vepstas <[EMAIL PROTECTED]>

---
 include/guile-dbi/guile-dbi.h |1 +
 src/guile-dbi.c   |   14 --
 2 files changed, 13 insertions(+), 2 deletions(-)

Index: guile-dbi-2.0.0/include/guile-dbi/guile-dbi.h
===
--- guile-dbi-2.0.0.orig/include/guile-dbi/guile-dbi.h  2008-09-16 
21:36:22.0 -0500
+++ guile-dbi-2.0.0/include/guile-dbi/guile-dbi.h   2008-09-16 
21:40:30.0 -0500
@@ -34,6 +34,7 @@ typedef struct g_db_handle
   SCM closed;  /* boolean, TRUE if closed otherwise FALSE */
   void* handle;
   void* db_info;
+  int in_free;
 } gdbi_db_handle_t;
 /* end guile smob struct */
 
Index: guile-dbi-2.0.0/src/guile-dbi.c
===
--- guile-dbi-2.0.0.orig/src/guile-dbi.c2008-09-16 21:40:24.0 
-0500
+++ guile-dbi-2.0.0/src/guile-dbi.c 2008-09-16 21:40:30.0 -0500
@@ -53,6 +53,8 @@ SCM_DEFINE (make_g_db_handle, "dbi-open"
   g_db_handle->bcknd   = bcknd;
   g_db_handle->constr  = conn_string;
   g_db_handle->handle  = NULL;
+  g_db_handle->closed  = SCM_BOOL_T;
+  g_db_handle->in_free = 0;
   g_db_handle->db_info = NULL;
 
   bcknd_str = scm_to_locale_string (bcknd);
@@ -189,6 +191,9 @@ free_db_handle (SCM g_db_handle_smob)
   struct g_db_handle *g_db_handle = NULL;
 
   g_db_handle = (struct g_db_handle*)SCM_SMOB_DATA(g_db_handle_smob);
+  if (g_db_handle->in_free) return 0;
+  g_db_handle->in_free = 1;
+
   close_g_db_handle(g_db_handle_smob);
 
   if (g_db_handle != NULL)
@@ -325,7 +330,8 @@ __gdbi_dbd_wrap(gdbi_db_handle_t* dbh, c
  20))) == NULL)
 {
   free(bcknd);
-  dbh->status = (SCM) scm_cons(scm_from_int(errno),
+  if (dbh->in_free) return; /* do not SCM anything while in GC */
+  dbh->status = scm_cons(scm_from_int(errno),
   scm_makfrom0str(strerror(errno)));
   return;
 }
@@ -335,6 +341,8 @@ __gdbi_dbd_wrap(gdbi_db_handle_t* dbh, c
   if((ret = dlerror()) != NULL)
 {
   free(bcknd);
+  free(func);
+  if (dbh->in_free) return; /* do not SCM anything while in GC */
   dbh->status = (SCM) scm_cons(scm_from_int(1),
   scm_makfrom0str(ret));
   return;
@@ -345,8 +353,10 @@ __gdbi_dbd_wrap(gdbi_db_handle_t* dbh, c
 {
   free(bcknd);
 }
+
+  if (dbh->in_free) return; /* do not SCM anything while in GC */
   /* todo: error msg to be translated */
-  dbh->status = (SCM) scm_cons(scm_from_int(0),
+  dbh->status = scm_cons(scm_from_int(0),
   scm_makfrom0str("symbol loaded"));
   return;
 }


signature.asc
Description: Digital signature


[PATCH 5/12] Guile-DBI: Use remember_upto_here

2008-09-19 Thread Linas Vepstas

Sprinkle code with some scm_remember_upto_here_1(), as it looks like
there's a potential garbage-collection race.

Also, simplify a particularly complicated test.

Signed-off-by: Linas Vepstas <[EMAIL PROTECTED]>

---
 src/guile-dbi.c |   16 ++--
 1 file changed, 10 insertions(+), 6 deletions(-)

Index: guile-dbi-2.0.0/src/guile-dbi.c
===
--- guile-dbi-2.0.0.orig/src/guile-dbi.c2008-09-16 20:53:23.0 
-0500
+++ guile-dbi-2.0.0/src/guile-dbi.c 2008-09-16 21:40:24.0 -0500
@@ -159,7 +159,7 @@ SCM_DEFINE (close_g_db_handle, "dbi-clos
   SCM_ASSERT (DBI_SMOB_P(db_handle), db_handle, SCM_ARG1, "close_g_db_handle");
   g_db_handle = (struct g_db_handle*)SCM_SMOB_DATA(db_handle);
 
-  if (scm_equal_p (g_db_handle->closed, SCM_BOOL_T) == SCM_BOOL_T)
+  if (g_db_handle->closed == SCM_BOOL_T)
 {
   return  SCM_UNSPECIFIED;
 }
@@ -167,6 +167,7 @@ SCM_DEFINE (close_g_db_handle, "dbi-clos
   __gdbi_dbd_wrap(g_db_handle,(char*) __FUNCTION__,(void**) &dbd_close);  
   if (scm_equal_p (SCM_CAR(g_db_handle->status),scm_from_int(0)) == SCM_BOOL_F)
 {
+  scm_remember_upto_here_1(db_handle);
   return  SCM_UNSPECIFIED;
 }
   (*dbd_close)(g_db_handle);
@@ -175,6 +176,7 @@ SCM_DEFINE (close_g_db_handle, "dbi-clos
   dlclose(g_db_handle->handle);
   g_db_handle->handle = NULL;
 }
+  scm_remember_upto_here_1(db_handle);
   return  SCM_UNSPECIFIED;
 }
 #undef FUNC_NAME
@@ -217,13 +219,13 @@ SCM_DEFINE (query_g_db_handle, "dbi-quer
   query_str = scm_to_locale_string(query);
 
   __gdbi_dbd_wrap(g_db_handle,(char*) __FUNCTION__,(void**) &dbi_query);  
-  if (scm_equal_p (SCM_CAR(g_db_handle->status),scm_from_int(0)) == SCM_BOOL_F)
+  if (scm_equal_p (SCM_CAR(g_db_handle->status),scm_from_int(0)) == SCM_BOOL_T)
 {
-  return(SCM_UNSPECIFIED);
+  (*dbi_query)(g_db_handle,query_str);
 }
-  
-  (*dbi_query)(g_db_handle,query_str);
 
+  free(query_str);
+  scm_remember_upto_here_1(db_handle);
   return (SCM_UNSPECIFIED);  
 }
 #undef FUNC_NAME
@@ -240,17 +242,18 @@ SCM_DEFINE (getrow_g_db_handle, "dbi-get
   SCM (*dbi_getrow)(gdbi_db_handle_t*);
 
   SCM_ASSERT (DBI_SMOB_P(db_handle), db_handle, SCM_ARG1, 
"getrow_g_db_handle");  
-
   g_db_handle = (struct g_db_handle*)SCM_SMOB_DATA(db_handle);
 
   __gdbi_dbd_wrap(g_db_handle,(char*) __FUNCTION__,(void**) &dbi_getrow);  
   if (scm_equal_p (SCM_CAR(g_db_handle->status),scm_from_int(0)) == SCM_BOOL_F)
 {
+  scm_remember_upto_here_1(db_handle);
   return(retrow);
 }
   
   retrow = (*dbi_getrow)(g_db_handle);
 
+  scm_remember_upto_here_1(db_handle);
   return(retrow);  
 }
 #undef FUNC_NAME
@@ -270,6 +273,7 @@ SCM_DEFINE (getstat_g_db_handle, "dbi-ge
 
   if (g_db_handle != NULL)
 {
+  scm_remember_upto_here_1(db_handle);
   return (g_db_handle->status);
 }
 


signature.asc
Description: Digital signature


[PATCH 7/12] Guile-DBI: Don't cast away const

2008-09-19 Thread Linas Vepstas


Avoid casting away const. Actually, avoid casting.

Signed-off-by: Linas Vepstas <[EMAIL PROTECTED]>

---
 include/guile-dbi/guile-dbi.h |2 +-
 src/guile-dbi.c   |   15 +++
 2 files changed, 8 insertions(+), 9 deletions(-)

Index: guile-dbi-2.0.0/include/guile-dbi/guile-dbi.h
===
--- guile-dbi-2.0.0.orig/include/guile-dbi/guile-dbi.h  2008-09-16 
21:40:30.0 -0500
+++ guile-dbi-2.0.0/include/guile-dbi/guile-dbi.h   2008-09-16 
21:40:43.0 -0500
@@ -48,7 +48,7 @@ void init_dbi(void);
 
 
 /* dbd dynamic wrapper stuff */
-void __gdbi_dbd_wrap(gdbi_db_handle_t* dbh, char* function_name,
+void __gdbi_dbd_wrap(gdbi_db_handle_t* dbh, const char* function_name,
 void** function_pointer);
 /* end dbd dynamic wrapper stuff */
 #endif
Index: guile-dbi-2.0.0/src/guile-dbi.c
===
--- guile-dbi-2.0.0.orig/src/guile-dbi.c2008-09-16 21:40:30.0 
-0500
+++ guile-dbi-2.0.0/src/guile-dbi.c 2008-09-16 21:42:31.0 -0500
@@ -80,7 +80,7 @@ SCM_DEFINE (make_g_db_handle, "dbi-open"
   SCM_RETURN_NEWSMOB (g_db_handle_tag, g_db_handle);
 }
 
-  __gdbi_dbd_wrap(g_db_handle,(char*) __FUNCTION__,(void**) &connect);  
+  __gdbi_dbd_wrap(g_db_handle, __FUNCTION__,(void**) &connect);
   if (scm_equal_p (SCM_CAR(g_db_handle->status),scm_from_int(0)) == SCM_BOOL_F)
 {
   free(bcknd_str);
@@ -166,7 +166,7 @@ SCM_DEFINE (close_g_db_handle, "dbi-clos
   return  SCM_UNSPECIFIED;
 }
 
-  __gdbi_dbd_wrap(g_db_handle,(char*) __FUNCTION__,(void**) &dbd_close);  
+  __gdbi_dbd_wrap(g_db_handle, __FUNCTION__,(void**) &dbd_close);
   if (scm_equal_p (SCM_CAR(g_db_handle->status),scm_from_int(0)) == SCM_BOOL_F)
 {
   scm_remember_upto_here_1(db_handle);
@@ -223,7 +223,7 @@ SCM_DEFINE (query_g_db_handle, "dbi-quer
   g_db_handle = (struct g_db_handle*)SCM_SMOB_DATA(db_handle);
   query_str = scm_to_locale_string(query);
 
-  __gdbi_dbd_wrap(g_db_handle,(char*) __FUNCTION__,(void**) &dbi_query);  
+  __gdbi_dbd_wrap(g_db_handle, __FUNCTION__,(void**) &dbi_query);
   if (scm_equal_p (SCM_CAR(g_db_handle->status),scm_from_int(0)) == SCM_BOOL_T)
 {
   (*dbi_query)(g_db_handle,query_str);
@@ -249,7 +249,7 @@ SCM_DEFINE (getrow_g_db_handle, "dbi-get
   SCM_ASSERT (DBI_SMOB_P(db_handle), db_handle, SCM_ARG1, 
"getrow_g_db_handle");  
   g_db_handle = (struct g_db_handle*)SCM_SMOB_DATA(db_handle);
 
-  __gdbi_dbd_wrap(g_db_handle,(char*) __FUNCTION__,(void**) &dbi_getrow);  
+  __gdbi_dbd_wrap(g_db_handle, __FUNCTION__,(void**) &dbi_getrow);
   if (scm_equal_p (SCM_CAR(g_db_handle->status),scm_from_int(0)) == SCM_BOOL_F)
 {
   scm_remember_upto_here_1(db_handle);
@@ -317,7 +317,7 @@ init_dbi(void)
 
 /* dbd handler */
 void
-__gdbi_dbd_wrap(gdbi_db_handle_t* dbh, char* function_name,
+__gdbi_dbd_wrap(gdbi_db_handle_t* dbh, const char* function_name,
void** function_pointer)
 {
   char *ret   = NULL;
@@ -337,13 +337,13 @@ __gdbi_dbd_wrap(gdbi_db_handle_t* dbh, c
 }
 
   sprintf(func,"__%s_%s",bcknd,function_name);
-  *(void **) (function_pointer) = dlsym(dbh->handle,func);
+  *function_pointer = dlsym(dbh->handle,func);
   if((ret = dlerror()) != NULL)
 {
   free(bcknd);
   free(func);
   if (dbh->in_free) return; /* do not SCM anything while in GC */
-  dbh->status = (SCM) scm_cons(scm_from_int(1),
+  dbh->status = scm_cons(scm_from_int(1),
   scm_makfrom0str(ret));
   return;
 }
@@ -358,5 +358,4 @@ __gdbi_dbd_wrap(gdbi_db_handle_t* dbh, c
   /* todo: error msg to be translated */
   dbh->status = scm_cons(scm_from_int(0),
   scm_makfrom0str("symbol loaded"));
-  return;
 }


signature.asc
Description: Digital signature


[PATCH 8/12] Guile-DBD-postgres: Fix handling of float point columns

2008-09-19 Thread Linas Vepstas


Database columns containing floating point and double values
are not handled correctly; they are handled as ints. Fix this.

Signed-off-by: Linas Vepstas <[EMAIL PROTECTED]>

---
 src/guile-dbd-postgresql.c |9 +++--
 1 file changed, 7 insertions(+), 2 deletions(-)

Index: guile-dbd-postgresql-2.0.0/src/guile-dbd-postgresql.c
===
--- guile-dbd-postgresql-2.0.0.orig/src/guile-dbd-postgresql.c  2008-09-15 
10:22:59.0 -0500
+++ guile-dbd-postgresql-2.0.0/src/guile-dbd-postgresql.c   2008-09-15 
10:33:54.0 -0500
@@ -311,8 +311,6 @@ __postgresql_getrow_g_db_handle(gdbi_db_
   SCM value;
   int type = PQftype(pgsqlP->res,f);
   if ((type >= 20 && type <= 24) ||
- type == 700||
- type == 701||
  type == 1700   ||
  type == 26  )
{
@@ -320,6 +318,13 @@ __postgresql_getrow_g_db_handle(gdbi_db_
  PQgetlength(pgsqlP->res,pgsqlP->lget,f));
  value = scm_int2num(atoi(value_str));
}
+  else if (type == 700 ||
+ type == 701)
+   {
+ value_str = (char*) strndup(PQgetvalue(pgsqlP->res,pgsqlP->lget,f),
+ PQgetlength(pgsqlP->res,pgsqlP->lget,f));
+ value = scm_from_double(atof(value_str));
+   }
   else if (type == 18 ||
   type == 19 ||
   type == 25 ||


signature.asc
Description: Digital signature


[PATCH 9/12] Guile-DBD-postgres: Avoid discouraged functions

2008-09-19 Thread Linas Vepstas


Don't use functions from the guile "discouraged" header.

Signed-off-by: Linas Vepstas <[EMAIL PROTECTED]>

---
 src/guile-dbd-postgresql.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Index: guile-dbd-postgresql-2.0.0/src/guile-dbd-postgresql.c
===
--- guile-dbd-postgresql-2.0.0.orig/src/guile-dbd-postgresql.c  2008-09-15 
10:45:02.0 -0500
+++ guile-dbd-postgresql-2.0.0/src/guile-dbd-postgresql.c   2008-09-15 
13:24:54.0 -0500
@@ -316,7 +316,7 @@ __postgresql_getrow_g_db_handle(gdbi_db_
{
  value_str = (char*) strndup(PQgetvalue(pgsqlP->res,pgsqlP->lget,f),
  PQgetlength(pgsqlP->res,pgsqlP->lget,f));
- value = scm_int2num(atoi(value_str));
+ value = scm_from_long(atoi(value_str));
}
   else if (type == 700 ||
  type == 701)


signature.asc
Description: Digital signature


[PATCH 10/12] Guile-DBD-postgres: Fix off-by-one when fetching rows

2008-09-19 Thread Linas Vepstas


It appears that the current postgres dbd code will return one less
row than the database actually contains, which is a disaster if 
the database holds only one row! Fix this.

Signed-off-by: Linas Vepstas <[EMAIL PROTECTED]>

---
 src/guile-dbd-postgresql.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Index: guile-dbd-postgresql-2.0.0/src/guile-dbd-postgresql.c
===
--- guile-dbd-postgresql-2.0.0.orig/src/guile-dbd-postgresql.c  2008-09-15 
14:10:33.0 -0500
+++ guile-dbd-postgresql-2.0.0/src/guile-dbd-postgresql.c   2008-09-15 
14:11:02.0 -0500
@@ -299,7 +299,7 @@ __postgresql_getrow_g_db_handle(gdbi_db_
   pgsqlP->lget = 0;
   return (SCM_BOOL_F);
 }
-  else if (pgsqlP->lget == (PQntuples(pgsqlP->res) - 1))
+  else if (pgsqlP->lget == PQntuples(pgsqlP->res))
 {
   pgsqlP->res = PQgetResult(pgsqlP->pgsql);
 }


signature.asc
Description: Digital signature


[PATCH 11/12] Guile-DBD-postgres: Avoid deprecated functions

2008-09-19 Thread Linas Vepstas

Don't use deprecated guile gh_ functions. Also, move
some string handling functions around so as to avoid memory leak.

Also, avoid some casting. Casting is bad, it can hide errors 
from the compiler.

Signed-off-by: Linas Vepstas <[EMAIL PROTECTED]>

---
 src/guile-dbd-postgresql.c |   67 ++---
 1 file changed, 34 insertions(+), 33 deletions(-)

Index: guile-dbd-postgresql-2.0.0/src/guile-dbd-postgresql.c
===
--- guile-dbd-postgresql-2.0.0.orig/src/guile-dbd-postgresql.c  2008-09-16 
19:31:37.0 -0500
+++ guile-dbd-postgresql-2.0.0/src/guile-dbd-postgresql.c   2008-09-16 
19:46:13.0 -0500
@@ -23,7 +23,6 @@
 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
@@ -59,7 +58,7 @@ __postgresql_make_g_db_handle(gdbi_db_ha
   if(scm_equal_p(scm_string_p(dbh->constr), SCM_BOOL_F) == SCM_BOOL_T)
 {
   /* todo: error msg to be translated */
-  dbh->status = (SCM) scm_cons(scm_from_int(1),
+  dbh->status = scm_cons(scm_from_int(1),
   scm_from_locale_string("missing connection 
string"));
   return;
 }
@@ -70,11 +69,7 @@ __postgresql_make_g_db_handle(gdbi_db_ha
   if (items >= 5 && items < 8)
 {
   char* port = NULL;
-  char* user = gh_scm2newstr(scm_list_ref(cp_list,scm_from_int(0)),NULL);
-  char* pass = gh_scm2newstr(scm_list_ref(cp_list,scm_from_int(1)),NULL);
-  char* db   = gh_scm2newstr(scm_list_ref(cp_list,scm_from_int(2)),NULL);
-  char* ctyp = gh_scm2newstr(scm_list_ref(cp_list,scm_from_int(3)),NULL);
-  char* loc  = gh_scm2newstr(scm_list_ref(cp_list,scm_from_int(4)),NULL);
+  char* user, *pass, *db, *ctyp, *loc;
 
   pgsqlP = (gdbi_pgsql_ds_t*)malloc(sizeof(gdbi_pgsql_ds_t));
   pgsqlP->retn = 0;
@@ -86,18 +81,24 @@ __postgresql_make_g_db_handle(gdbi_db_ha
  return;
}
 
+  user = scm_to_locale_string(scm_list_ref(cp_list,scm_from_int(0)));
+  pass = scm_to_locale_string(scm_list_ref(cp_list,scm_from_int(1)));
+  db   = scm_to_locale_string(scm_list_ref(cp_list,scm_from_int(2)));
+  ctyp = scm_to_locale_string(scm_list_ref(cp_list,scm_from_int(3)));
+  loc  = scm_to_locale_string(scm_list_ref(cp_list,scm_from_int(4)));
+
   pgsqlP->pgsql = NULL;
   pgsqlP->res   = NULL;
 
   if (strcmp(ctyp,"tcp") == 0)
{
- port  = (char*) 
gh_scm2newstr(scm_list_ref(cp_list,scm_from_int(5)),NULL);
+ port  = scm_to_locale_string(scm_list_ref(cp_list,scm_from_int(5)));
  pgsqlP->pgsql = (PGconn*) 
PQsetdbLogin(loc,port,NULL,NULL,db,user,pass);
  if (items == 7)
{
- char* sretn  = 
gh_scm2newstr(scm_list_ref(cp_list,scm_from_int(6)),
-  NULL);
+ char* sretn  = 
scm_to_locale_string(scm_list_ref(cp_list,scm_from_int(6)));
  pgsqlP->retn = atoi(sretn);
+ free (sretn);
}
}
   else
@@ -105,9 +106,9 @@ __postgresql_make_g_db_handle(gdbi_db_ha
  pgsqlP->pgsql = (PGconn*) 
PQsetdbLogin(loc,NULL,NULL,NULL,db,user,pass);
  if (items == 6)
{
- char* sretn  = 
gh_scm2newstr(scm_list_ref(cp_list,scm_from_int(5)),
-  NULL);
+ char* sretn  = 
scm_to_locale_string(scm_list_ref(cp_list,scm_from_int(5)));
  pgsqlP->retn = atoi(sretn);
+ free (sretn);
}
}
 
@@ -139,7 +140,7 @@ __postgresql_make_g_db_handle(gdbi_db_ha
 
   if(PQstatus(pgsqlP->pgsql) == CONNECTION_BAD)
{
- dbh->status = (SCM) scm_cons(scm_from_int(1),
+ dbh->status = scm_cons(scm_from_int(1),
   
scm_from_locale_string(PQerrorMessage(pgsqlP->pgsql)));
  PQfinish(pgsqlP->pgsql);
  pgsqlP->pgsql = NULL;
@@ -151,7 +152,7 @@ __postgresql_make_g_db_handle(gdbi_db_ha
   else
{
  /* todo: error msg to be translated */
- dbh->status = (SCM) scm_cons(scm_from_int(0),
+ dbh->status = scm_cons(scm_from_int(0),
   scm_from_locale_string("db connected"));
  dbh->db_info = pgsqlP;
  dbh->closed = SCM_BOOL_F;
@@ -161,7 +162,7 @@ __postgresql_make_g_db_handle(gdbi_db_ha
   else
 {
   /* todo: error msg to be translated */
-  dbh->status = (SCM) scm_cons(scm_from_int(1),
+  dbh->status = scm_cons(scm_from_int(1),
   scm_from_locale_string("invalid connection 
string"));
   dbh->db_info = NULL;
   dbh->closed = SCM_BOOL_T;
@@ -181,14 +182,14 @@ __postgresql_close_g_db_handle(gdbi_db_h
   if (pgsqlP == NULL)
 {
   /* todo: error msg to be translated */
-  dbh->status = (SCM) scm_cons(scm_from_int(1),
+  dbh->status = scm_cons(scm_from_int(1),
   scm_from_locale_str

[PATCH 12/12] Guile-DBD-postgres: Crash in GC

2008-09-19 Thread Linas Vepstas


Fix a serious bug which results in a crash in the GC. The problem
is that the DBI free routine ill call the close routine, which will
call this routine, which tries to alloc new SCM cells. But one must
not alloc while the garbage collector is runing. Soo.. A previous
patch added a flag to indicate that we're in the GC. If this flag
is set, then avoid doing the cell allocs.

Signed-off-by: Linas Vepstas <[EMAIL PROTECTED]>

---
 src/guile-dbd-postgresql.c |   14 ++
 1 file changed, 10 insertions(+), 4 deletions(-)

Index: guile-dbd-postgresql-2.0.0/src/guile-dbd-postgresql.c
===
--- guile-dbd-postgresql-2.0.0.orig/src/guile-dbd-postgresql.c  2008-09-16 
19:57:34.0 -0500
+++ guile-dbd-postgresql-2.0.0/src/guile-dbd-postgresql.c   2008-09-16 
20:05:25.0 -0500
@@ -181,6 +181,7 @@ __postgresql_close_g_db_handle(gdbi_db_h
   gdbi_pgsql_ds_t* pgsqlP = (gdbi_pgsql_ds_t*)dbh->db_info;  
   if (pgsqlP == NULL)
 {
+  if (dbh->in_free) return; /* don't scm anything if in GC */
   /* todo: error msg to be translated */
   dbh->status = scm_cons(scm_from_int(1),
   scm_from_locale_string("dbd info not 
found"));
@@ -188,9 +189,12 @@ __postgresql_close_g_db_handle(gdbi_db_h
 }
   else if (pgsqlP->pgsql == NULL)
 {
-  /* todo: error msg to be translated */
-  dbh->status = scm_cons(scm_from_int(1),
-  scm_from_locale_string("dbi connection 
already closed"));
+  if (0 == dbh->in_free)
+{
+  /* todo: error msg to be translated */
+  dbh->status = scm_cons(scm_from_int(1),
+  scm_from_locale_string("dbi connection 
already closed"));
+}
   free(dbh->db_info);
   dbh->db_info = NULL;
   dbh->closed = SCM_BOOL_T;
@@ -207,8 +211,10 @@ __postgresql_close_g_db_handle(gdbi_db_h
   free(dbh->db_info);
   dbh->db_info = NULL;
 
-  /* todo: error msg to be translated */
   dbh->closed = SCM_BOOL_T;
+
+  if (dbh->in_free) return; /* don't scm anything if in GC */
+  /* todo: error msg to be translated */
   dbh->status = scm_cons(scm_from_int(0),
   scm_from_locale_string("dbi closed"));
   return;


signature.asc
Description: Digital signature


project page

2008-09-19 Thread tantalum

hello

i think guiles project page could need at least 2 small changes.

1
replace the link 'anonymous cvs' under 'getting guile' with one to the 
more up to date page,

this one: http://www.gnu.org/software/guile/repository.html

2
that page says to use 'git-clone', which does not exist on my system, 
only 'git clone' works.





Re: PATCH [0/12]: Guile-DBI and Guile-DBD-Postgres

2008-09-19 Thread Mike Gran
- Original Message 
> From: Linas Vepstas <[EMAIL PROTECTED]>
> 
> Hi,
> 
> Below follows a series of 12 patches against Guile-DBI and DBD-Postgres.
> 

Linus, thank you for doing this.

-Mike Gran




Re: project page

2008-09-19 Thread Ludovic Courtès
Hi,

tantalum <[EMAIL PROTECTED]> writes:

> 1
> replace the link 'anonymous cvs' under 'getting guile' with one to the
> more up to date page,
> this one: http://www.gnu.org/software/guile/repository.html
>
> 2
> that page says to use 'git-clone', which does not exist on my system,
> only 'git clone' works.

This is now fixed, thanks!

Ludo'.





Re: PATCH [0/12]: Guile-DBI and Guile-DBD-Postgres

2008-09-19 Thread Neil Jerram
2008/9/19 Linas Vepstas <[EMAIL PROTECTED]>:
>
> I'm posting here -- although there used to be guile-dbi-user and 
> guile-dbi-devel
> mailing lists, these had no subscribers, and quickly filled with spam, as
> evidenced by their mail archives. I've applied to get an account on gna.org
> to post the patches there, but its been a week, and my account application
> still hasn't gone through :-( It also appears that the original maintainer,
> Maurizio Boriani, is not responding to email. Bummer.

Can anyone provide firm evidence regarding whether guile-dbi is now
maintained or unmaintained?

If it is unmaintained, I guess we could consider merging it into the
core Guile distribution.  Any thoughts on that?

Also, can anyone provide a summary of all the DB-related libraries for
Guile?  I believe there's guile-pg, and guile-sqlite, but (i) there
could be others I've forgotten, and (ii) it would be great if someone
could summarize how they differ / overlap / compare with each other.

> The patches fix a variety of different crashes and hangs, and also fix
> problems with missing data (e.g. for a query with N records, only N-1
> were being returned -- bad news when N=1)

Cool, thanks.  If it turns out to make sense to pull guile-dbi into
core Guile, I guess we'll review and incorporate these patches at that
time.

Regards,
 Neil




Re: PATCH [0/12]: Guile-DBI and Guile-DBD-Postgres

2008-09-19 Thread Greg Troxel

  Also, can anyone provide a summary of all the DB-related libraries for
  Guile?  I believe there's guile-pg, and guile-sqlite, but (i) there
  could be others I've forgotten, and (ii) it would be great if someone
  could summarize how they differ / overlap / compare with each other.

I am familiar with guile-pg.  It used to be on sourceforge, and was
unmaintained, and then ttn took it over and has done a lot of work on
it.  Last I checked guile-pg only supported guile through 1.6 due to it
using hte load-module-from-.so feature removed in 1.8, but ttn has said
that he'd take patches to make guile-pg work with 1.8+.

There is ttn's guile-gdbm: http://www.gnuvola.org/software/guile-gdbm/

There is no guile-dbi package in pkgsrc.

I dimly remember a pg-guile which was BSD licensed but have not heard
anything about it in years.


pgp1p3DHLcgd6.pgp
Description: PGP signature


Re: PATCH [0/12]: Guile-DBI and Guile-DBD-Postgres

2008-09-19 Thread Greg Troxel

  Also, can anyone provide a summary of all the DB-related libraries for
  Guile?  I believe there's guile-pg, and guile-sqlite, but (i) there
  could be others I've forgotten, and (ii) it would be great if someone
  could summarize how they differ / overlap / compare with each other.

guile-pg has really nice support for converting postgresql types to and
From scheme types, and you can register custom converters.  So it's much
beyond just being able to run query strings and get string answers.  I
have the impression that it's implementation is tied to pg.

IMHO the right thing would be to use the type mapping part of guile-pg
with a DBI sort of back end to go to various databases.


pgpu9IsYGo5hu.pgp
Description: PGP signature


Re: PATCH [0/12]: Guile-DBI and Guile-DBD-Postgres

2008-09-19 Thread Linas Vepstas
2008/9/19 Greg Troxel <[EMAIL PROTECTED]>:
>
> guile-pg has really nice support for converting postgresql types to and
> From scheme types,

? I would be surprised if any database interface returned a
string, when the database column was declared an int,
so I don't quite understand this ...

> and you can register custom converters.

This could be interesting. Different databases have all
sorts of crazy column formats (23 different types of dates,
money amounts, "binary large objects" etc),  and clearly
guile-dbi doesn't have this.  Its a fairly small/low-brow
package.

> have the impression that it's implementation is tied to pg.

I didn't even look at guile-pg, because I know that some of
the users of my code will insist on mysql.  So I had to be
agnostic.

--linas