Logo Search packages:      
Sourcecode: bibledit version File versions  Download package

projectutilsold1.cpp

/*
** Copyright (C) 2003-2006 Teus Benschop.
**  
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**  
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
**  
** 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.
**  
*/


#include "libraries.h"
#include "utilities.h"
#include "projectutilsold1.h"
#include "directories.h"
#include "gwrappers.h"
#include "shell.h"
#include "sqlite3.h"
#include "books.h"
#include "vacuum.h"
#include "bible.h"
#include "progresswindow.h"
#include "import.h"


vector<ustring> projects_old1_get_all ()
// Gets sorted list of all projects.
{
  vector<ustring> projects;
  ReadDirectories rd (directories_get_projects (), "", "");
  for (unsigned int i = 0; i < rd.directories.size (); i++)
  {
    if (project_old1_exists (rd.directories[i])) {
      projects.push_back (rd.directories[i]);
    }
  }
  sort (projects.begin(), projects.end());
  return projects;
}


ustring project_old1_filename (const ustring& project)
{
  return gw_build_filename (directories_get_projects (), project, "data.sql1");
}


bool project_old1_exists (const ustring& project)
{
  return g_file_test (project_old1_filename(project).c_str(), G_FILE_TEST_IS_REGULAR);
}


void project_old1_create (const ustring& project)
{
  // Create project directory.
  create_directory (gw_build_filename (directories_get_projects (), project));
  // Some variables.  
  sqlite3 *db;
  int rc;
  char *error = NULL;
  try
  {
    // Connect to the database.
    rc = sqlite3_open (project_old1_filename (project).c_str (), &db);
    if (rc) {
      throw runtime_error (sqlite3_errmsg(db));
    }
    // Variable.
    char * sql;
    // Create the usfm data table. 
    // It holds the USFM data.
    sql = g_strdup_printf ("create table usfm (book text, chapter integer, verse text, sequence integer, usfm text);");
    rc = sqlite3_exec (db, sql, NULL, NULL, &error);
    if (rc) {
      throw runtime_error (sqlite3_errmsg(db));
    }
    // Create the synchronization table.
    // It stores the state of the synchronization between internal database and external USFM files.
    sql = g_strdup_printf ("create table sync (book text, updated integer, filename text, filetime integer, filesize integer);");
    rc = sqlite3_exec (db, sql, NULL, NULL, &error);
    if (rc) {
      throw runtime_error (sqlite3_errmsg(db));
    }
    // Create the index table.
    // Information to keep the index up-to-date.
    sql = g_strdup_printf ("create table idx (timestamp integer);");
    rc = sqlite3_exec (db, sql, NULL, NULL, &error);
    if (rc) {
      throw runtime_error (sqlite3_errmsg(db));
    }
    // Free memory.
    g_free (sql);
  }
  catch (exception & ex)
  {
    gw_critical (ex.what ());
  }
  // Close connection.
  sqlite3_close (db);
  // Create books data.
  books_create (project);
}


void project_old1_store_book (const ustring& project, const ustring& book, CategorizeChapterVerse& ccv)
{
  // Some variables.  
  sqlite3 *db;
  int rc;
  char *error = NULL;
  try
  {
    // Connect to the database.
    rc = sqlite3_open (project_old1_filename (project).c_str (), &db);
    if (rc) {
      throw runtime_error (sqlite3_errmsg(db));
    }
    // Variable.
    char * sql;
    // Begin transaction;
    rc = sqlite3_exec (db, "begin;", NULL, NULL, &error);
    if (rc) {
      throw runtime_error (sqlite3_errmsg(db));
    }
    // Delete the whole book's data. 
    sql = g_strdup_printf ("delete from usfm where book = '%s';", book.c_str());
    rc = sqlite3_exec (db, sql, NULL, NULL, &error);
    if (rc) {
      throw runtime_error (sqlite3_errmsg(db));
    }
    // Store the new data.
    for (unsigned int i = 0; i < ccv.line.size(); i++) {
      ustring text = double_apostrophy (ccv.line[i]);
      sql = g_strdup_printf ("insert into usfm values ('%s', %d, '%s', %d, '%s')", 
        book.c_str(), ccv.chapter[i], ccv.verse[i].c_str(), ccv.sequence[i], text.c_str());
      rc = sqlite3_exec (db, sql, NULL, NULL, &error);
      if (rc) {
        throw runtime_error (sqlite3_errmsg(db));
      }
    }    
    // Commit the changes.
    rc = sqlite3_exec (db, "commit;", NULL, NULL, &error);
    if (rc) {
      throw runtime_error (sqlite3_errmsg(db));
    }
    // Free memory.
    g_free (sql);
  }
  catch (exception & ex)
  {
    gw_critical (ex.what ());
  }
  // Close connection.
  sqlite3_close (db);
  // Timestamp.
  unsigned int timestamp = time (0);
  project_old1_update_book (project, book, timestamp);
}


void project_old1_update_book (const ustring& project, const ustring& book, unsigned int timestamp)
// Sets flags/variables that indicate this book has been updated.
{
  // Some variables.  
  sqlite3 *db;
  int rc;
  char *error = NULL;
  try
  {
    // Connect to the database.
    rc = sqlite3_open (project_old1_filename (project).c_str (), &db);
    if (rc) {
      throw runtime_error (sqlite3_errmsg(db));
    }
    // Variable.
    char * sql;
    // Delete the timestamp.
    sql = g_strdup_printf ("delete from idx;");
    rc = sqlite3_exec (db, sql, NULL, NULL, &error);
    if (rc) {
      throw runtime_error (sqlite3_errmsg(db));
    }
    // Store timestamp
    sql = g_strdup_printf ("insert into idx values (%d)", timestamp);
    rc = sqlite3_exec (db, sql, NULL, NULL, &error);
    if (rc) {
      throw runtime_error (sqlite3_errmsg(db));
    }
    // Set updated flag for synchronization.
    sql = g_strdup_printf ("update sync set updated = %d where book = '%s';", 1, book.c_str());
    rc = sqlite3_exec (db, sql, NULL, NULL, &error);
    if (rc) {
      throw runtime_error (sqlite3_errmsg(db));
    }    
    // Free memory.
    g_free (sql);
  }
  catch (exception & ex)
  {
    gw_critical (ex.what ());
  }
  // Close connection.
  sqlite3_close (db);
}


ustring project_old1_retrieve_verse_extended (const ustring& project, const ustring& book, unsigned int chapter, const ustring& verse)
/*
This function will be called when the exact verse was not found in the text.
E.g. it requested verse "1-2", and the text happens to have verse "1" and
verse "2", but not the combined verse. This extended function handles these
and similar cases.
This is roughly the strategy to be followed to get the right verse.
- The requested verse may have the a or b suffix, e.g. verse 4a.
- Therefore use a system of "half" verses.
- Create a vector with all the half verses requested.
- Create sets with all the half verses that are in a particular verse, e.g.
  v 1-2 will contain 1a and 1b, and v 3-5 contains 3a, 3b, 4a, 4b, 5a, 5b.
- Take any set that contains any of the requested half verses and get the 
  text(s) of the verse(s).
*/
{
  // Holds the verse text we will retrieve.
  ustring line;
  
  // Get the requested half-verses.
  vector<int> requested_verses = verses_encode (verse);

  // Get all verses in this chapter.
  vector <ustring> all_verses = project_old1_get_verses (project, book, chapter);

  // Get the sets with the half-verses of each available verse in this chapter.
  vector< set<int> > available_verses_sets;
  for (unsigned int i = 0; i < all_verses.size (); i++) {
    vector<int> verses_v = verses_encode (all_verses[i]);
    set<int> verses_s (verses_v.begin(), verses_v.end());
    available_verses_sets.push_back (verses_s);
  }

  // Retrieve any verse that relates to the verse we look for.
  for (unsigned int a = 0; a < available_verses_sets.size(); a++) {
    for (unsigned int r = 0; r < requested_verses.size(); r++) {
      if (available_verses_sets[a].find (requested_verses[r]) != available_verses_sets[a].end()) {
        if (!line.empty ()) 
          line.append ("\n");
        line.append (project_old1_retrieve_verse (project, book, chapter, all_verses[a]));
      }
    }
  }

  // Return whatever we got.
  return line;   
}


ustring project_old1_retrieve_verse (const ustring& project, const ustring& book, unsigned int chapter, const ustring& verse)
{
  // Holds the retrieved verse.
  ustring line;
  // Database variables.  
  sqlite3 *db;
  int rc;
  char *error = NULL;
  try
  {
    // Open database.
    rc = sqlite3_open(project_old1_filename (project).c_str (), &db);
    if (rc) {
      throw runtime_error (sqlite3_errmsg(db));
    }
    sqlite3_busy_timeout (db, 1000);
    // Read the verse.    
    SqliteReader sqlitereader (0);
    char * sql;
    sql = g_strdup_printf ("select usfm from usfm where book = '%s' and chapter = %d and verse = '%s';", book.c_str(), chapter, verse.c_str());
    rc = sqlite3_exec(db, sql, sqlitereader.callback, &sqlitereader, &error);
    g_free (sql);
    if (rc != SQLITE_OK) {
      throw runtime_error (error);
    }
    if ((sqlitereader.ustring0.size() > 0)) {
      line = sqlitereader.ustring0[0];
    }
  }
  catch (exception & ex)
  {
    gw_critical (ex.what ());
  }
  // Close connection.  
  sqlite3_close (db);
  // If the verse was not found, use extended retrieval mechanism to get it.
  if (line.empty()) {
    line = project_old1_retrieve_verse_extended (project, book, chapter, verse);
  }
  // Return the data.
  return line;
}


vector<ustring> project_old1_retrieve_chapter (const ustring& project, const ustring& book, unsigned int chapter)
{
  // Holds the chapter.
  vector<ustring> result;
  // Database variables.  
  sqlite3 *db;
  int rc;
  char *error = NULL;
  try
  {
    // Open database.
    rc = sqlite3_open(project_old1_filename (project).c_str (), &db);
    if (rc) {
      throw runtime_error (sqlite3_errmsg(db));
    }
    sqlite3_busy_timeout (db, 1000);
    // Read the chapter including the sequence of the verses.
    SqliteReader sqlitereader (0);
    char * sql;
    sql = g_strdup_printf ("select usfm, sequence from usfm where book = '%s' and chapter = %d;", book.c_str(), chapter);
    rc = sqlite3_exec(db, sql, sqlitereader.callback, &sqlitereader, &error);
    g_free (sql);
    if (rc != SQLITE_OK) {
      throw runtime_error (error);
    }
    vector<ustring> lines (sqlitereader.ustring0.begin(), sqlitereader.ustring0.end());
    // Verses have been stored in the database before. 
    // We cannot be sure however that the verses will be retrieved in the order
    // they were stored. Some factors cause that.
    // For example, while replacing it is possible that only one verse gets 
    // stored. 
    // A sequence variable is used. The verses are sorted on that sequence,
    // so they will be put in the right order.
    vector <unsigned int> sequence;
    for (unsigned int i = 0; i < sqlitereader.ustring1.size(); i++) {
      sequence.push_back (convert_to_int (sqlitereader.ustring1[i]));
    }
    quick_sort (sequence, lines, 0, sequence.size());
    // Make separate lines from it.
    for (unsigned int i = 0; i < lines.size(); i++) {
      ParseLine parseline (lines[i]);
      for (unsigned int i2 = 0; i2 < parseline.lines.size(); i2++) {
        result.push_back (parseline.lines[i2]);
      }
    }
  }
  catch (exception & ex)
  {
    gw_critical (ex.what ());
  }
  // Close connection.  
  sqlite3_close (db);
  // Return the chapter.
  return result;
}


vector<ustring> project_old1_get_books (const ustring& project)
// Gives all books in this project.
// Reorders the book according to settings made by user.
{
  // Holds the books.
  vector <ustring> books;
  // Database variables.  
  sqlite3 *db;
  int rc;
  char *error = NULL;
  try
  {
    // Open database.
    rc = sqlite3_open(project_old1_filename (project).c_str (), &db);
    if (rc) {
      throw runtime_error (sqlite3_errmsg(db));
    }
    sqlite3_busy_timeout (db, 1000);
    // Read the books.
    SqliteReader sqlitereader (0);
    char * sql;
    sql = g_strdup_printf ("select distinct book from usfm;");
    rc = sqlite3_exec(db, sql, sqlitereader.callback, &sqlitereader, &error);
    g_free (sql);
    if (rc != SQLITE_OK) {
      throw runtime_error (error);
    }
    books.assign (sqlitereader.ustring0.begin(), sqlitereader.ustring0.end());
  }
  catch (exception & ex)
  {
    gw_critical (ex.what ());
  }
  // Close connection.  
  sqlite3_close (db);
  // Reorder the books
  books_order (project, books);
  // Return books.
  return books;
}


vector<unsigned int> project_old1_get_chapters (const ustring& project, const ustring& book)
// Gives all chapters in a book of a project.
{
  vector <unsigned int> chapters;
  sqlite3 *db;
  int rc;
  char *error = NULL;
  try
  {
    rc = sqlite3_open(project_old1_filename (project).c_str (), &db);
    if (rc) {
      throw runtime_error (sqlite3_errmsg(db));
    }
    sqlite3_busy_timeout (db, 1000);
    SqliteReader sqlitereader (0);
    char * sql;
    sql = g_strdup_printf ("select distinct chapter from usfm where book = '%s';", book.c_str());
    rc = sqlite3_exec(db, sql, sqlitereader.callback, &sqlitereader, &error);
    g_free (sql);
    if (rc != SQLITE_OK) {
      throw runtime_error (error);
    }
    for (unsigned int i = 0; i < sqlitereader.ustring0.size(); i++) {
      chapters.push_back (convert_to_int (sqlitereader.ustring0[i]));
    }
  }
  catch (exception & ex)
  {
    gw_critical (ex.what ());
  }
  sqlite3_close (db);
  sort (chapters.begin(), chapters.end());
  return chapters;
}


vector<ustring> project_old1_get_verses (const ustring& project, const ustring& book, unsigned int chapter)
{
  // Holds the verse numbers.
  vector<ustring> result;
  // Database variables.  
  sqlite3 *db;
  int rc;
  char *error = NULL;
  try
  {
    // Open database.
    rc = sqlite3_open(project_old1_filename (project).c_str (), &db);
    if (rc) {
      throw runtime_error (sqlite3_errmsg(db));
    }
    sqlite3_busy_timeout (db, 1000);
    // Read the verses including the sequence.
    SqliteReader sqlitereader (0);
    char * sql;
    sql = g_strdup_printf ("select verse, sequence from usfm where book = '%s' and chapter = %d;", book.c_str(), chapter);
    rc = sqlite3_exec(db, sql, sqlitereader.callback, &sqlitereader, &error);
    g_free (sql);
    if (rc != SQLITE_OK) {
      throw runtime_error (error);
    }
    result.assign (sqlitereader.ustring0.begin(), sqlitereader.ustring0.end());
    // Sequence for ordering the verses.
    vector <unsigned int> sequence;
    for (unsigned int i = 0; i < sqlitereader.ustring1.size(); i++) {
      sequence.push_back (convert_to_int (sqlitereader.ustring1[i]));
    }
    quick_sort (sequence, result, 0, sequence.size());
  }
  catch (exception & ex)
  {
    gw_critical (ex.what ());
  }
  // Close connection.  
  sqlite3_close (db);
  // Return the verses.
  return result;
}

Generated by  Doxygen 1.6.0   Back to index