Login | Register
My pages Projects Community openCollabNet

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Catacomb] namespaces in values and [Fwd: [Catacomb-checkins] CVS: catacomb dav_repos.h dbms.c dbms.h mod_dav_repos.c repos.c]



FYI, this is checked into a branch so that people can bang on it, check it out, comment, complain, etc. Currently it passes the "basic" Litmus tests, I'm not familiar with the new tests in Litmus 0.9 so I am unsure if the later test failures are common with the main line Catacomb.

Also note that I submitted a bug fix with the dav/main module...See http://nagoya.apache.org/bugzilla/show_bug.cgi?id=14969 that will change how dav/main talks to Catacomb. I haven't heard from anyone from the Apache project (Greg Stein?) as to whether they confirm that this is indeed a bug and should be fixed. I may send a patch to dav/main and dav/fs illustrating this fix.

Send me comments/concerns/criticisms. I'm not terribly well versed in the versioning code so I likely overlooked something. ;^}
--- Begin Message ---
cknight     03/04/02 11:12:57

  Modified:    .        Tag: stream_dbms dav_repos.h dbms.c dbms.h
                        mod_dav_repos.c repos.c
  Log:
  added stream abstraction into dbms.c and added functionality to store files
  externally
  
  Revision  Changes    Path
  No                   revision
  
  
  
  
  No                   revision
  
  
  
  
  1.9.4.1   +2 -0      catacomb/dav_repos.h
  
  Index: dav_repos.h
  ===================================================================
  RCS file: /home/cvs/catacomb/dav_repos.h,v
  retrieving revision 1.9
  retrieving revision 1.9.4.1
  diff -u -r1.9 -r1.9.4.1
  --- dav_repos.h	17 Oct 2002 04:33:34 -0000	1.9
  +++ dav_repos.h	2 Apr 2003 19:12:56 -0000	1.9.4.1
  @@ -96,6 +96,7 @@
       const char *db_id;
       const char *db_pass;
       const char *tmp_dir;
  +    const char *file_dir;
   
       apr_table_t *d_params;	/* per-directory DAV config parameters */
   
  @@ -112,6 +113,7 @@
       const char *db_id;
       const char *db_pass;
       const char *tmp_dir;
  +    const char *file_dir;
   
       apr_table_t *d_params;	/* per-directory DAV config parameters */
   
  
  
  
  1.30.2.1  +318 -5    catacomb/dbms.c
  
  Index: dbms.c
  ===================================================================
  RCS file: /home/cvs/catacomb/dbms.c,v
  retrieving revision 1.30
  retrieving revision 1.30.2.1
  diff -u -r1.30 -r1.30.2.1
  --- dbms.c	31 Dec 2002 20:39:41 -0000	1.30
  +++ dbms.c	2 Apr 2003 19:12:56 -0000	1.30.2.1
  @@ -105,6 +105,33 @@
   }
   
   /**
  + * Given a particular resource (with it's serialno, type, etc) return a
  + * path into the filesystem for storage. Change the algorithm to change
  + * the layout of how data is stored in the fs. *path is set to NULL if
  + * there is no file_dir defined (as the root dir.)
  + */
  +static dav_error *generate_path(char **path, apr_pool_t *pool,
  +	const char *file_dir, const long serialno, const int version) {
  +    char *dirpath;
  +
  +    TRACE();
  +
  +    DBG2("Serial number: %ld version: %d", serialno, version);
  +    dirpath = apr_psprintf(pool, "%s/%ld/%ld",
  +    	file_dir, serialno % 100l, serialno / 100l);
  +    ap_no2slash(dirpath);
  +
  +    // should I check to see if dirpath exists already or can I assume
  +    // apr_dir_make_recursive is smart 'nuf?
  +    if (apr_dir_make_recursive(dirpath, APR_OS_DEFAULT, pool) != APR_SUCCESS)
  +    	return dav_new_error(pool, HTTP_INTERNAL_SERVER_ERROR, 0,
  +	    "Unable to create directory for storage.");
  +
  +    *path = apr_psprintf(pool, "%s/%ld-%d", dirpath, serialno, version);
  +    return NULL;
  +}
  +
  +/**
    * Connects to and opens the database
    * @param d DB connection struct containing the user, password, and DB name
    * @return 0 indicating success
  @@ -387,9 +414,10 @@
       apr_pool_t *pool = db_r->p;
       dav_repos_query *q = NULL;
   
  -
       TRACE();
       
  +    if (d->file_dir) {
  +    }
       /*Create the select command to get the textcontent by serialNO */
       if (db_r->type == DAV_RESOURCE_TYPE_VERSION) { /* Version_resource */
           if (db_r->istext == 1)	/*It is a regular file */
  @@ -772,6 +800,7 @@
   {
       apr_pool_t *pool = r->p;
       dav_repos_query *q = NULL;
  +    char *path = NULL;
   
       TRACE();
   
  @@ -822,9 +851,13 @@
   	
           dbms_query_destroy(q); 
       }
  +
  +    if (!generate_path (&path, r->p, d->file_dir,
  +	    r->serialno, r->version))
  +        apr_file_remove(path, r->p);
  +    // note, this does nothing to remove directories that are now empty.
       
       return 0;
  -
   }				/*End of dbms_remove_resource */
   
   /**
  @@ -863,7 +896,7 @@
   }				/*End of db_insert_property */
   
   /**
  - * Set the value of a dead property on a resrouce identified by serialno
  + * Set the value of a dead property on a resource identified by serialno
    * @param d DB connection struct
    * @param r Identified the resource to set the property on
    * @param pr The dead property to set
  @@ -1054,6 +1087,8 @@
       int depth_diff = 0;
       apr_pool_t *pool = r_src->p;
       dav_repos_query *q = NULL;
  +    char *src_fn = NULL, *des_fn = NULL;
  +    long des_serialno = 0l;
   
       TRACE();
   
  @@ -1113,6 +1148,30 @@
               dbms_query_destroy(q); 
   	    return -1;
   	}
  +        dbms_query_destroy(q);
  +
  +	des_serialno = mysql_insert_id((MYSQL *) (&(d->db)));
  +
  +    	if (generate_path (&src_fn, r_src->p, d->file_dir,
  +	    r_src->serialno, r_src->version)) {
  +	    db_error_message(r_src->p, &(d->db),
  +		"Error generating source path.");
  +	    return -1;
  +	}
  +	// new resource is version 0 by default
  +    	if (generate_path (&des_fn, r_src->p, d->file_dir,
  +	    des_serialno, 0)) {
  +	    db_error_message(r_src->p, &(d->db),
  +		"Error generating destination path.");
  +	    return -1;
  +	}
  +	DBG2("copying file %s to %s", src_fn, des_fn);
  +	if (apr_file_copy(src_fn, des_fn, APR_OS_DEFAULT, r_src->p)
  +		!= APR_SUCCESS) {
  +	    db_error_message(r_src->p, &(d->db),
  +		"Unable to copy file");
  +	    return -1;
  +	}
       }				/*End of if it is a regular file */
       else if (r_src->resourcetype == 1) {
   	/*It is a collection(directory) */
  @@ -1165,9 +1224,50 @@
               dbms_query_destroy(q); 
   	    return -1;
   	}
  +	dbms_query_destroy(q);
  +
  +	q = dbms_prepare(pool, &(d->db), "select s.serialno, d.serialno from dasl_resource s, dasl_resource d where s.uri like ? and d.uri like ? and d.resourcetype = 0 and substring(s.uri, ?) = substring(d.uri, ?)");
  +	dbms_set_string(q, 1, apr_psprintf(r_src->p, "%s/%%", r_src->uri));
  +	dbms_set_string(q, 2, apr_psprintf(r_src->p, "%s/%%", r_des->uri));
  +	dbms_set_int(q, 3, strlen(r_src->uri) + 1);
  +	dbms_set_int(q, 4, strlen(r_des->uri) + 1);
  +	if (!(dbms_select(q))) {
  +	    db_error_message(r_src->p, &(d->db), "Error retrieving dest files");
  +            dbms_query_destroy(q);
  +	    return -1;
  +	}
  +        while (dbms_next(q)) {
  +	    char *src_fn = NULL, *des_fn = NULL;
  +	    long src_serialno = dbms_get_int(q, 1);
  +	    long des_serialno = dbms_get_int(q, 2);
  +
  +	    if (generate_path (&src_fn, r_src->p, d->file_dir,
  +		    src_serialno, 0)) {
  +		db_error_message(r_src->p, &(d->db),
  +		    "Error generating source path.");
  +		dbms_query_destroy(q); 
  +		return -1;
  +	    }
  +
  +	    if (generate_path (&des_fn, r_src->p, d->file_dir,
  +		    des_serialno, 0)) {
  +		db_error_message(r_src->p, &(d->db),
  +		    "Error generating destination path.");
  +		dbms_query_destroy(q); 
  +		return -1;
  +	    }
  +
  +	    if (apr_file_copy(src_fn, des_fn, APR_OS_DEFAULT, r_src->p)
  +		    != APR_SUCCESS) {
  +		db_error_message(r_src->p, &(d->db),
  +		    "Unable to copy file");
  +		dbms_query_destroy(q); 
  +		return -1;
  +	    }
  +	}
  +        dbms_query_destroy(q); 
       }				/*End of else if */
   
  -    dbms_query_destroy(q); 
       return 0;
   }				/*End of dbms_copy_resource */
   
  @@ -2199,7 +2299,7 @@
       }
       dbms_query_destroy(q);
   
  -    /* Duplicate the records in the temporary table 
  +    /* Duplicate the record in the temporary table 
   	   to the table version_resource */
       q = dbms_prepare(pool, &(db->db), "INSERT into version_resource "
   		"SELECT * from tmp_resforvcr");
  @@ -2210,6 +2310,24 @@
       	     HTTP_INTERNAL_SERVER_ERROR, 0, "DBMS Error");
       }
   
  +    if (db->file_dir) { // create a version of the file
  +	char *src_fn = NULL, *des_fn = NULL;
  +    	if (generate_path(&src_fn, db_r->p, db->file_dir,
  +		db_r->serialno, 0))
  +	    return dav_new_error(pool,
  +		HTTP_INTERNAL_SERVER_ERROR, 0, "Unable to generate src fn");
  +
  +    	if (generate_path(&des_fn, db_r->p, db->file_dir,
  +		db_r->serialno, version))
  +	    return dav_new_error(pool,
  +		HTTP_INTERNAL_SERVER_ERROR, 0, "Unable to generate src fn");
  +
  +	if (apr_file_copy(src_fn, des_fn, APR_OS_DEFAULT, db_r->p)
  +		!= APR_SUCCESS)
  +	    return dav_new_error(pool,
  +		HTTP_INTERNAL_SERVER_ERROR, 0, "Unable to copy file.");
  +    }
  +
       dbms_query_destroy(q); 
       
       /*Copy the record in the 'dasl_property' table for 'version_property' table */
  @@ -2388,4 +2506,199 @@
       return NULL;
   }
   
  +struct dbms_stream {
  +    dav_repos_db *db;
  +    dav_repos_resource *db_r;
  +    apr_file_t *file;
  +    char *path;
  +    int temporary;
  +};
  +
  +dav_error *dbms_open_stream(dav_repos_db *db, dav_repos_resource *db_r,
  +	dbms_stream **stream, dav_stream_mode mode) {
  +    dav_error *err = NULL;
  +    dbms_stream *s = NULL;
  +    dav_repos_query *q = NULL;
  +
  +    TRACE();
  +
  +    s = apr_pcalloc(db_r->p, sizeof(*s));
  +    s->db = db;
  +    s->db_r = db_r;
  +
  +    // only way to get a serialno is to add a row (or convert to using a
  +    // sequence-generator
  +    if (!db_r->serialno) {
  +	long serialno;
  +	if (db_insert_resource(db, db_r, &serialno))
  +	    return dav_new_error(db_r->p, HTTP_INTERNAL_SERVER_ERROR, 0,
  +		"Unable to add resource to the database");
  +	db_r->serialno = serialno;
  +    }
  +
  +    if (db->file_dir) { // or should this check be in generate_path?
  +    	if ((err = generate_path(&(s->path), db_r->p, db->file_dir,
  +		db_r->serialno, db_r->version))) {
  +	    q = dbms_prepare(db_r->p, &(db->db), "DELETE FROM dasl_resource "
  +		"WHERE serialno=?");
  +	    dbms_set_int(q, 1, db_r->serialno);
  +	    dbms_execute(q);
  +	    dbms_query_destroy(q);
  +	}
  +    }
  +
  +    if (!s->path) {
  +	s->temporary = 1;
  +	s->path = apr_psprintf(db_r->p, "%s/catacomb-%ld-%d",
  +		db->tmp_dir, db_r->serialno, db_r->version);
  +	ap_no2slash(s->path);
  +    }
  +
  +    DBG1("path: %s", s->path);
  +
  +    switch(mode) {
  +    	case DAV_MODE_WRITE_TRUNC:
  +    	case DAV_MODE_WRITE_SEEKABLE:
  +	    if (apr_file_open(&(s->file), s->path,
  +		    APR_CREATE | APR_WRITE | APR_TRUNCATE | APR_BINARY | APR_BUFFERED,
  +		    APR_OS_DEFAULT, db_r->p) != APR_SUCCESS)
  +		err = dav_new_error(db_r->p, HTTP_INTERNAL_SERVER_ERROR, 0,
  +		    "Unable to open file for write");
  +	    break;
  +    	default: // any possibility of this happening?
  +	    if (apr_file_open(&(s->file), s->path,
  +		    APR_READ | APR_BINARY | APR_BUFFERED,
  +		    APR_OS_DEFAULT, db_r->p) != APR_SUCCESS)
  +		err = dav_new_error(db_r->p, HTTP_INTERNAL_SERVER_ERROR, 0,
  +		    "Unable to open file for read");
  +	    break;
  +    }
  +
  +    if (err) {
  +	    q = dbms_prepare(db_r->p, &(db->db), "DELETE FROM dasl_resource "
  +		"WHERE serialno=?");
  +	    dbms_set_int(q, 1, db_r->serialno);
  +	    dbms_execute(q);
  +	    dbms_query_destroy(q);
  +	    return err;
  +    }
  +
  +    *stream = s;
  +    return NULL;
  +}
  +
  +dav_error *dbms_close_stream(dbms_stream *stream, int commit) {
  +    // TODO: merge dbms_write_content into this
  +    dav_error *err = NULL;
  +    dav_repos_query *q = NULL;
  +
  +    TRACE();
  +
  +    if (commit) {
  +    	if (apr_file_close(stream->file) == APR_SUCCESS) {
  +	    if (stream->temporary) {
  +		if (dbms_write_content(stream->db, stream->db_r,
  +			stream->path)) {
  +		    err = dav_new_error(stream->db_r->p,
  +			HTTP_INTERNAL_SERVER_ERROR, 0, "Unable to close file!");
  +		}
  +	    }
  +	} else err = dav_new_error(stream->db_r->p,
  +	    HTTP_INTERNAL_SERVER_ERROR, 0, "Unable to close file!");
  +    }
  +
  +    if (!commit || stream->temporary) {
  +	q = dbms_prepare(stream->db_r->p, &(stream->db->db), "DELETE FROM dasl_resource "
  +	    "WHERE serialno=?");
  +	dbms_set_int(q, 1, stream->db_r->serialno);
  +	dbms_execute(q);
  +	dbms_query_destroy(q);
  +
  +	if (apr_file_remove(stream->path, stream->db_r->p) != APR_SUCCESS)
  +	    err = dav_new_error(stream->db_r->p, HTTP_INTERNAL_SERVER_ERROR,
  +	        0, "Unable to remove temporary file.");
  +    }
  +    return err;
  +}
  +
  +dav_error *dbms_write_stream(dbms_stream *stream, const void *buf,
  +	const apr_size_t bufsize) {
  +    apr_size_t s = bufsize;
  +    TRACE();
  +
  +    DBG1("stream = %x", stream);
  +    DBG1("stream->file = %x", stream->file);
  +    if (apr_file_write(stream->file, buf, &s) != APR_SUCCESS)
  +        return dav_new_error(stream->db_r->p, HTTP_INTERNAL_SERVER_ERROR, 0,
  +	    "Unable to write to file.");
  +    if (s != bufsize)
  +        return dav_new_error(stream->db_r->p, HTTP_INTERNAL_SERVER_ERROR, 0,
  +	    "Did not write all contents.");
  +    return NULL;
  +}
  +
  +dav_error *dbms_seek_stream(dbms_stream *stream, const apr_size_t pos) {
  +    apr_size_t p = pos;
  +    TRACE();
  +
  +    if (apr_file_write(stream->file, APR_SET, &p) != APR_SUCCESS)
  +        return dav_new_error(stream->db_r->p, HTTP_INTERNAL_SERVER_ERROR, 0,
  +	    "Unable to seek in file.");
  +    if (p != pos)
  +        return dav_new_error(stream->db_r->p, HTTP_INTERNAL_SERVER_ERROR, 0,
  +	    "Seek resulted in different position.");
  +    return NULL;
  +}
   
  +dav_error *dbms_deliver(dav_repos_db *db, dav_repos_resource *db_r,
  +	ap_filter_t *output) {
  +    dav_error *err = NULL;
  +    char *filename = NULL;
  +    apr_file_t *fd;
  +    apr_bucket_brigade *bb;
  +    apr_bucket *bkt;
  +
  +    if (db->file_dir) {
  +        if (err = generate_path(&filename, db_r->p, db->file_dir,
  +	    db_r->serialno, db_r->version)) return err;
  +    } else {
  +	/* Anyway we need to make random filename */
  +	filename = apr_psprintf(db_r->p, "%s/dav_repos_deliver_XXXXXX",
  +	    db->tmp_dir);
  +	if (mktemp(filename) == NULL) {
  +	    return dav_new_error(db_r->p, HTTP_INTERNAL_SERVER_ERROR, 0,
  +		"An error occurred while opening a resource name.");
  +	}
  +
  +	/* get file from data base */
  +	if (dbms_read_content(db, db_r, filename) != 0) {
  +	    return dav_new_error(db_r->p, HTTP_INTERNAL_SERVER_ERROR, 0,
  +		"An error occurred while getting a resource name.");
  +	}
  +    }
  +
  +DBG1("TESTCDK: %s", filename);
  +    if (apr_file_open(&fd, filename, APR_READ | APR_BINARY, 0,
  +	    db_r->p) != APR_SUCCESS) {
  +	return dav_new_error(db_r->p, HTTP_FORBIDDEN, 0,
  +			     "File permissions deny server access.");
  +    }
  +
  +    bb = apr_brigade_create(db_r->p, output->c->bucket_alloc);
  +
  +    /* ### this does not handle large files. but this is test code anyway */
  +    bkt = apr_bucket_file_create(fd, 0,
  +				 (apr_size_t) db_r->getcontentlength,
  +				 db_r->p, output->c->bucket_alloc);
  +    APR_BRIGADE_INSERT_TAIL(bb, bkt);
  +
  +    bkt = apr_bucket_eos_create(output->c->bucket_alloc);
  +    APR_BRIGADE_INSERT_TAIL(bb, bkt);
  +
  +    if (ap_pass_brigade(output, bb) != APR_SUCCESS)
  +	err = dav_new_error(db_r->p, HTTP_FORBIDDEN, 0,
  +			     "Could not write contents to filter.");
  +
  +    if (!db->file_dir) apr_file_remove(filename, db_r->p); //ignore the error?
  +    return err;
  +}
  
  
  
  1.11.4.1  +21 -9     catacomb/dbms.h
  
  Index: dbms.h
  ===================================================================
  RCS file: /home/cvs/catacomb/dbms.h,v
  retrieving revision 1.11
  retrieving revision 1.11.4.1
  diff -u -r1.11 -r1.11.4.1
  --- dbms.h	17 Oct 2002 04:33:34 -0000	1.11
  +++ dbms.h	2 Apr 2003 19:12:56 -0000	1.11.4.1
  @@ -88,6 +88,7 @@
   };
   
   typedef struct dav_repos_property dav_repos_property;
  +typedef struct dav_repos_stream dav_repos_stream;
   
   /*
   ** DBMS data transfer interface
  @@ -155,16 +156,14 @@
       request_rec *rec;           /* Save rec */
   };
   
  +typedef struct dbms_stream dbms_stream;
  +
   /* define the dav_stream structure for our use */
  -struct dav_stream
  -{
  +struct dav_stream {
       apr_pool_t *p;
  -    apr_file_t *f;
  -    const dav_resource *resource;
  -    const char *pathname;	/* we may need to remove it at close time */
  -    int test_flag;		/* test flag */
  -    int is_write;
  -    unsigned long data_read;   /* Keep size of read */
  +    dbms_stream *stream;
  +    dav_repos_db *db;
  +    dav_repos_resource *db_r;
   };
   
   
  @@ -286,5 +285,18 @@
   dav_error * dbms_create_vr(const dav_repos_db * db, dav_repos_resource * db_r, int version);
   dav_error * dbms_get_vrs(const dav_repos_db * db, dav_repos_resource * db_r,
                          dav_repos_resource ** vrs);
  -		       
  +
  +dav_error *dbms_open_stream(dav_repos_db *db, dav_repos_resource *db_r,
  +	dbms_stream **stream, dav_stream_mode mode);
  +
  +dav_error *dbms_close_stream(dbms_stream *stream, int commit);
  +
  +dav_error *dbms_write_stream(dbms_stream *stream, const void *buf,
  +	const apr_size_t bufsize);
  +
  +dav_error *dbms_seek_stream(dbms_stream *stream, const apr_size_t pos);
  +
  +dav_error *dbms_deliver(dav_repos_db *db, dav_repos_resource *db_r,
  +    ap_filter_t *output);
  +
   #endif
  
  
  
  1.7.4.1   +15 -0     catacomb/mod_dav_repos.c
  
  Index: mod_dav_repos.c
  ===================================================================
  RCS file: /home/cvs/catacomb/mod_dav_repos.c,v
  retrieving revision 1.7
  retrieving revision 1.7.4.1
  diff -u -r1.7 -r1.7.4.1
  --- mod_dav_repos.c	19 Nov 2002 20:48:45 -0000	1.7
  +++ mod_dav_repos.c	2 Apr 2003 19:12:56 -0000	1.7.4.1
  @@ -134,6 +134,7 @@
       newconf->db_id = INHERIT_VALUE(parent, child, db_id);
       newconf->db_pass = INHERIT_VALUE(parent, child, db_pass);
       newconf->tmp_dir = INHERIT_VALUE(parent, child, tmp_dir);
  +    newconf->file_dir = INHERIT_VALUE(parent, child, file_dir);
   
       return newconf;
   }
  @@ -198,6 +199,17 @@
   
   }
   
  +static const char *dav_repos_file_dir_cmd(cmd_parms * cmd, void *config,
  +					 const char *arg1)
  +{
  +    dav_repos_server_conf *conf =
  +	ap_get_module_config(cmd->server->module_config,
  +			     &dav_repos_module);
  +
  +    conf->file_dir = apr_pstrdup(cmd->pool, arg1);
  +    return NULL;
  +
  +}
   
   static const command_rec dav_repos_cmds[] = {
       /* per directory/location */
  @@ -218,6 +230,9 @@
   
       AP_INIT_TAKE1("DavDBMSTmpDir", dav_repos_tmp_dir_cmd, NULL, RSRC_CONF,
   		  "specify the MYSQL_TMP_DIR for a directory or location"),
  +
  +    AP_INIT_TAKE1("DavDBMSFileDir", dav_repos_file_dir_cmd, NULL, RSRC_CONF,
  +		  "specify the directory for permanent external storage"),
   
       {NULL}
   };
  
  
  
  1.19.2.1  +19 -157   catacomb/repos.c
  
  Index: repos.c
  ===================================================================
  RCS file: /home/cvs/catacomb/repos.c,v
  retrieving revision 1.19
  retrieving revision 1.19.2.1
  diff -u -r1.19 -r1.19.2.1
  --- repos.c	31 Dec 2002 20:39:41 -0000	1.19
  +++ repos.c	2 Apr 2003 19:12:56 -0000	1.19.2.1
  @@ -470,17 +470,15 @@
       return strcmp(res1->uri, parent_uri) == 0;
   }
   
  -/** FIXME: */
  -mode_t umask(mode_t mask);
  -
  +/**
  + * Note that this is only called for write (PUT).
  + */
   static dav_error *dav_repos_open_stream(const dav_resource * resource,
   					dav_stream_mode mode,
   					dav_stream ** stream)
   {
       dav_error *err;
  -    char *filename;
       const char *slength;
  -    apr_int32_t flags;
       dav_resource *parent;
       request_rec *subrec;
       request_rec *rec = resource->info->rec;
  @@ -488,31 +486,10 @@
       dav_stream *ds = apr_pcalloc(pool, sizeof(*ds));
       dav_repos_db *db = resource->info->db;
       dav_repos_resource *db_r = (dav_repos_resource *) resource->info->db_r;
  -    
   
       TRACE();
   
  -    /* Anyway we need to make random filename */
  -    filename = apr_psprintf(pool, "%s/dav_repos_open_XXXXXX", db->tmp_dir);
  -    if (mktemp(filename) == NULL) {
  -	return dav_new_error(pool, HTTP_INTERNAL_SERVER_ERROR, 0,
  -			     "An error occurred while opening a resource name.");
  -    }
  -
       switch (mode) {
  -    default:
  -	DBG0("READ MODE");
  -	flags = APR_READ | APR_BINARY;
  -	ds->is_write = 0;
  -
  -	/* get file from database */
  -	if (dbms_read_content(db, db_r, filename) != 0) {
  -	    return dav_new_error(pool, HTTP_INTERNAL_SERVER_ERROR, 0,
  -				 "An error occurred while getting a resource name.");
  -	}
  -
  -	break;
  -
       case DAV_MODE_WRITE_TRUNC:
       case DAV_MODE_WRITE_SEEKABLE:
   	DBG0("WRITE MODE");
  @@ -537,9 +514,6 @@
   	    return dav_new_error(pool, HTTP_CONFLICT, 0,
   				 "No parent collection.");
   	}
  -	
  -	ds->is_write = 1;
  -	flags = APR_WRITE | APR_CREATE | APR_TRUNCATE | APR_BINARY;
   
   	/* make time */
   	db_r->getlastmodified = apr_time_now();
  @@ -551,6 +525,7 @@
   	slength = apr_table_get(rec->headers_in, "Content-Length");
   	db_r->getcontentlength = slength ? atol(slength) : 0;
   	
  +	// TODO: check to see if this works.
   	/* First , try to get the content-type from client */
   	if ( rec->content_type ) {
   	    db_r->getcontenttype = apr_pstrdup(pool, rec->content_type);
  @@ -558,7 +533,6 @@
   	else {
   	    /* perform a "GET" on the resource's URI (note that the resource
   	       may not correspond to the current request!). */
  -	    DBG1("FILENAME:%s",  rec->filename);
   	    subrec = ap_sub_req_lookup_uri(rec->uri, rec, NULL);
   	    
   	    if (subrec && subrec->content_type) {
  @@ -575,120 +549,47 @@
   	break;
       }
   
  -    ds->p = pool;
  -    ds->pathname = resource->info->pathname;
  -    ds->resource = resource;
  -
  -    /* FIXME: Should I include 
  -       #include <sys/types.h>
  -       #include <sys/stat.h>
  -       What about non Unix system??
  -     */
  -    /* set umask for new file permission, 644 */
  -
  -    umask(022);
  -
  -    /* For mysql upload. it should be a 644 mode */
  -    if (apr_file_open(&ds->f, filename, flags, APR_OS_DEFAULT, pool) !=
  -	APR_SUCCESS) {
  -	return dav_new_error(pool, HTTP_INTERNAL_SERVER_ERROR, 0,
  -			     "An error occurred while opening a resource.");
  -    }
  +    ds->db = db;
  +    ds->db_r = db_r;
  +    if ((err = dbms_open_stream(db, db_r, &(ds->stream), mode))) return err;
   
       *stream = ds;
       return NULL;
   }
   
   
  -static dav_error *dav_repos_close_stream(dav_stream * stream, int commit)
  -{
  -    const char *filename;
  -    const dav_resource *resource = stream->resource;
  -    dav_repos_db *db = resource->info->db;
  -    dav_repos_resource *db_r = (dav_repos_resource *) resource->info->db_r;
  -    
  +static dav_error *dav_repos_close_stream(dav_stream * stream, int commit) {
       TRACE();
   
  -    /* get file name */
  -    apr_file_name_get(&filename, stream->f);
  -    apr_file_close(stream->f);
  -
  -    if (stream->is_write) {
  -	
  -	/* Different size */
  -	if (db_r->getcontentlength != stream->data_read) {
  -	    
  -	    DBG2("CONTENT: %ld   Write: %ld",
  -		 db_r->getcontentlength, stream->data_read);
  -	    
  -	    /* Error handling */
  -	    return dav_new_error(stream->p, HTTP_BAD_REQUEST, 0,
  -				 "Content-length and data length are diffrent");
  -	}
  -	
  +    if (commit) {
   	/* Let's save db info here */
  -	if ((db_r->serialno = dbms_set_property(db, db_r)) == -1) {
  +	if ((stream->db_r->serialno
  +		= dbms_set_property(stream->db, stream->db_r)) == -1) {
  +	    dbms_close_stream(stream->stream, 0);
  +
   	    /* Error handling */
   	    return dav_new_error(stream->p, HTTP_INTERNAL_SERVER_ERROR, 0,
  -				 "[ MYSQL database error ].");
  +		"database error");
   	}
  -	
  -	/* save file to DB */
  -	dbms_write_content(db, db_r, filename);
       }
   
  -    /* remove temprary file */
  -    if (apr_file_remove(filename, stream->p) != APR_SUCCESS) {
  -	return dav_new_error(stream->p, HTTP_INTERNAL_SERVER_ERROR, 0,
  -			     "There was a problem removing (rolling "
  -			     "back) the resource "
  -			     "when it was being closed.");
  -
  -    }
  -    return NULL;
  +    return dbms_close_stream(stream->stream, commit);
   }
   
   static dav_error *dav_repos_write_stream(dav_stream * stream, const void *buf,
   					 apr_size_t bufsize)
   {
  -
  -    apr_status_t status;
  -
       TRACE();
   
  -    /* Keep counting the size */
  -    stream->data_read += bufsize;
  -
  -    status = apr_file_write_full(stream->f, buf, bufsize, NULL);
  -
  -    if (APR_STATUS_IS_ENOSPC(status)) {
  -	return dav_new_error(stream->p, HTTP_INSUFFICIENT_STORAGE, 0,
  -			     "There is not enough storage to write to "
  -			     "this resource.");
  -    }
  -    else if (status != APR_SUCCESS) {
  -	/* ### use something besides 500? */
  -	return dav_new_error(stream->p, HTTP_INTERNAL_SERVER_ERROR, 0,
  -			     "An error occurred while writing to a "
  -			     "resource.");
  -    }
  -    return NULL;
  +    return dbms_write_stream(stream->stream, buf, bufsize);
   }
   
   static dav_error *dav_repos_seek_stream(dav_stream * stream,
   					apr_off_t abs_pos)
   {
       TRACE();
  -
  -    if (apr_file_seek(stream->f, APR_SET, &abs_pos) != APR_SUCCESS) {
  -	/* ### should check whether apr_file_seek set abs_pos was set to the
  -	 * correct position? */
  -	/* ### use something besides 500? */
  -	return dav_new_error(stream->p, HTTP_INTERNAL_SERVER_ERROR, 0,
  -			     "Could not seek to specified position in the "
  -			     "resource.");
  -    }
  -    return NULL;
  +    
  +    return dbms_seek_stream(stream->stream, abs_pos);
   }
   
   static dav_error *dav_repos_set_headers(request_rec * r,
  @@ -732,14 +633,12 @@
   {
       apr_pool_t *pool = resource->pool;
       apr_bucket_brigade *bb;
  -    apr_file_t *fd;
       apr_status_t status;
       apr_bucket *bkt;
   
       dav_repos_db *db = resource->info->db;
       dav_repos_resource *tmp_r;
       dav_repos_resource *db_r = (dav_repos_resource *) resource->info->db_r;
  -    char *filename;
   
       TRACE();
   
  @@ -807,44 +706,7 @@
   #endif
       }
   
  -    /* Anyway we need to make random filename */
  -    filename = apr_psprintf(pool, "%s/dav_repos_deliver_XXXXXX", db->tmp_dir);
  -    if (mktemp(filename) == NULL) {
  -	return dav_new_error(pool, HTTP_INTERNAL_SERVER_ERROR, 0,
  -			     "An error occurred while opening a resource name.");
  -    }
  -
  -    /* get file from data base */
  -    if (dbms_read_content(db, db_r, filename) != 0) {
  -	return dav_new_error(pool, HTTP_INTERNAL_SERVER_ERROR, 0,
  -			     "An error occurred while getting a resource name.");
  -    }
  -
  -    /* open temparory file */
  -    if ((status = apr_file_open(&fd, filename,
  -				APR_READ | APR_BINARY, 0,
  -				pool)) != APR_SUCCESS) {
  -	return dav_new_error(pool, HTTP_FORBIDDEN, 0,
  -			     "File permissions deny server access.");
  -    }
  -
  -    bb = apr_brigade_create(pool, output->c->bucket_alloc);
  -
  -    /* ### this does not handle large files. but this is test code anyway */
  -    bkt = apr_bucket_file_create(fd, 0,
  -				 (apr_size_t) db_r->getcontentlength,
  -				 pool, output->c->bucket_alloc);
  -    APR_BRIGADE_INSERT_TAIL(bb, bkt);
  -
  -    bkt = apr_bucket_eos_create(output->c->bucket_alloc);
  -    APR_BRIGADE_INSERT_TAIL(bb, bkt);
  -
  -    if ((status = ap_pass_brigade(output, bb)) != APR_SUCCESS) {
  -	return dav_new_error(pool, HTTP_FORBIDDEN, 0,
  -			     "Could not write contents to filter.");
  -    }
  -
  -    return NULL;
  +    return dbms_deliver(db, db_r, output);
   }
   
   static dav_error *dav_repos_create_collection(dav_resource * resource)
  
  
  
_______________________________________________
Catacomb-checkins mailing list
Catacomb-checkins@webdav.org
http://mailman.webdav.org/mailman/listinfo/catacomb-checkins

--- End Message ---