Update ooo320-m1
[ooovba.git] / connectivity / source / drivers / postgresql / pq_resultset.cxx
blob62020f9220636e2a978e6462836ec04ace725cc6
1 #include "pq_resultset.hxx"
2 #include "pq_resultsetmetadata.hxx"
4 #include <com/sun/star/sdbc/ResultSetType.hpp>
5 #include <com/sun/star/sdbc/DataType.hpp>
7 using rtl::OUString;
8 using rtl::OUStringToOString;
10 using osl::MutexGuard;
12 using com::sun::star::uno::RuntimeException;
13 using com::sun::star::uno::Any;
14 using com::sun::star::uno::makeAny;
15 using com::sun::star::uno::Reference;
16 using com::sun::star::uno::XInterface;
18 using com::sun::star::sdbc::SQLException;
19 using com::sun::star::sdbc::XResultSetMetaData;
22 namespace pq_sdbc_driver
24 #define ASCII_STR(x) OUString( RTL_CONSTASCII_USTRINGPARAM( x ) )
26 void ResultSet::checkClosed()
27 throw ( com::sun::star::sdbc::SQLException, com::sun::star::uno::RuntimeException )
29 if( ! m_result )
31 throw SQLException( ASCII_STR( "pq_resultset: already closed" ),
32 *this, OUString(), 1, Any() );
35 if( ! m_ppSettings || ! *m_ppSettings || ! (*m_ppSettings)->pConnection )
37 throw SQLException( ASCII_STR( "pq_resultset: statement has been closed already" ),
38 *this, OUString(), 1, Any() );
43 ResultSet::ResultSet( const ::rtl::Reference< RefCountedMutex > & refMutex,
44 const Reference< XInterface > & owner,
45 ConnectionSettings **ppSettings,
46 PGresult * result,
47 const rtl::OUString &schema,
48 const rtl::OUString &table)
49 : BaseResultSet(
50 refMutex, owner, PQntuples( result ),
51 PQnfields( result ),(*ppSettings)->tc ),
52 m_ppSettings( ppSettings ),
53 m_result( result ),
54 m_schema( schema ),
55 m_table( table )
57 sal_Bool b = sal_True;
58 // m_props[RESULTSET_IS_BOOKMARKABLE] = Any( &b, getBooleanCppuType() );
59 m_props[ BASERESULTSET_RESULT_SET_TYPE] = makeAny(
60 com::sun::star::sdbc::ResultSetType::SCROLL_INSENSITIVE );
64 Any ResultSet::getValue( sal_Int32 columnIndex )
66 Any ret;
67 if( PQgetisnull( m_result, m_row, columnIndex -1 ) )
69 m_wasNull = true;
71 else
73 m_wasNull = false;
74 ret <<= ::rtl::OUString(
75 PQgetvalue( m_result, m_row , columnIndex -1 ) ,
76 PQgetlength( m_result, m_row , columnIndex -1 ) ,
77 (*m_ppSettings)->encoding );
80 return ret;
83 ResultSet::~ResultSet()
86 void ResultSet::close( ) throw (SQLException, RuntimeException)
88 Reference< XInterface > owner;
90 MutexGuard guard( m_refMutex->mutex );
91 if( m_result )
93 PQclear(m_result );
94 m_result = 0;
95 m_row = -1;
97 owner = m_owner;
98 m_owner.clear();
102 Reference< XResultSetMetaData > ResultSet::getMetaData( ) throw (SQLException, RuntimeException)
104 MutexGuard guard( m_refMutex->mutex );
105 checkClosed();
106 return new ResultSetMetaData(
107 m_refMutex, this, this, m_ppSettings, m_result, m_schema, m_table );
110 sal_Int32 ResultSet::findColumn( const ::rtl::OUString& columnName )
111 throw (SQLException, RuntimeException)
113 MutexGuard guard( m_refMutex->mutex );
114 checkClosed();
115 return PQfnumber(
116 m_result,
117 OUStringToOString( columnName, (*m_ppSettings)->encoding ).getStr())
121 static bool isNumber( const char * data, sal_Int32 len )
123 bool ret = false;
124 if( len )
126 ret = true;
127 for( int i = 0 ; i < len ; i ++ )
129 if( ( data[i] >= '0' && data[i] <= '9' ) ||
130 data[i] == '-' || data[i] == '+' || data[i] == '.' || data[i] == ',' )
132 if( data[i] == '-' && i != 0 && i != len-1 )
134 // no number, maybe a date
135 ret = false;
136 break;
139 else
141 ret = false;
142 break;
146 return ret;
149 static bool isInteger( const char * data, sal_Int32 len )
151 bool ret = false;
152 if( len )
154 ret = true;
155 for( int i = 0 ; i < len ; i ++ )
157 if( ( data[i] >= '0' && data[i] <= '9' ) ||
158 data[i] == '-' || data[i] == '+' )
160 if( data[i] == '-' && i != 0 && i != len-1 )
162 // no number, maybe a date
163 ret = false;
164 break;
167 else
169 ret = false;
170 break;
174 return ret;
177 static bool isDate( const char * data, sal_Int32 len )
179 bool ret = false;
180 return 10 == len &&
181 '-' == data[4] &&
182 '-' == data[7] &&
183 isInteger( &(data[0]),4 ) &&
184 isInteger( &(data[5]),2) &&
185 isInteger( &(data[8]),2 );
188 static bool isTime( const char * data, sal_Int32 len )
190 bool ret = false;
191 return 8 == len &&
192 ':' == data[2] &&
193 ':' == data[5] &&
194 isInteger( &(data[0]),2 ) &&
195 isInteger( &(data[3]),2) &&
196 isInteger( &(data[6]),2 );
200 static bool isTimestamp( const char * data, sal_Int32 len )
202 return len == 19 && isDate( data, 10) && isTime( &(data[11]),8 );
205 sal_Int32 ResultSet::guessDataType( sal_Int32 column )
207 // we don't look into more than 100 rows ...
208 sal_Int32 ret = com::sun::star::sdbc::DataType::INTEGER;
210 int maxRows = ( m_rowCount > 100 ? 100 : m_rowCount );
211 for( int i = 0 ; i < maxRows ; i ++ )
213 if( ! PQgetisnull( m_result, i , column-1 ) )
215 const char * p = PQgetvalue( m_result, i , column -1 );
216 int len = PQgetlength( m_result, i , column -1 );
218 if( com::sun::star::sdbc::DataType::INTEGER == ret )
220 if( ! isInteger( p,len ) )
221 ret = com::sun::star::sdbc::DataType::NUMERIC;
223 if( com::sun::star::sdbc::DataType::NUMERIC == ret )
225 if( ! isNumber( p,len ) )
227 ret = com::sun::star::sdbc::DataType::DATE;
230 if( com::sun::star::sdbc::DataType::DATE == ret )
232 if( ! isDate( p,len ) )
234 ret = com::sun::star::sdbc::DataType::TIME;
237 if( com::sun::star::sdbc::DataType::TIME == ret )
239 if( ! isTime( p,len ) )
241 ret = com::sun::star::sdbc::DataType::TIMESTAMP;
244 if( com::sun::star::sdbc::DataType::TIMESTAMP == ret )
246 if( ! isTimestamp( p,len ) )
248 ret = com::sun::star::sdbc::DataType::LONGVARCHAR;
249 break;
254 return ret;