~ubuntu-branches/ubuntu/utopic/pdns/utopic-updates

« back to all changes in this revision

Viewing changes to pdns/ssqlite3.cc

  • Committer: Package Import Robot
  • Author(s): Marc Haber, Marc Haber, Evgeni Golov
  • Date: 2012-05-11 23:51:27 UTC
  • mfrom: (1.1.9) (12.1.14 sid)
  • Revision ID: package-import@ubuntu.com-20120511235127-v0qjuaplfckcb2cd
Tags: 3.1-1
[ Marc Haber ]
* Imported Upstream version 3.1
  * reduce column size for 'algorithm' to 50. Closes: #662935
  * handle smallcaps RRs. Closes: #656788
* refresh patches
* remove unused patches
* add patch to turn off the traceback handler at run time
* add patch for changeset 2575 (race condition with supermasters)
* fix mysql multiarch build failure, set cflags etc to hardening defaults
* do not run bootstrap a build time, using autotools_dev
* use dh-autoreconf, remove autofoo created files from
  patches/fix-mongodb-backend-patch
* fix dh invocation
* create MySQL databases with engine=innodb instead of type
* set debian/compat to 9
* Standards-Version: 3.9.3 (no changes needed)
* add myself to uploaders, change Vcs-Header to my git. Closes: #672550

[ Evgeni Golov ]
* use system libpolarssl if present, local copy otherwise.
  Closes: #671856, #656861

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
//
 
3
// SQLite backend for PowerDNS
 
4
// Copyright (C) 2003, Michel Stol <michel@powerdns.com>
 
5
//
 
6
 
 
7
#include "pdns/utility.hh"
 
8
#include <string>
 
9
#include "ssqlite3.hh"
 
10
#include <iostream>
 
11
 
 
12
#ifdef WIN32
 
13
# include <io.h>
 
14
# define access _access
 
15
# define F_OK 0
 
16
#else // WIN32
 
17
# include <unistd.h>
 
18
#endif // Unix
 
19
 
 
20
// Constructor.
 
21
SSQLite3::SSQLite3( const std::string & database, bool creat )
 
22
{
 
23
  // Open the database connection.
 
24
  if(!creat) 
 
25
    if ( access( database.c_str(), F_OK ) == -1 )
 
26
      throw sPerrorException( "SQLite database does not exist yet" );
 
27
 
 
28
  if ( sqlite3_open( database.c_str(), &m_pDB)!=SQLITE_OK )
 
29
    throw sPerrorException( "Could not connect to the SQLite database '" + database + "'" );
 
30
  m_pStmt = 0;
 
31
  sqlite3_busy_handler(m_pDB, busyHandler, 0);
 
32
}
 
33
 
 
34
// Destructor.
 
35
SSQLite3::~SSQLite3()
 
36
{
 
37
  int ret;
 
38
  for(int n = 0; n < 2 ; ++n) {
 
39
    if((ret =sqlite3_close( m_pDB )) != SQLITE_OK) {
 
40
      if(n || !m_pStmt || ret != SQLITE_BUSY) { // if we have SQLITE_BUSY, and a working m_Pstmt, try finalize
 
41
        cerr<<"Unable to close down sqlite connection: "<<ret<<endl;
 
42
        abort();
 
43
      }
 
44
      else {
 
45
        sqlite3_finalize(m_pStmt);
 
46
      }
 
47
    }
 
48
    else
 
49
      break;
 
50
  }
 
51
}
 
52
 
 
53
 
 
54
// Constructs a SSqlException object.
 
55
SSqlException SSQLite3::sPerrorException( const std::string & reason )
 
56
{
 
57
  return SSqlException( reason );
 
58
}
 
59
 
 
60
 
 
61
// Performs a query.
 
62
int SSQLite3::doQuery( const std::string & query, result_t & result )
 
63
{
 
64
  result.clear();
 
65
 
 
66
  doQuery( query );
 
67
 
 
68
  row_t row;
 
69
  while( getRow( row ))
 
70
    result.push_back( row );
 
71
 
 
72
  return result.size();
 
73
}
 
74
 
 
75
 
 
76
// Performs a query.
 
77
int SSQLite3::doQuery( const std::string & query )
 
78
{
 
79
  const char *pTail;
 
80
  // Execute the query.
 
81
  
 
82
#if SQLITE_VERSION_NUMBER >=  3003009
 
83
  if ( sqlite3_prepare_v2( m_pDB, query.c_str(), -1, &m_pStmt, &pTail ) != SQLITE_OK )
 
84
#else
 
85
  if ( sqlite3_prepare( m_pDB, query.c_str(), -1, &m_pStmt, &pTail ) != SQLITE_OK )   
 
86
#endif
 
87
    throw sPerrorException( string("Unable to compile SQLite statement : ")+ sqlite3_errmsg( m_pDB ) );
 
88
 
 
89
  return 0;
 
90
}
 
91
 
 
92
int SSQLite3::busyHandler(void*, int)
 
93
{
 
94
  usleep(1000);
 
95
  return 1;
 
96
}
 
97
 
 
98
// Returns a row from the result set.
 
99
bool SSQLite3::getRow( row_t & row )
 
100
{
 
101
  int  numCols;
 
102
  int  rc;
 
103
  const char *pData;
 
104
 
 
105
  row.clear();
 
106
 
 
107
  rc = sqlite3_step( m_pStmt );
 
108
 
 
109
  if ( rc == SQLITE_ROW )
 
110
  {
 
111
    numCols = sqlite3_column_count( m_pStmt );
 
112
    // Another row received, process it.
 
113
    for ( int i = 0; i < numCols; i++ )
 
114
    {
 
115
      pData = (const char*) sqlite3_column_text( m_pStmt, i );
 
116
      row.push_back( pData ? pData : "" ); // NULL value to "".
 
117
    }
 
118
 
 
119
    return true;
 
120
  }
 
121
 
 
122
  if ( rc == SQLITE_DONE )
 
123
  {
 
124
    // We're done, clean up.
 
125
    sqlite3_finalize( m_pStmt );
 
126
    m_pStmt = NULL;
 
127
    return false;
 
128
  }
 
129
  
 
130
  if(rc == SQLITE_CANTOPEN) {
 
131
    string error ="CANTOPEN error in sqlite3, often caused by unwritable sqlite3 db *directory*: "+string(sqlite3_errmsg(m_pDB));
 
132
    sqlite3_finalize(m_pStmt);
 
133
    m_pStmt = 0;
 
134
    throw sPerrorException(error);
 
135
  }
 
136
  
 
137
  // Something went wrong, complain.
 
138
  throw sPerrorException( "Error while retrieving SQLite query results: "+string(sqlite3_errmsg(m_pDB) ));
 
139
 
 
140
  // Prevent some compilers from complaining.
 
141
  return false;
 
142
}
 
143
 
 
144
 
 
145
// Escape a SQL query.
 
146
std::string SSQLite3::escape( const std::string & name)
 
147
{
 
148
  std::string a;
 
149
 
 
150
  for( std::string::const_iterator i = name.begin(); i != name.end(); ++i ) 
 
151
  {
 
152
    if( *i == '\'' || *i == '\\' )
 
153
      a += '\\';
 
154
 
 
155
    a += *i;
 
156
  }
 
157
 
 
158
  return a;
 
159
}
 
160