Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : */
9 :
10 : #include "Util.hxx"
11 : #include <rtl/ustrbuf.hxx>
12 :
13 : using namespace ::connectivity;
14 :
15 : using namespace ::com::sun::star;
16 : using namespace ::com::sun::star::sdbc;
17 : using namespace ::com::sun::star::uno;
18 :
19 86 : OUString firebird::sanitizeIdentifier(const OUString& rIdentifier)
20 : {
21 86 : OUString sRet = rIdentifier.trim();
22 : assert(sRet.getLength() <= 31); // Firebird identifiers cannot be longer than this.
23 :
24 86 : return sRet;
25 : }
26 :
27 0 : OUString firebird::StatusVectorToString(const ISC_STATUS_ARRAY& rStatusVector,
28 : const OUString& rCause)
29 : {
30 0 : OUStringBuffer buf;
31 : char msg[512]; // Size is based on suggestion in docs.
32 0 : const ISC_STATUS* pStatus = (const ISC_STATUS*) &rStatusVector;
33 :
34 0 : buf.appendAscii("firebird_sdbc error:");
35 : try
36 : {
37 0 : while(fb_interpret(msg, sizeof(msg), &pStatus))
38 : {
39 : // TODO: verify encoding
40 0 : buf.appendAscii("\n*");
41 0 : buf.append(OUString(msg, strlen(msg), RTL_TEXTENCODING_UTF8));
42 : }
43 : }
44 0 : catch (...)
45 : {
46 : SAL_WARN("connectivity.firebird", "ignore fb_interpret exception");
47 : }
48 0 : buf.appendAscii("\ncaused by\n'").append(rCause).appendAscii("'\n");
49 :
50 0 : OUString error = buf.makeStringAndClear();
51 : SAL_WARN("connectivity.firebird", error);
52 0 : return error;
53 : }
54 :
55 48 : void firebird::evaluateStatusVector(const ISC_STATUS_ARRAY& rStatusVector,
56 : const OUString& rCause,
57 : const uno::Reference< XInterface >& _rxContext)
58 : throw(SQLException)
59 : {
60 48 : if (IndicatesError(rStatusVector))
61 : {
62 0 : OUString error = StatusVectorToString(rStatusVector, rCause);
63 0 : throw SQLException(error, _rxContext, OUString(), 1, Any());
64 : }
65 48 : }
66 :
67 46 : sal_Int32 firebird::getColumnTypeFromFBType(short aType)
68 : {
69 46 : aType &= ~1; // Remove last bit -- it is used to denote whether column
70 : // can store Null, not needed for type determination
71 46 : switch (aType)
72 : {
73 : case SQL_TEXT:
74 6 : return DataType::CHAR;
75 : case SQL_VARYING:
76 6 : return DataType::VARCHAR;
77 : case SQL_SHORT:
78 6 : return DataType::SMALLINT;
79 : case SQL_LONG:
80 10 : return DataType::INTEGER;
81 : case SQL_FLOAT:
82 2 : return DataType::FLOAT;
83 : case SQL_DOUBLE:
84 2 : return DataType::DOUBLE;
85 : case SQL_D_FLOAT:
86 0 : return DataType::DOUBLE;
87 : case SQL_TIMESTAMP:
88 2 : return DataType::TIMESTAMP;
89 : case SQL_BLOB:
90 2 : return DataType::BLOB;
91 : case SQL_ARRAY:
92 0 : return DataType::ARRAY;
93 : case SQL_TYPE_TIME:
94 2 : return DataType::TIME;
95 : case SQL_TYPE_DATE:
96 2 : return DataType::DATE;
97 : case SQL_INT64:
98 6 : return DataType::BIGINT;
99 : case SQL_NULL:
100 0 : return DataType::SQLNULL;
101 : case SQL_QUAD: // Is a "Blob ID" according to the docs
102 0 : return 0; // TODO: verify
103 : default:
104 : assert(false); // Should never happen
105 0 : return 0;
106 : }
107 : }
108 :
109 12 : OUString firebird::getColumnTypeNameFromFBType(short aType)
110 : {
111 12 : aType &= ~1; // Remove last bit -- it is used to denote whether column
112 : // can store Null, not needed for type determination
113 12 : switch (aType)
114 : {
115 : case SQL_TEXT:
116 2 : return OUString("SQL_TEXT");
117 : case SQL_VARYING:
118 2 : return OUString("SQL_VARYING");
119 : case SQL_SHORT:
120 2 : return OUString("SQL_SHORT");
121 : case SQL_LONG:
122 4 : return OUString("SQL_LONG");
123 : case SQL_FLOAT:
124 0 : return OUString("SQL_FLOAT");
125 : case SQL_DOUBLE:
126 0 : return OUString("SQL_DOUBLE");
127 : case SQL_D_FLOAT:
128 0 : return OUString("SQL_D_FLOAT");
129 : case SQL_TIMESTAMP:
130 0 : return OUString("SQL_TIMESTAMP");
131 : case SQL_BLOB:
132 0 : return OUString("SQL_BLOB");
133 : case SQL_ARRAY:
134 0 : return OUString("SQL_ARRAY");
135 : case SQL_TYPE_TIME:
136 0 : return OUString("SQL_TYPE_TIME");
137 : case SQL_TYPE_DATE:
138 0 : return OUString("SQL_TYPE_DATE");
139 : case SQL_INT64:
140 2 : return OUString("SQL_INT64");
141 : case SQL_NULL:
142 0 : return OUString("SQL_NULL");
143 : case SQL_QUAD:
144 0 : return OUString("SQL_QUAD");
145 : default:
146 : assert(false); // Should never happen
147 0 : return OUString();
148 : }
149 : }
150 :
151 12 : short firebird::getFBTypeFromBlrType(short blrType)
152 : {
153 12 : switch (blrType)
154 : {
155 : case blr_text:
156 2 : return SQL_TEXT;
157 : case blr_text2:
158 : assert(false);
159 0 : return 0; // No idea if this should be supported
160 : case blr_varying:
161 2 : return SQL_VARYING;
162 : case blr_varying2:
163 : assert(false);
164 0 : return 0; // No idea if this should be supported
165 : case blr_short:
166 2 : return SQL_SHORT;
167 : case blr_long:
168 4 : return SQL_LONG;
169 : case blr_float:
170 0 : return SQL_FLOAT;
171 : case blr_double:
172 0 : return SQL_DOUBLE;
173 : case blr_d_float:
174 0 : return SQL_D_FLOAT;
175 : case blr_timestamp:
176 0 : return SQL_TIMESTAMP;
177 : case blr_blob:
178 0 : return SQL_BLOB;
179 : // case blr_SQL_ARRAY:
180 : // return OUString("SQL_ARRAY");
181 : case blr_sql_time:
182 0 : return SQL_TYPE_TIME;
183 : case blr_sql_date:
184 0 : return SQL_TYPE_DATE;
185 : case blr_int64:
186 2 : return SQL_INT64;
187 : // case SQL_NULL:
188 : // return OUString("SQL_NULL");
189 : case blr_quad:
190 0 : return SQL_QUAD;
191 : default:
192 : // If this happens we have hit one of the extra types in ibase.h
193 : // look up blr_* for a list, e.g. blr_domain_name, blr_not_nullable etc.
194 : assert(false);
195 0 : return 0;
196 : }
197 : }
198 :
199 18 : void firebird::mallocSQLVAR(XSQLDA* pSqlda)
200 : {
201 : // TODO: confirm the sizings below.
202 18 : XSQLVAR* pVar = pSqlda->sqlvar;
203 102 : for (int i=0; i < pSqlda->sqld; i++, pVar++)
204 : {
205 84 : int dtype = (pVar->sqltype & ~1); /* drop flag bit for now */
206 84 : switch(dtype) {
207 : case SQL_TEXT:
208 24 : pVar->sqldata = (char *)malloc(sizeof(char)*pVar->sqllen);
209 24 : break;
210 : case SQL_VARYING:
211 4 : pVar->sqldata = (char *)malloc(sizeof(char)*pVar->sqllen + 2);
212 4 : break;
213 : case SQL_SHORT:
214 28 : pVar->sqldata = (char*) malloc(sizeof(sal_Int16));
215 28 : break;
216 : case SQL_LONG:
217 8 : pVar->sqldata = (char*) malloc(sizeof(sal_Int32));
218 8 : break;
219 : case SQL_FLOAT:
220 0 : pVar->sqldata = (char *)malloc(sizeof(float));
221 0 : break;
222 : case SQL_DOUBLE:
223 0 : pVar->sqldata = (char *)malloc(sizeof(double));
224 0 : break;
225 : case SQL_D_FLOAT:
226 0 : pVar->sqldata = (char *)malloc(sizeof(double));
227 0 : break;
228 : case SQL_TIMESTAMP:
229 0 : pVar->sqldata = (char*) malloc(sizeof(ISC_TIMESTAMP));
230 0 : break;
231 : case SQL_BLOB:
232 16 : pVar->sqldata = (char*) malloc(sizeof(ISC_QUAD));
233 16 : break;
234 : case SQL_ARRAY:
235 : assert(false); // TODO: implement
236 0 : break;
237 : case SQL_TYPE_TIME:
238 0 : pVar->sqldata = (char*) malloc(sizeof(ISC_TIME));
239 0 : break;
240 : case SQL_TYPE_DATE:
241 0 : pVar->sqldata = (char*) malloc(sizeof(ISC_DATE));
242 0 : break;
243 : case SQL_INT64:
244 4 : pVar->sqldata = (char *)malloc(sizeof(sal_Int64));
245 4 : break;
246 : case SQL_NULL:
247 : assert(false); // TODO: implement
248 0 : break;
249 : case SQL_QUAD:
250 : assert(false); // TODO: implement
251 0 : break;
252 : default:
253 : SAL_WARN("connectivity.firebird", "Unknown type: " << dtype);
254 : assert(false);
255 0 : break;
256 : }
257 84 : if (pVar->sqltype & 1)
258 : {
259 : /* allocate variable to hold NULL status */
260 80 : pVar->sqlind = (short *)malloc(sizeof(short));
261 : }
262 : }
263 18 : }
264 :
265 18 : void firebird::freeSQLVAR(XSQLDA* pSqlda)
266 : {
267 18 : XSQLVAR* pVar = pSqlda->sqlvar;
268 102 : for (int i=0; i < pSqlda->sqld; i++, pVar++)
269 : {
270 84 : int dtype = (pVar->sqltype & ~1); /* drop flag bit for now */
271 84 : switch(dtype) {
272 : case SQL_TEXT:
273 : case SQL_VARYING:
274 : case SQL_SHORT:
275 : case SQL_LONG:
276 : case SQL_FLOAT:
277 : case SQL_DOUBLE:
278 : case SQL_D_FLOAT:
279 : case SQL_TIMESTAMP:
280 : case SQL_BLOB:
281 : case SQL_INT64:
282 : case SQL_TYPE_TIME:
283 : case SQL_TYPE_DATE:
284 84 : if(pVar->sqldata)
285 : {
286 84 : free(pVar->sqldata);
287 84 : pVar->sqldata = NULL;
288 : }
289 84 : break;
290 : case SQL_ARRAY:
291 : assert(false); // TODO: implement
292 0 : break;
293 : case SQL_NULL:
294 : assert(false); // TODO: implement
295 0 : break;
296 : case SQL_QUAD:
297 : assert(false); // TODO: implement
298 0 : break;
299 : default:
300 : SAL_WARN("connectivity.firebird", "Unknown type: " << dtype);
301 : // assert(false);
302 0 : break;
303 : }
304 :
305 84 : if (pVar->sqltype & 1)
306 : {
307 80 : if(pVar->sqlind)
308 : {
309 80 : free(pVar->sqlind);
310 80 : pVar->sqlind = NULL;
311 : }
312 : }
313 : }
314 18 : }
315 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|