|
25 | 25 | #include "ext/pdo/php_pdo_driver.h"
|
26 | 26 | #include "php_pdo_firebird.h"
|
27 | 27 | #include "php_pdo_firebird_int.h"
|
| 28 | +#include "pdo_firebird_utils.h" |
28 | 29 |
|
29 | 30 | #include <time.h>
|
30 | 31 |
|
@@ -64,6 +65,78 @@ static zend_always_inline ISC_QUAD php_get_isc_quad_from_sqldata(const ISC_SCHAR
|
64 | 65 | READ_AND_RETURN_USING_MEMCPY(ISC_QUAD, sqldata);
|
65 | 66 | }
|
66 | 67 |
|
| 68 | +#if FB_API_VER >= 40 |
| 69 | + |
| 70 | +static zend_always_inline ISC_TIME_TZ php_get_isc_time_tz_from_sqldata(const ISC_SCHAR *sqldata) |
| 71 | +{ |
| 72 | + READ_AND_RETURN_USING_MEMCPY(ISC_TIME_TZ, sqldata); |
| 73 | +} |
| 74 | + |
| 75 | +static zend_always_inline ISC_TIMESTAMP_TZ php_get_isc_timestamp_tz_from_sqldata(const ISC_SCHAR *sqldata) |
| 76 | +{ |
| 77 | + READ_AND_RETURN_USING_MEMCPY(ISC_TIMESTAMP_TZ, sqldata); |
| 78 | +} |
| 79 | + |
| 80 | +/* fetch formatted time with time zone */ |
| 81 | +static int get_formatted_time_tz(pdo_stmt_t *stmt, const ISC_TIME_TZ* timeTz, zval *result) |
| 82 | +{ |
| 83 | + pdo_firebird_stmt *S = (pdo_firebird_stmt*)stmt->driver_data; |
| 84 | + unsigned hours = 0, minutes = 0, seconds = 0, fractions = 0; |
| 85 | + char timeZoneBuffer[40] = {0}; |
| 86 | + char *fmt; |
| 87 | + struct tm t; |
| 88 | + ISC_TIME time; |
| 89 | + char timeBuf[80] = {0}; |
| 90 | + char timeTzBuf[124] = {0}; |
| 91 | + if (fb_decode_time_tz(S->H->isc_status, timeTz, &hours, &minutes, &seconds, &fractions, sizeof(timeZoneBuffer), timeZoneBuffer)) { |
| 92 | + return 1; |
| 93 | + } |
| 94 | + time = fb_encode_time(hours, minutes, seconds, fractions); |
| 95 | + isc_decode_sql_time(&time, &t); |
| 96 | + fmt = S->H->time_format ? S->H->time_format : PDO_FB_DEF_TIME_FMT; |
| 97 | + |
| 98 | + size_t len = strftime(timeBuf, sizeof(timeBuf), fmt, &t); |
| 99 | + if (len == 0) { |
| 100 | + return 1; |
| 101 | + } |
| 102 | + |
| 103 | + size_t time_tz_len = sprintf(timeTzBuf, "%s %s", timeBuf, timeZoneBuffer); |
| 104 | + ZVAL_STRINGL(result, timeTzBuf, time_tz_len); |
| 105 | + return 0; |
| 106 | +} |
| 107 | + |
| 108 | +/* fetch formatted timestamp with time zone */ |
| 109 | +static int get_formatted_timestamp_tz(pdo_stmt_t *stmt, const ISC_TIMESTAMP_TZ* timestampTz, zval *result) |
| 110 | +{ |
| 111 | + pdo_firebird_stmt *S = (pdo_firebird_stmt*)stmt->driver_data; |
| 112 | + unsigned year, month, day, hours, minutes, seconds, fractions; |
| 113 | + char timeZoneBuffer[40] = {0}; |
| 114 | + char *fmt; |
| 115 | + struct tm t; |
| 116 | + ISC_TIMESTAMP ts; |
| 117 | + char timestampBuf[80] = {0}; |
| 118 | + char timestampTzBuf[124] = {0}; |
| 119 | + if (fb_decode_timestamp_tz(S->H->isc_status, timestampTz, &year, &month, &day, &hours, &minutes, &seconds, &fractions, sizeof(timeZoneBuffer), timeZoneBuffer)) { |
| 120 | + return 1; |
| 121 | + } |
| 122 | + ts.timestamp_date = fb_encode_date(year, month, day); |
| 123 | + ts.timestamp_time = fb_encode_time(hours, minutes, seconds, fractions); |
| 124 | + isc_decode_timestamp(&ts, &t); |
| 125 | + |
| 126 | + fmt = S->H->timestamp_format ? S->H->timestamp_format : PDO_FB_DEF_TIMESTAMP_FMT; |
| 127 | + |
| 128 | + size_t len = strftime(timestampBuf, sizeof(timestampBuf), fmt, &t); |
| 129 | + if (len == 0) { |
| 130 | + return 1; |
| 131 | + } |
| 132 | + |
| 133 | + size_t timestamp_tz_len = sprintf(timestampTzBuf, "%s %s", timestampBuf, timeZoneBuffer); |
| 134 | + ZVAL_STRINGL(result, timestampTzBuf, timestamp_tz_len); |
| 135 | + return 0; |
| 136 | +} |
| 137 | + |
| 138 | +#endif |
| 139 | + |
67 | 140 | /* free the allocated space for passing field values to the db and back */
|
68 | 141 | static void php_firebird_free_sqlda(XSQLDA const *sqlda) /* {{{ */
|
69 | 142 | {
|
@@ -494,6 +567,16 @@ static int pdo_firebird_stmt_get_col(
|
494 | 567 | size_t len = strftime(buf, sizeof(buf), fmt, &t);
|
495 | 568 | ZVAL_STRINGL(result, buf, len);
|
496 | 569 | break;
|
| 570 | +#if FB_API_VER >= 40 |
| 571 | + case SQL_TIME_TZ: { |
| 572 | + ISC_TIME_TZ time = php_get_isc_time_tz_from_sqldata(var->sqldata); |
| 573 | + return get_formatted_time_tz(stmt, &time, result); |
| 574 | + } |
| 575 | + case SQL_TIMESTAMP_TZ: { |
| 576 | + ISC_TIMESTAMP_TZ ts = php_get_isc_timestamp_tz_from_sqldata(var->sqldata); |
| 577 | + return get_formatted_timestamp_tz(stmt, &ts, result); |
| 578 | + } |
| 579 | +#endif |
497 | 580 | case SQL_BLOB: {
|
498 | 581 | ISC_QUAD quad = php_get_isc_quad_from_sqldata(var->sqldata);
|
499 | 582 | return php_firebird_fetch_blob(stmt, colno, result, &quad);
|
|
0 commit comments