mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
setting the stage for non-file URL's
git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@3409 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
@@ -114,9 +114,8 @@ show_file_error (GNCFileIOError io_error, const char *newfile)
|
||||
/* ======================================================== */
|
||||
|
||||
static gboolean
|
||||
show_book_error(GNCBook *book, const char *newfile)
|
||||
show_book_error(GNCBook *book, const char *newfile, int norr)
|
||||
{
|
||||
int norr = gnc_book_get_error (book);
|
||||
gboolean uh_oh = FALSE;
|
||||
char *buf = NULL;
|
||||
|
||||
@@ -249,10 +248,11 @@ gncPostFileOpen (const char * filename)
|
||||
gboolean uh_oh = FALSE;
|
||||
AccountGroup *new_group;
|
||||
char * newfile;
|
||||
int norr = 0;
|
||||
|
||||
if (!filename) return;
|
||||
|
||||
newfile = xaccResolveFilePath (filename);
|
||||
newfile = xaccResolveURL (filename);
|
||||
if (!newfile)
|
||||
{
|
||||
char *buf = g_strdup_printf (file_not_found_msg(), filename);
|
||||
@@ -277,16 +277,46 @@ gncPostFileOpen (const char * filename)
|
||||
gnc_set_busy_cursor (NULL);
|
||||
xaccLogDisable ();
|
||||
new_group = NULL;
|
||||
if (gnc_book_begin_file (new_book, newfile, gncLockFailHandler))
|
||||
|
||||
/* hack alert -- there has got to be a simpler way of dealing with
|
||||
* errors than this spaghetti code! I beleive that this would simplify
|
||||
* a whole lot if all functions returned void, and one *always* used
|
||||
* try-throw semantics, instead of this hodge-podge of testing
|
||||
* return values. -- linas jan 2001
|
||||
*/
|
||||
if (gnc_book_begin (new_book, newfile, FALSE))
|
||||
{
|
||||
if (gnc_book_load (new_book))
|
||||
new_group = gnc_book_get_group (new_book);
|
||||
if (gnc_book_load (new_book))
|
||||
{
|
||||
new_group = gnc_book_get_group (new_book);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
norr = gnc_book_get_error (new_book);
|
||||
/* if file appears to be locked, ask the user ... */
|
||||
if (EBUSY == norr)
|
||||
{
|
||||
norr = 0;
|
||||
if (gncLockFailHandler (newfile))
|
||||
{
|
||||
/* user told us to ignore locks. So ignore them. */
|
||||
if (gnc_book_begin (new_book, newfile, TRUE))
|
||||
{
|
||||
if (gnc_book_load (new_book))
|
||||
{
|
||||
new_group = gnc_book_get_group (new_book);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
xaccLogEnable ();
|
||||
gnc_unset_busy_cursor (NULL);
|
||||
|
||||
/* check for book errors, put up appropriate dialog */
|
||||
uh_oh = show_book_error (new_book, newfile);
|
||||
if (!norr) norr = gnc_book_get_error (new_book);
|
||||
uh_oh = show_book_error (new_book, newfile, norr);
|
||||
|
||||
if (!uh_oh)
|
||||
{
|
||||
@@ -338,7 +368,6 @@ gncPostFileOpen (const char * filename)
|
||||
current_book = new_book;
|
||||
|
||||
xaccLogEnable();
|
||||
|
||||
gnc_engine_resume_events ();
|
||||
gnc_gui_refresh_all ();
|
||||
|
||||
@@ -475,6 +504,7 @@ gncFileSaveAs (void)
|
||||
char *newfile;
|
||||
const char *oldfile;
|
||||
gboolean uh_oh = FALSE;
|
||||
int norr = 0;
|
||||
|
||||
filename = fileBox(_("Save"), "*.gnc", NULL);
|
||||
if (!filename) return;
|
||||
@@ -482,7 +512,7 @@ gncFileSaveAs (void)
|
||||
/* Check to see if the user specified the same file as the current
|
||||
* file. If so, then just do that, instead of the below, which
|
||||
* assumes a truly new name was given. */
|
||||
newfile = xaccResolveFilePath (filename);
|
||||
newfile = xaccResolveURL (filename);
|
||||
if (!newfile)
|
||||
{
|
||||
char *buf = g_strdup_printf (file_not_found_msg(), filename);
|
||||
@@ -508,11 +538,24 @@ gncFileSaveAs (void)
|
||||
* switchover is not something we want to keep in a journal. */
|
||||
xaccLogDisable ();
|
||||
new_book = gnc_book_new ();
|
||||
gnc_book_begin_file (new_book, newfile, gncLockFailHandler);
|
||||
gnc_book_begin (new_book, newfile, FALSE);
|
||||
|
||||
norr = gnc_book_get_error (new_book);
|
||||
/* if file appears to be locked, ask the user ... */
|
||||
if (EBUSY == norr)
|
||||
{
|
||||
norr = 0;
|
||||
if (gncLockFailHandler (newfile))
|
||||
{
|
||||
/* user told us to ignore locks. So ignore them. */
|
||||
gnc_book_begin (new_book, newfile, TRUE);
|
||||
}
|
||||
}
|
||||
xaccLogEnable ();
|
||||
|
||||
/* check for session errors (e.g. file locked by another user) */
|
||||
uh_oh = show_book_error (new_book, newfile);
|
||||
if (!norr) norr = gnc_book_get_error (new_book);
|
||||
uh_oh = show_book_error (new_book, newfile, norr);
|
||||
|
||||
/* No check for file errors since we didn't read a file... */
|
||||
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
#include "gnc-book.h"
|
||||
#include "gnc-engine-util.h"
|
||||
|
||||
static short module = MOD_IO;
|
||||
|
||||
struct _gnc_book
|
||||
{
|
||||
@@ -175,9 +176,12 @@ gnc_book_get_file_path (GNCBook *book)
|
||||
/* ============================================================== */
|
||||
|
||||
gboolean
|
||||
gnc_book_begin (GNCBook *book, const char * book_id)
|
||||
gnc_book_begin (GNCBook *book, const char * book_id, gboolean ignore_lock)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (!book) return FALSE;
|
||||
ENTER (" book-id=%s\n", book_id);
|
||||
|
||||
/* clear the error condition of previous errors */
|
||||
book->errtype = 0;
|
||||
@@ -198,14 +202,35 @@ gnc_book_begin (GNCBook *book, const char * book_id)
|
||||
}
|
||||
|
||||
/* check to see if this is a type we know how to handle */
|
||||
if (strncmp(book_id, "file:", 5) != 0)
|
||||
if (!strncmp(book_id, "file:", 5))
|
||||
{
|
||||
/* add 5 to space past 'file:' */
|
||||
rc = gnc_book_begin_file (book, book_id + 5, ignore_lock);
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (!strncmp(book_id, "http://", 7))
|
||||
{
|
||||
book->errtype = ENOSYS;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* add 5 to space past 'file:' */
|
||||
return gnc_book_begin_file (book, book_id + 5, NULL);
|
||||
if (!strncmp(book_id, "https://", 8))
|
||||
{
|
||||
book->errtype = ENOSYS;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!strncmp(book_id, "postgres://", 11))
|
||||
{
|
||||
book->errtype = ENOSYS;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/* otherwise, lets just assume its a file. */
|
||||
rc = gnc_book_begin_file (book, book_id, ignore_lock);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* ============================================================== */
|
||||
@@ -317,9 +342,10 @@ gnc_book_get_file_lock (GNCBook *book)
|
||||
|
||||
gboolean
|
||||
gnc_book_begin_file (GNCBook *book, const char * filefrag,
|
||||
GNCBookLockFailHandler handler)
|
||||
gboolean ignore_lock)
|
||||
{
|
||||
if (!book) return FALSE;
|
||||
ENTER ("filefrag=%s\n", filefrag);
|
||||
|
||||
/* clear the error condition of previous errors */
|
||||
book->errtype = 0;
|
||||
@@ -358,17 +384,16 @@ gnc_book_begin_file (GNCBook *book, const char * filefrag,
|
||||
|
||||
book->lockfile = g_strconcat(book->fullpath, ".LCK", NULL);
|
||||
|
||||
if (!gnc_book_get_file_lock (book))
|
||||
if (!ignore_lock && !gnc_book_get_file_lock (book))
|
||||
{
|
||||
if (!handler || !handler (book->fullpath))
|
||||
{
|
||||
g_free (book->book_id); book->book_id = NULL;
|
||||
g_free (book->fullpath); book->fullpath = NULL;
|
||||
g_free (book->lockfile); book->lockfile = NULL;
|
||||
return FALSE;
|
||||
}
|
||||
book->errtype = EBUSY;
|
||||
g_free (book->book_id); book->book_id = NULL;
|
||||
g_free (book->fullpath); book->fullpath = NULL;
|
||||
g_free (book->lockfile); book->lockfile = NULL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
LEAVE ("\n");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -386,6 +411,7 @@ gnc_book_load (GNCBook *book)
|
||||
if (!book) return FALSE;
|
||||
if (!book->book_id) return FALSE;
|
||||
|
||||
ENTER ("book_id=%s\n", book->book_id);
|
||||
if (strncmp(book->book_id, "file:", 5) == 0)
|
||||
{
|
||||
/* file: */
|
||||
@@ -415,6 +441,7 @@ gnc_book_load (GNCBook *book)
|
||||
|
||||
xaccGroupScrubSplits (book->topgroup);
|
||||
|
||||
LEAVE("\n");
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
@@ -561,7 +588,6 @@ MakeHomeDir (void)
|
||||
}
|
||||
|
||||
/* ============================================================== */
|
||||
|
||||
/* XXX hack alert -- we should be yanking this out of some config file */
|
||||
static char * searchpaths[] =
|
||||
{
|
||||
@@ -569,7 +595,7 @@ static char * searchpaths[] =
|
||||
NULL,
|
||||
};
|
||||
|
||||
char *
|
||||
static char *
|
||||
xaccResolveFilePath (const char * filefrag)
|
||||
{
|
||||
struct stat statbuf;
|
||||
@@ -580,6 +606,7 @@ xaccResolveFilePath (const char * filefrag)
|
||||
|
||||
/* seriously invalid */
|
||||
if (!filefrag) return NULL;
|
||||
ENTER ("filefrag=%s\n", filefrag);
|
||||
|
||||
/* ---------------------------------------------------- */
|
||||
/* OK, now we try to find or build an absolute file path */
|
||||
@@ -692,4 +719,35 @@ xaccResolveFilePath (const char * filefrag)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* ============================================================== */
|
||||
|
||||
char *
|
||||
xaccResolveURL (const char * pathfrag)
|
||||
{
|
||||
/* seriously invalid */
|
||||
if (!pathfrag) return NULL;
|
||||
|
||||
/* At this stage of checking, URL's are always, by definition,
|
||||
* resolved. If there's an error connecting, we'll find out later.
|
||||
*/
|
||||
if (!strncmp (pathfrag, "http://", 7)) {
|
||||
return (char *) pathfrag;
|
||||
}
|
||||
|
||||
if (!strncmp (pathfrag, "https://", 8)) {
|
||||
return (char *) pathfrag;
|
||||
}
|
||||
|
||||
if (!strncmp (pathfrag, "postgres://", 11)) {
|
||||
PERR ("not implemented")
|
||||
return (char *) pathfrag;
|
||||
}
|
||||
|
||||
if (!strncmp (pathfrag, "file:", 5)) {
|
||||
return (xaccResolveFilePath (pathfrag+5));
|
||||
}
|
||||
|
||||
return (xaccResolveFilePath (pathfrag));
|
||||
}
|
||||
|
||||
/* ==================== END OF FILE ================== */
|
||||
|
||||
@@ -60,9 +60,6 @@
|
||||
/** TYPEDEFS ********************************************************/
|
||||
typedef struct _gnc_book GNCBook;
|
||||
|
||||
typedef gboolean (*GNCBookLockFailHandler) (const char *file);
|
||||
|
||||
|
||||
/** PROTOTYPES ******************************************************/
|
||||
|
||||
GNCBook * gnc_book_new (void);
|
||||
@@ -83,19 +80,19 @@ void gnc_book_destroy (GNCBook *book);
|
||||
* then a lock will be obtained and the function returns TRUE. Otherwise
|
||||
* the function returns FALSE.
|
||||
*/
|
||||
gboolean gnc_book_begin (GNCBook *book, const char * book_id);
|
||||
gboolean gnc_book_begin (GNCBook *book, const char * book_id,
|
||||
gboolean ignore_lock);
|
||||
|
||||
/* The gnc_book_begin_file() routine is identical to the gnc_book_begin()
|
||||
* routine, except that the argument is a filename (i.e. the five
|
||||
* letters "file:" should not be prepended) and there is an additional
|
||||
* function argument. This function is called if gnc_book_begin_file
|
||||
* fails to obtain a lock for the file. If it returns TRUE, the file
|
||||
* is loaded anyway. If it returns FALSE, or the handler is NULL, a
|
||||
* failed lock attempt will abort the load. The lock fail handler is
|
||||
* passed the filename of the data file being loaded.
|
||||
* routine, except that the argument is assumed to be a filename, not
|
||||
* a URL.
|
||||
*
|
||||
* The 'ignore_lock' argument, if set to TRUE, will cause this routine
|
||||
* to ignore any file locks that it finds. If set to FALSE, then
|
||||
* file locks will be tested and obeyed.
|
||||
*/
|
||||
gboolean gnc_book_begin_file (GNCBook *book, const char * filename,
|
||||
GNCBookLockFailHandler handler);
|
||||
gboolean ignore_lock);
|
||||
|
||||
/* The gnc_book_load() method loads the data associated with the book.
|
||||
* The function returns TRUE on success.
|
||||
@@ -166,5 +163,6 @@ void gnc_book_end (GNCBook *book);
|
||||
* used.
|
||||
*/
|
||||
char * xaccResolveFilePath (const char * filefrag);
|
||||
char * xaccResolveURL (const char * pathfrag);
|
||||
|
||||
#endif /* __GNC_BOOK_H__ */
|
||||
|
||||
@@ -23,11 +23,11 @@ main (int argc, char *argv[])
|
||||
char * fake_argv[] = {"hello2", 0};
|
||||
GNCBook *book;
|
||||
AccountGroup *grp;
|
||||
Query *q;
|
||||
GList *split_list, *node;
|
||||
Query *q, *qq;
|
||||
GList *split_list, *sl2, *node;
|
||||
Split *s;
|
||||
char *bufp;
|
||||
int i, rc, sz;
|
||||
int i, ii, rc, sz;
|
||||
|
||||
|
||||
/* intitialize the engine */
|
||||
@@ -64,8 +64,8 @@ main (int argc, char *argv[])
|
||||
|
||||
/* Get everything between some random dates */
|
||||
/* In real life, we would use a query as specified by the user */
|
||||
xaccQueryAddDateMatch (q, TRUE, 1982, 2, 28,
|
||||
FALSE, 2010, 10, 16,
|
||||
xaccQueryAddDateMatch (q, TRUE, 28, 2, 1982,
|
||||
FALSE, 16, 10, 2010,
|
||||
QUERY_OR);
|
||||
|
||||
split_list = xaccQueryGetSplits (q);
|
||||
@@ -79,7 +79,19 @@ main (int argc, char *argv[])
|
||||
}
|
||||
|
||||
gncxml_write_query_to_buf(q, &bufp, &sz);
|
||||
qq = gncxml_read_query (bufp, sz);
|
||||
xaccQuerySetMaxSplits (qq, 30);
|
||||
xaccQuerySetGroup (qq, grp);
|
||||
sl2 = xaccQueryGetSplits (qq);
|
||||
|
||||
/* count number of splits */
|
||||
ii = 0;
|
||||
for (node = sl2; node; node = node->next)
|
||||
{
|
||||
s = node->data;
|
||||
ii++;
|
||||
}
|
||||
|
||||
/* print the HTTP header */
|
||||
printf ("HTTP/1.1 200 OK\n");
|
||||
printf ("Content-Type: text/xml\n");
|
||||
@@ -88,10 +100,12 @@ main (int argc, char *argv[])
|
||||
|
||||
printf ("%s", bufp);
|
||||
|
||||
free (bufp);
|
||||
printf (" its %d and %d \n", i, ii);
|
||||
|
||||
free (bufp);
|
||||
xaccFreeQuery (q);
|
||||
|
||||
|
||||
bookerrexit:
|
||||
/* close the book */
|
||||
gnc_book_destroy (book);
|
||||
|
||||
Reference in New Issue
Block a user