Back to index

lightning-sunbird  0.9+nobinonly
Public Member Functions | Public Attributes | Protected Member Functions | Protected Attributes | Private Attributes | Friends
mozSqlConnectionSqlite Class Reference

#include <mozSqlConnectionSqlite.h>

Inheritance diagram for mozSqlConnectionSqlite:
Inheritance graph
[legend]
Collaboration diagram for mozSqlConnectionSqlite:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 mozSqlConnectionSqlite ()
virtual ~mozSqlConnectionSqlite ()
NS_DECL_ISUPPORTS NS_IMETHOD Init (const nsAString &aHost, PRInt32 aPort, const nsAString &aDatabase, const nsAString &aUsername, const nsAString &aPassword)
NS_IMETHOD GetPrimaryKeys (const nsAString &aSchema, const nsAString &aTable, mozISqlResult **_retval)
void init (in AString aHost, in long aPort, in AString aDatabase, in AString aUsername, in AString aPassword)
 Set up the connection.
mozISqlResult executeQuery (in AString aQuery)
 Execute an SQL query synchronously and return the query result.
long executeUpdate (in AString aUpdate)
 Execute an SQL update synchronously and return the number of updated rows.
mozISqlRequest asyncExecuteQuery (in AString aQuery, in nsISupports aContext, in mozISqlRequestObserver aObserver)
 Execute an SQL query asynchronously and return a request.
mozISqlRequest asyncExecuteUpdate (in AString aQuery, in nsISupports aContext, in mozISqlRequestObserver aObserver)
 Execute an SQL update asynchronously and return a request.
void beginTransaction ()
 Begin a transaction.
void commitTransaction ()
 Commit the current transaction.
void rollbackTransaction ()
 Rollback (cancel) the current transaction.
mozISqlResult getPrimaryKeys (in AString aSchema, in AString aTable)
 Return the primary keys of a given table.
NS_IMETHOD Run ()=0
 Defines an entry point for a newly created thread.
void run ()

Public Attributes

NS_DECL_ISUPPORTS
NS_DECL_MOZISQLCONNECTION
friend class 
mozSqlRequest
readonly attribute AString serverVersion
 A string holding the name and/or version info of the database.
readonly attribute AString errorMessage
 The most recent error message.
readonly attribute long lastID
 The ID of the most recently added record.

Protected Member Functions

nsresult Setup ()
virtual nsresult RealExec (const nsAString &aQuery, mozISqlResult **aResult, PRInt32 *aAffectedRows)
virtual nsresult CancelExec ()
virtual nsresult GetIDName (nsAString &aIDName)
nsresult CancelRequest (mozISqlRequest *aRequest)

Protected Attributes

nsString mServerVersion
nsString mErrorMessage
PRInt32 mLastID
PRLockmLock
PRCondVarmCondVar
PRLockmExecLock
nsCOMPtr< nsIThreadmThread
nsCOMArray< mozISqlRequestmRequests
nsCOMPtr< mozISqlRequestmCurrentRequest
PRBool mShutdown
PRBool mWaiting

Private Attributes

sqlite3mConnection
PRInt32 mVersion
PRBool mWritable

Friends

class mozSqlResult

Detailed Description

Definition at line 52 of file mozSqlConnectionSqlite.h.


Constructor & Destructor Documentation

Definition at line 45 of file mozSqlConnectionSqlite.cpp.

Definition at line 50 of file mozSqlConnectionSqlite.cpp.

Here is the call graph for this function:


Member Function Documentation

mozISqlRequest mozISqlConnection::asyncExecuteQuery ( in AString  aQuery,
in nsISupports  aContext,
in mozISqlRequestObserver  aObserver 
) [inherited]

Execute an SQL query asynchronously and return a request.

An observer may be used to track when the query has completed.

Parameters:
aQuerythe SQL string of the query to execute
aContextextra argument that will be passed to the observer
aObserverobserver that will be notified when the query is done
Returns:
a request object
mozISqlRequest mozISqlConnection::asyncExecuteUpdate ( in AString  aQuery,
in nsISupports  aContext,
in mozISqlRequestObserver  aObserver 
) [inherited]

Execute an SQL update asynchronously and return a request.

An observer may be used to track when the query has completed.

Parameters:
aQuerythe SQL string of the update to execute
aContextextra argument that will be passed to the observer
aObserverobserver that will be notified when the update is done
Returns:
a request object

Begin a transaction.

Updates made during the transaction will not be made permanent until it is committed using commitTransaction.

nsresult mozSqlConnectionSqlite::CancelExec ( ) [protected, virtual]

Implements mozSqlConnection.

Definition at line 362 of file mozSqlConnectionSqlite.cpp.

Here is the call graph for this function:

nsresult mozSqlConnection::CancelRequest ( mozISqlRequest aRequest) [protected, inherited]

Definition at line 263 of file mozSqlConnection.cpp.

{
  PR_Lock(mLock);
  if (mCurrentRequest == aRequest)
    CancelExec();
  else {
    if (mRequests.RemoveObject(aRequest))
      ((mozSqlRequest*)aRequest)->mStatus = mozISqlRequest::STATUS_CANCELLED;
  }
  PR_Unlock(mLock);

  return NS_OK;
}

Here is the call graph for this function:

Commit the current transaction.

mozISqlResult mozISqlConnection::executeQuery ( in AString  aQuery) [inherited]

Execute an SQL query synchronously and return the query result.

Parameters:
aQuerythe SQL string of the query to execute
Returns:
the result of the query
long mozISqlConnection::executeUpdate ( in AString  aUpdate) [inherited]

Execute an SQL update synchronously and return the number of updated rows.

Parameters:
aUpdatethe update to execute
Returns:
the result of the query
nsresult mozSqlConnectionSqlite::GetIDName ( nsAString &  aIDName) [protected, virtual]

Implements mozSqlConnection.

Definition at line 375 of file mozSqlConnectionSqlite.cpp.

{
  aIDName.AssignLiteral("OID");
  return NS_OK;
}
NS_IMETHODIMP mozSqlConnectionSqlite::GetPrimaryKeys ( const nsAString &  aSchema,
const nsAString &  aTable,
mozISqlResult **  _retval 
)

Definition at line 125 of file mozSqlConnectionSqlite.cpp.

{
  if (! mConnection)
    return NS_ERROR_NOT_INITIALIZED;
    
  /* the purpose of this all is to get primary keys in a structure used in
   * GetPrimaryKeys() for pgsql. as sqlite3 doesn't allow to do it using a
   * single select query, we have to create it by hand
   * i thought of other variants but this one seems to be the easiest, if you
   * know how to implement GetPrimaryKeys() in a better way, please tell me
   */
  char **r, *errmsg;
  PRInt32 stat, nrow, ncolumn;
  nsAutoString preselect, select1, select2, uni, select, common;
  
  common.AssignLiteral("select NULL as TABLE_SCHEM, '");
  select1.AssignLiteral("' as COLUMN_NAME, ");
  select2.AssignLiteral(" as KEY_SEQ, NULL as PK_NAME");
  uni.AssignLiteral(" UNION ");
  
  // first select: we need it to get the "create table" statement
  preselect.AssignLiteral("select sql from sqlite_master where type='table' and name='");
  if (!aTable.IsEmpty()) {
    preselect.Append(aTable);
    common.Append(aTable);
  }
  else
    return NS_ERROR_FAILURE;
  preselect.Append(NS_LITERAL_STRING("';"));
  common.Append(NS_LITERAL_STRING("' as TABLE_NAME, '"));
  
  stat = sqlite3_get_table(mConnection, NS_ConvertUCS2toUTF8(preselect).get(),
                           &r, &nrow, &ncolumn, &errmsg);
  if (stat != SQLITE_OK) {
    CopyUTF8toUTF16(errmsg, mErrorMessage);
    sqlite3_free_table(r);
    return NS_ERROR_FAILURE;
  }
  
  // now we parse that statement in order to find primary key columns
  nsAutoString aToken = NS_ConvertUTF8toUCS2(nsDependentCString("PRIMARY KEY"));
  nsAutoString aKeyColumn;
  NS_ConvertUTF8toUCS2 buffer(r[1]);
  nsAString::const_iterator start, end, iter, iter2;
  buffer.BeginReading(start);
  buffer.EndReading(end);
  
  if (CaseInsensitiveFindInReadable(aToken, start, end))
    iter = end;
  else
    return NS_ERROR_FAILURE;
  buffer.BeginReading(start);
  buffer.EndReading(end);

  PRInt32 count = 1;
  while (iter != end && (*iter == PRUnichar(' ') || *iter == PRUnichar('\t') ||
         *iter == PRUnichar('\n')))
    ++iter;
  
  // if we have "primary key (colname1, colname2, ...)" we can have multiple
  // columns
  if (*iter == PRUnichar('(')) {
    char str[16];
    ++iter;
    while (iter != end && *iter != PRUnichar(')')) {
      while ((*iter == PRUnichar(' ') || *iter == PRUnichar('\n') ||
             *iter == PRUnichar('\t') || *iter == PRUnichar(',')) &&
             *iter != PRUnichar(')') && iter != end)
        ++iter;
      if (iter != end && *iter != PRUnichar(')')) {
       // we get column names and create a fake select which selects nothing
       if (count > 1)
          select.Append(uni);
        select.Append(common);
        iter2 = iter;
       while (iter2 != end && *iter2 != PRUnichar(',') &&
               *iter2 != PRUnichar(' ') && *iter2 != PRUnichar('\n') &&
               *iter2 != PRUnichar('\t') && *iter2 != PRUnichar(')'))
         ++iter2;
       aKeyColumn = Substring(iter,iter2);
       select.Append(aKeyColumn);
       iter = iter2;
       select.Append(select1);
        PRInt32 i = 0, j, tmp, cnt = count;
        do {
          str[i++] = cnt % 10 + 48;
          str[i] = '\0';
        } while ((cnt /= 10) > 0);
        for (i = 0, j = strlen(str) - 1; i < j; i++, j--) {
         tmp = str[i];
          str[i] = str[j];
          str[j] = tmp;
       }
       select.Append(UTF8ToNewUnicode(nsDependentCString(str)));
       select.Append(select2);
       count++;
      }
    }
  }
  // we have only one primary key column: "colname ... primary key ..."
  else {
    PRInt32 openParenth = 0;
    while (iter != start && (*iter != PRUnichar(',') && openParenth == 0)) {
      if (*iter == PRUnichar(')'))
        openParenth++;
      else if (*iter == PRUnichar('('))
        openParenth--;
      --iter;
    }
    if (iter == start) {
      while (*iter != PRUnichar('(') && iter != end)
        ++iter;
    }
    ++iter;
    while ((*iter == PRUnichar(' ') || *iter == PRUnichar('\n') ||
           *iter == PRUnichar('\t')) && iter != end)
      ++iter;
    select.Append(common);
    iter2 = iter;
    while (iter2 != end && *iter2 != PRUnichar(' ') &&
           *iter2 != PRUnichar('\n') && *iter2 != PRUnichar('\t'))
      ++iter2;
    aKeyColumn = Substring(iter,iter2);
    select.Append(aKeyColumn);
    select.Append(select1);
    select.Append(PRUnichar('1'));
    select.Append(select2);
  }
  select.Append(PRUnichar(';'));
  
  sqlite3_free_table(r);

  /* by this time we have either this select:
   *   select NULL as TABLE_SCHEM, 'table_name' as TABLE_NAME, 'colname1' as
   *   COLUMN_NAME, 1 as KEY_SEQ, NULL as PK_NAME UNION select NULL as
   *   TABLE_SCHEM, 'table_name' as TABLE_NAME, 'colname2' as COLUMN_NAME, 2 as
   *   KEY_SEQ, NULL as PK_NAME ...;
   * or this one:
   *   select NULL as TABLE_SCHEM, 'table_name' as TABLE_NAME, 'colname' as
   *   COLUMN_NAME, 1 as KEY_SEQ, NULL as PK_NAME;
   * anyway, they do not select anything, they just assign the values
   */
  return RealExec(select, _retval, nsnull);
}

Here is the call graph for this function:

mozISqlResult mozISqlConnection::getPrimaryKeys ( in AString  aSchema,
in AString  aTable 
) [inherited]

Return the primary keys of a given table.

Parameters:
aSchemathe schema
aTablethe table name of the keys to retrieve
Returns:
the result which holds the keys
NS_IMETHODIMP mozSqlConnectionSqlite::Init ( const nsAString &  aHost,
PRInt32  aPort,
const nsAString &  aDatabase,
const nsAString &  aUsername,
const nsAString &  aPassword 
)

Definition at line 65 of file mozSqlConnectionSqlite.cpp.

{
  if (mConnection)
    return NS_OK;

  nsAString::const_iterator start;
  nsresult rv;
  nsAutoString path;
  aDatabase.BeginReading(start);

  nsCOMPtr<nsILocalFile> file(do_CreateInstance(NS_LOCAL_FILE_CONTRACTID, &rv));
  if (NS_FAILED(rv))
    return rv;
    
  rv = file->InitWithPath(aDatabase);

  if (rv == NS_ERROR_FILE_UNRECOGNIZED_PATH) {
    nsCOMPtr<nsIProperties> directoryService = do_GetService(
                                               NS_DIRECTORY_SERVICE_CONTRACTID,
                                               &rv);
    if (NS_FAILED(rv))
      return rv;
    rv = directoryService->Get(NS_APP_USER_PROFILE_50_DIR,
                               NS_GET_IID(nsILocalFile),
                               getter_AddRefs(file));
    if (NS_FAILED(rv))
      return rv;
    rv = file->Append(aDatabase);
    if (NS_FAILED(rv))
      return rv;
    file->GetPath(path);
    if (path.IsEmpty())
      return NS_ERROR_FAILURE;
  }
  else if (NS_FAILED(rv))
    return NS_ERROR_FAILURE;
  else
    path = aDatabase;

  PRBool exists;
  rv = file->Exists(&exists);
  if (NS_FAILED(rv))
    return NS_ERROR_FAILURE;
  
  rv = file->IsWritable(&mWritable);
  if (NS_FAILED(rv))
    return NS_ERROR_FAILURE;
       
  rv = sqlite3_open(NS_ConvertUCS2toUTF8(path).get(), &mConnection);
  if (rv != SQLITE_OK)
    return rv;

  return Setup();
}

Here is the call graph for this function:

void mozISqlConnection::init ( in AString  aHost,
in long  aPort,
in AString  aDatabase,
in AString  aUsername,
in AString  aPassword 
) [inherited]

Set up the connection.

This is called by the SQL service. There is no need to call this method directly.

Parameters:
aHostthe host name.
aPortthe port at which the host is listening.
aDatabasethe real database name to connect to.
aUsernamethe username to connect as.
aPasswordthe password to use in authentification phase.
nsresult mozSqlConnectionSqlite::RealExec ( const nsAString &  aQuery,
mozISqlResult **  aResult,
PRInt32 aAffectedRows 
) [protected, virtual]

Implements mozSqlConnection.

Definition at line 306 of file mozSqlConnectionSqlite.cpp.

{
  //sqlite3_changes doesn't reset its count to 0 after selects
  static PRInt32 oldChange = 0;
  
  if (! mConnection)
    return NS_ERROR_NOT_INITIALIZED;

  char **r, *errmsg;
  PRInt32 stat, nrow, ncolumn;

  stat = sqlite3_get_table(mConnection, NS_ConvertUCS2toUTF8(aQuery).get(), &r,
                           &nrow, &ncolumn, &errmsg);
  PRInt32 changed = sqlite3_total_changes(mConnection) - oldChange;
  oldChange += changed;

  if (stat == SQLITE_OK && !changed) {
    if (!aResult)
      return NS_ERROR_NULL_POINTER;
    
    if (*aResult) {
      ((mozSqlResultSqlite*)*aResult)->SetResult(r, nrow, ncolumn, mWritable);
      nsresult rv = ((mozSqlResult*)*aResult)->Rebuild();
      if (NS_FAILED(rv))
        return rv;
      NS_ADDREF(*aResult);
    }
    else {
      mozSqlResult* result = new mozSqlResultSqlite(this, aQuery);
      if (!result)
        return NS_ERROR_OUT_OF_MEMORY;
      ((mozSqlResultSqlite*)result)->SetResult(r, nrow, ncolumn, mWritable);
      nsresult rv = result->Init();
      if (NS_FAILED(rv))
        return rv;
      NS_ADDREF(*aResult = result);
    }
  }
  else if (stat == SQLITE_OK && changed) {
    if (!aAffectedRows)
      return NS_ERROR_NULL_POINTER;
    *aAffectedRows = changed;
    mLastID = sqlite3_last_insert_rowid(mConnection);
  }
  else {
    CopyUTF8toUTF16(errmsg, mErrorMessage);
    sqlite3_free_table(r);
    return NS_ERROR_FAILURE;
  }

  return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Rollback (cancel) the current transaction.

void nsIRunnable::run ( ) [inherited]
NS_IMETHOD nsIRunnable::Run ( ) [pure virtual, inherited]

Definition at line 273 of file mozSqlConnectionSqlite.cpp.

{
  if (sqlite3_errcode(mConnection) != SQLITE_OK) {
    CopyUTF8toUTF16(sqlite3_errmsg(mConnection), mErrorMessage);
    
    mConnection = nsnull;
    return NS_ERROR_FAILURE;
  }

  NS_ConvertUTF8toUCS2 buffer(sqlite3_version);
  nsAString::const_iterator start, end, iter;
  PRInt32 numbers[3] = {0,0,0};
  buffer.BeginReading(iter);
  buffer.EndReading(end);
  for (PRInt32 i = 0; i < 3; i++) {
    start = iter;
    while (iter != end && *iter != PRUnichar('.'))
      ++iter;
    nsAutoString v(Substring(start,iter));
    PRInt32 err;
    numbers[i] = v.ToInteger(&err);
    while (iter != end && *iter == PRUnichar('.'))
      ++iter;
  }
  mVersion = SERVER_VERSION(numbers[0], numbers[1], numbers[2]);

  if (mVersion < SERVER_VERSION(3,0,2))
    return NS_ERROR_FAILURE;

  return NS_OK;
}

Here is the call graph for this function:


Friends And Related Function Documentation

friend class mozSqlResult [friend, inherited]

Definition at line 64 of file mozSqlConnection.h.


Member Data Documentation

readonly attribute AString mozISqlConnection::errorMessage [inherited]

The most recent error message.

Definition at line 63 of file mozISqlConnection.idl.

The ID of the most recently added record.

Definition at line 68 of file mozISqlConnection.idl.

PRCondVar* mozSqlConnection::mCondVar [protected, inherited]

Definition at line 79 of file mozSqlConnection.h.

Definition at line 81 of file mozSqlConnectionSqlite.h.

Definition at line 83 of file mozSqlConnection.h.

nsString mozSqlConnection::mErrorMessage [protected, inherited]

Definition at line 75 of file mozSqlConnection.h.

PRLock* mozSqlConnection::mExecLock [protected, inherited]

Definition at line 80 of file mozSqlConnection.h.

PRInt32 mozSqlConnection::mLastID [protected, inherited]

Definition at line 76 of file mozSqlConnection.h.

PRLock* mozSqlConnection::mLock [protected, inherited]

Definition at line 78 of file mozSqlConnection.h.

NS_DECL_ISUPPORTS NS_DECL_MOZISQLCONNECTION friend class mozSqlConnection::mozSqlRequest [inherited]

Definition at line 63 of file mozSqlConnection.h.

Definition at line 82 of file mozSqlConnection.h.

Definition at line 74 of file mozSqlConnection.h.

PRBool mozSqlConnection::mShutdown [protected, inherited]

Definition at line 84 of file mozSqlConnection.h.

nsCOMPtr<nsIThread> mozSqlConnection::mThread [protected, inherited]

Definition at line 81 of file mozSqlConnection.h.

Definition at line 82 of file mozSqlConnectionSqlite.h.

PRBool mozSqlConnection::mWaiting [protected, inherited]

Definition at line 85 of file mozSqlConnection.h.

Definition at line 83 of file mozSqlConnectionSqlite.h.

readonly attribute AString mozISqlConnection::serverVersion [inherited]

A string holding the name and/or version info of the database.

Definition at line 58 of file mozISqlConnection.idl.


The documentation for this class was generated from the following files: