* Get and convert columns from a result set */
| 79 | * Get and convert columns from a result set |
| 80 | */ |
| 81 | int db_postgres_get_columns(const db_con_t* _h, db_res_t* _r) |
| 82 | { |
| 83 | int col, datatype; |
| 84 | |
| 85 | if (!_h || !_r) { |
| 86 | LM_ERR("invalid parameter value\n"); |
| 87 | return -1; |
| 88 | } |
| 89 | |
| 90 | /* Get the number of rows (tuples) in the query result. */ |
| 91 | RES_ROW_N(_r) = PQntuples(CON_RESULT(_h)); |
| 92 | |
| 93 | /* Get the number of columns (fields) in each row of the query result. */ |
| 94 | RES_COL_N(_r) = PQnfields(CON_RESULT(_h)); |
| 95 | |
| 96 | if (!RES_COL_N(_r)) { |
| 97 | LM_DBG("no columns returned from the query\n"); |
| 98 | return -2; |
| 99 | } else { |
| 100 | LM_DBG("%d columns returned from the query\n", RES_COL_N(_r)); |
| 101 | } |
| 102 | |
| 103 | if (db_allocate_columns(_r, RES_COL_N(_r)) != 0) { |
| 104 | LM_ERR("could not allocate columns\n"); |
| 105 | return -3; |
| 106 | } |
| 107 | |
| 108 | /* For each column both the name and the OID number of the |
| 109 | * data type are saved. */ |
| 110 | for(col = 0; col < RES_COL_N(_r); col++) { |
| 111 | |
| 112 | /* The pointer that is here returned is part of the result structure.*/ |
| 113 | RES_NAMES(_r)[col]->s = PQfname(CON_RESULT(_h), col); |
| 114 | RES_NAMES(_r)[col]->len = strlen(PQfname(CON_RESULT(_h), col)); |
| 115 | |
| 116 | LM_DBG("RES_NAMES(%p)[%d]=[%.*s]\n", RES_NAMES(_r)[col], col, |
| 117 | RES_NAMES(_r)[col]->len, RES_NAMES(_r)[col]->s); |
| 118 | |
| 119 | /* get the datatype of the column */ |
| 120 | switch(datatype = PQftype(CON_RESULT(_h),col)) |
| 121 | { |
| 122 | case INT2OID: |
| 123 | case INT4OID: |
| 124 | LM_DBG("use DB_INT result type\n"); |
| 125 | RES_TYPES(_r)[col] = DB_INT; |
| 126 | break; |
| 127 | |
| 128 | case INT8OID: |
| 129 | LM_DBG("use DB_BIGINT result type\n"); |
| 130 | RES_TYPES(_r)[col] = DB_BIGINT; |
| 131 | break; |
| 132 | |
| 133 | case FLOAT4OID: |
| 134 | case FLOAT8OID: |
| 135 | case NUMERICOID: |
| 136 | LM_DBG("use DB_DOUBLE result type\n"); |
| 137 | RES_TYPES(_r)[col] = DB_DOUBLE; |
| 138 | break; |
no test coverage detected