odbcdesc.c
来自「这个是内存数据库的客户端」· C语言 代码 · 共 314 行
C
314 行
/* * The contents of this file are subject to the MonetDB Public License * Version 1.1 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://monetdb.cwi.nl/Legal/MonetDBLicense-1.1.html * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the * License for the specific language governing rights and limitations * under the License. * * The Original Code is the MonetDB Database System. * * The Initial Developer of the Original Code is CWI. * Portions created by CWI are Copyright (C) 1997-2007 CWI. * All Rights Reserved. */#include "ODBCGlobal.h"#include "ODBCStmt.h"#define ODBC_DESC_MAGIC_NR 21845 /* for internal sanity check only *//* * Creates a new allocated ODBCDesc object and initializes it. * * Precondition: valid ODBCDbc object * Postcondition: returns a new ODBCDesc object */ODBCDesc *newODBCDesc(ODBCDbc *dbc){ ODBCDesc *desc; assert(dbc); desc = (ODBCDesc *) malloc(sizeof(ODBCDesc)); if (desc == NULL) { /* Memory allocation error */ addDbcError(dbc, "HY001", NULL, 0); return NULL; } assert(desc); desc->Dbc = dbc; desc->Error = NULL; desc->RetrievedErrors = 0; desc->Stmt = NULL; desc->descRec = NULL; desc->sql_desc_alloc_type = SQL_DESC_ALLOC_USER; desc->sql_desc_array_size = 1; desc->sql_desc_array_status_ptr = NULL; desc->sql_desc_bind_offset_ptr = NULL; desc->sql_desc_bind_type = SQL_BIND_TYPE_DEFAULT; desc->sql_desc_count = 0; desc->sql_desc_rows_processed_ptr = NULL; desc->Type = ODBC_DESC_MAGIC_NR; /* set it valid */ return desc;}/* * Check if the descriptor handle is valid. * Note: this function is used internally by the driver to assert legal * and save usage of the handle and prevent crashes as much as possible. * * Precondition: none * Postcondition: returns 1 if it is a valid statement handle, * returns 0 if is invalid and thus an unusable handle. */intisValidDesc(ODBCDesc *desc){#ifdef ODBCDEBUG if (!(desc && desc->Type == ODBC_DESC_MAGIC_NR)) ODBCLOG("desc " PTRFMT "not a valid descriptor handle\n", PTRFMTCAST desc);#endif return desc && desc->Type == ODBC_DESC_MAGIC_NR;}/* * Creates and adds an error msg object to the end of the error list of * this ODBCDesc struct. * When the errMsg is NULL and the SQLState is an ISO SQLState the * standard ISO message text for the SQLState is used as message. * * Precondition: desc must be valid. SQLState and errMsg may be NULL. */voidaddDescError(ODBCDesc *desc, const char *SQLState, const char *errMsg, int nativeErrCode){ ODBCError *error = NULL;#ifdef ODBCDEBUG ODBCLOG("addDescError " PTRFMT " %s %s %d\n", PTRFMTCAST desc, SQLState, errMsg ? errMsg : getStandardSQLStateMsg(SQLState), nativeErrCode);#endif assert(isValidDesc(desc)); error = newODBCError(SQLState, errMsg, nativeErrCode); appendODBCError(&desc->Error, error);}/* * Extracts an error object from the error list of this ODBCDesc struct. * The error object itself is removed from the error list. * The caller is now responsible for freeing the error object memory. * * Precondition: desc and error must be valid * Postcondition: returns a ODBCError object or null when no error is available. */ODBCError *getDescError(ODBCDesc *desc){ assert(isValidDesc(desc)); return desc->Error;}static voidcleanODBCDescRec(ODBCDesc *desc, ODBCDescRec *rec){ if (rec->sql_desc_base_column_name) free(rec->sql_desc_base_column_name); if (rec->sql_desc_base_table_name) free(rec->sql_desc_base_table_name); if (rec->sql_desc_catalog_name) free(rec->sql_desc_catalog_name); if (rec->sql_desc_label) free(rec->sql_desc_label); if (rec->sql_desc_literal_prefix) free(rec->sql_desc_literal_prefix); if (rec->sql_desc_literal_suffix) free(rec->sql_desc_literal_suffix); if (rec->sql_desc_local_type_name) free(rec->sql_desc_local_type_name); if (rec->sql_desc_name) free(rec->sql_desc_name); if (rec->sql_desc_schema_name) free(rec->sql_desc_schema_name); if (rec->sql_desc_table_name) free(rec->sql_desc_table_name); if (rec->sql_desc_type_name) free(rec->sql_desc_type_name); memset(rec, 0, sizeof(*rec)); if (desc) { if (isAD(desc)) { rec->sql_desc_concise_type = SQL_C_DEFAULT; rec->sql_desc_type = SQL_C_DEFAULT; } else if (isIPD(desc)) { rec->sql_desc_parameter_type = SQL_PARAM_INPUT; rec->sql_desc_nullable = SQL_NULLABLE; } }}voidsetODBCDescRecCount(ODBCDesc *desc, int count){ assert(count >= 0); assert(desc->sql_desc_count >= 0); if (count == desc->sql_desc_count) return; if (count < desc->sql_desc_count) { int i; for (i = count + 1; i <= desc->sql_desc_count; i++) cleanODBCDescRec(NULL, &desc->descRec[i]); } if (count == 0) { assert(desc->descRec != NULL); free(desc->descRec); desc->descRec = NULL; } else if (desc->descRec == NULL) { assert(desc->sql_desc_count == 0); desc->descRec = (ODBCDescRec *) malloc((count + 1) * sizeof(*desc->descRec)); } else { assert(desc->sql_desc_count > 0); desc->descRec = (ODBCDescRec *) realloc(desc->descRec, (count + 1) * sizeof(*desc->descRec)); } if (count > desc->sql_desc_count) { int i; memset(desc->descRec + desc->sql_desc_count + 1, 0, (count - desc->sql_desc_count) * sizeof(*desc->descRec)); if (isAD(desc)) { for (i = desc->sql_desc_count + 1; i <= count; i++) { desc->descRec[i].sql_desc_concise_type = SQL_C_DEFAULT; desc->descRec[i].sql_desc_type = SQL_C_DEFAULT; } } else if (isIPD(desc)) { for (i = desc->sql_desc_count + 1; i <= count; i++) { desc->descRec[i].sql_desc_parameter_type = SQL_PARAM_INPUT; desc->descRec[i].sql_desc_nullable = SQL_NULLABLE; } } } desc->sql_desc_count = count;}/* * Destroys the ODBCDesc object including its own managed data. * * Precondition: desc must be valid. * Postcondition: desc is completely destroyed, desc handle is become invalid. */voiddestroyODBCDesc(ODBCDesc *desc){ assert(isValidDesc(desc)); desc->Type = 0; deleteODBCErrorList(&desc->Error); setODBCDescRecCount(desc, 0); free(desc);}ODBCDescRec *addODBCDescRec(ODBCDesc *desc, SQLSMALLINT recno){ assert(desc); assert(recno > 0); if (desc->sql_desc_count < recno) setODBCDescRecCount(desc, recno); else { assert(desc->descRec != NULL); cleanODBCDescRec(desc, &desc->descRec[recno]); } return &desc->descRec[recno];}SQLUINTEGERODBCDisplaySize(ODBCDescRec *rec){ switch (rec->sql_desc_concise_type) { case SQL_CHAR: case SQL_VARCHAR: case SQL_LONGVARCHAR: case SQL_WCHAR: case SQL_WVARCHAR: case SQL_WLONGVARCHAR: return rec->sql_desc_length; case SQL_DECIMAL: case SQL_NUMERIC: return rec->sql_desc_length; case SQL_BIT: return 1; case SQL_TINYINT: return 3; case SQL_SMALLINT: return 5; case SQL_INTEGER: return 10; case SQL_BIGINT: return rec->sql_desc_unsigned ? 20 : 19; case SQL_REAL: return 7; case SQL_FLOAT: case SQL_DOUBLE: return 15; case SQL_TYPE_DATE: return 10; /* strlen("yyyy-mm-dd") */ case SQL_TYPE_TIME: return 12; /* strlen("hh:mm:ss.fff") */ case SQL_TYPE_TIMESTAMP: return 23; /* strlen("yyyy-mm-dd hh:mm:ss.fff") */ case SQL_INTERVAL_SECOND: /* strlen("INTERVAL -'sss[.fff]' SECOND(p,q)") */ return 11 + 13 + (rec->sql_desc_datetime_interval_precision > 10) + (rec->sql_desc_precision > 10) + rec->sql_desc_datetime_interval_precision + (rec->sql_desc_precision > 0 ? rec->sql_desc_precision + 1 : 0); case SQL_INTERVAL_DAY_TO_SECOND: /* strlen("INTERVAL -'ddd hh:mm:ss[.fff]' DAY(p) TO SECOND(q)") */ return 11 + 21 + (rec->sql_desc_datetime_interval_precision > 10) + (rec->sql_desc_precision > 10) + rec->sql_desc_datetime_interval_precision + 9 + (rec->sql_desc_precision > 0 ? rec->sql_desc_precision + 1 : 0); case SQL_INTERVAL_HOUR_TO_SECOND: /* strlen("INTERVAL -'hhh:mm:ss[.fff]' HOUR(p) TO SECOND(q)") */ return 11 + 22 + (rec->sql_desc_datetime_interval_precision > 10) + (rec->sql_desc_precision > 10) + rec->sql_desc_datetime_interval_precision + 6 + (rec->sql_desc_precision > 0 ? rec->sql_desc_precision + 1 : 0); case SQL_INTERVAL_MINUTE_TO_SECOND: /* strlen("INTERVAL -'mmm:ss[.fff]' MINUTE(p) TO SECOND(q)") */ return 11 + 24 + (rec->sql_desc_datetime_interval_precision > 10) + (rec->sql_desc_precision > 10) + rec->sql_desc_datetime_interval_precision + 3 + (rec->sql_desc_precision > 0 ? rec->sql_desc_precision + 1 : 0); case SQL_INTERVAL_YEAR: /* strlen("INTERVAL -'yyy' YEAR(p)") */ return 11 + 9 + (rec->sql_desc_datetime_interval_precision > 10) + rec->sql_desc_datetime_interval_precision; case SQL_INTERVAL_MONTH: /* strlen("INTERVAL -'yyy' MONTH(p)") */ return 11 + 10 + (rec->sql_desc_datetime_interval_precision > 10) + rec->sql_desc_datetime_interval_precision; case SQL_INTERVAL_DAY: /* strlen("INTERVAL -'yyy' DAY(p)") */ return 11 + 8 + (rec->sql_desc_datetime_interval_precision > 10) + rec->sql_desc_datetime_interval_precision; case SQL_INTERVAL_HOUR: /* strlen("INTERVAL -'yyy' HOUR(p)") */ return 11 + 9 + (rec->sql_desc_datetime_interval_precision > 10) + rec->sql_desc_datetime_interval_precision; case SQL_INTERVAL_MINUTE: /* strlen("INTERVAL -'yyy' MINUTE(p)") */ return 11 + 11 + (rec->sql_desc_datetime_interval_precision > 10) + rec->sql_desc_datetime_interval_precision; case SQL_INTERVAL_YEAR_TO_MONTH: /* strlen("INTERVAL -'yyy' YEAR(p) TO MONTH") */ return 11 + 18 + (rec->sql_desc_datetime_interval_precision > 10) + rec->sql_desc_datetime_interval_precision + 3; case SQL_INTERVAL_DAY_TO_HOUR: /* strlen("INTERVAL -'yyy' DAY(p) TO HOUR") */ return 11 + 16 + (rec->sql_desc_datetime_interval_precision > 10) + rec->sql_desc_datetime_interval_precision + 3; case SQL_INTERVAL_HOUR_TO_MINUTE: /* strlen("INTERVAL -'yyy' HOUR(p) TO MINUTE") */ return 11 + 19 + (rec->sql_desc_datetime_interval_precision > 10) + rec->sql_desc_datetime_interval_precision + 3; case SQL_INTERVAL_DAY_TO_MINUTE: /* strlen("INTERVAL -'yyy' DAY(p) TO MINUTE") */ return 11 + 18 + (rec->sql_desc_datetime_interval_precision > 10) + rec->sql_desc_datetime_interval_precision + 6; case SQL_GUID: /* strlen("aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee") */ return 36; default: return SQL_NO_TOTAL; }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?