query.c
上传用户:yhdzpy8989
上传日期:2007-06-13
资源大小:13604k
文件大小:6k
源码类别:

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: query.c,v $
  4.  * PRODUCTION Revision 1000.0  2003/10/29 20:35:13  gouriano
  5.  * PRODUCTION PRODUCTION: IMPORTED [ORIGINAL] Dev-tree R1.1
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /* FreeTDS - Library of routines accessing Sybase and Microsoft databases
  10.  * Copyright (C) 1998-1999  Brian Bruns
  11.  *
  12.  * This library is free software; you can redistribute it and/or
  13.  * modify it under the terms of the GNU Library General Public
  14.  * License as published by the Free Software Foundation; either
  15.  * version 2 of the License, or (at your option) any later version.
  16.  *
  17.  * This library is distributed in the hope that it will be useful,
  18.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  20.  * Library General Public License for more details.
  21.  *
  22.  * You should have received a copy of the GNU Library General Public
  23.  * License along with this library; if not, write to the
  24.  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  25.  * Boston, MA 02111-1307, USA.
  26.  */
  27. #include <tds_config.h>
  28. #include "tds.h"
  29. #include "tdsutil.h"
  30. #include "tdsconvert.h"
  31. #ifdef DMALLOC
  32. #include <dmalloc.h>
  33. #endif
  34. static char  software_version[]   = "$Id: query.c,v 1000.0 2003/10/29 20:35:13 gouriano Exp $";
  35. static void *no_unused_var_warn[] = {software_version,
  36.                                      no_unused_var_warn};
  37. /* All manner of client to server submittal functions */
  38. /* 
  39. ** tds_submit_query() sends a language string to the database server for
  40. ** processing.  TDS 4.2 is a plain text message with a packet type of 0x01,
  41. ** TDS 7.0 is a unicode string with packet type 0x01, and TDS 5.0 uses a 
  42. ** TDS_LANG_TOKEN to encapsulate the query and a packet type of 0x0f.
  43. */
  44. int tds_submit_query(TDSSOCKET *tds, char *query)
  45. {
  46. unsigned char *buf;
  47. int bufsize;
  48. TDS_INT bufsize2;
  49. if (!query) return TDS_FAIL;
  50. /* Jeff's hack to handle long query timeouts */
  51. tds->queryStarttime = time(NULL); 
  52. if (tds->state==TDS_PENDING) {
  53. /* FIX ME -- get real message number et al. 
  54. ** if memory serves the servername is 
  55. ** OpenClient for locally generated messages,
  56. ** but this needs to be verified too.
  57. */
  58. tds_client_msg(tds->tds_ctx, tds,10000,7,0,1,
  59.         "Attempt to initiate a new SQL Server operation with results pending.");
  60. return TDS_FAIL;
  61. }
  62. tds_free_all_results(tds);
  63. tds->rows_affected = 0;
  64. tds->state = TDS_QUERYING;
  65. if (IS_TDS50(tds)) {
  66. bufsize = strlen(query)+6;
  67. buf = (unsigned char *) malloc(bufsize);
  68. memset(buf,'',bufsize);
  69. buf[0]=TDS_LANG_TOKEN; 
  70. bufsize2 = strlen(query) + 1;
  71. memcpy(buf+1, (void *)&bufsize2, 4);
  72. memcpy(&buf[6],query,strlen(query));
  73. tds->out_flag=0x0F;
  74. } else if (IS_TDS70(tds) || IS_TDS80(tds)) {
  75. bufsize = strlen(query)*2;
  76. buf = (unsigned char *) malloc(bufsize);
  77. memset(buf,'',bufsize);
  78. tds7_ascii2unicode(tds,query, buf, bufsize);
  79. tds->out_flag=0x01;
  80. } else { /* 4.2 */
  81. bufsize = strlen(query);
  82. buf = (unsigned char *) malloc(bufsize);
  83. memset(buf,'',bufsize);
  84. memcpy(&buf[0],query,strlen(query));
  85. tds->out_flag=0x01;
  86. }
  87. tds_put_n(tds, buf, bufsize);
  88. tds_flush_packet(tds);
  89. free(buf);
  90. return TDS_SUCCEED;
  91. }
  92. /* 
  93. ** tds_submit_prepare() creates a temporary stored procedure in the server.
  94. ** Currently works only with TDS 5.0 
  95. */
  96. int tds_submit_prepare(TDSSOCKET *tds, char *query, char *id)
  97. {
  98. int id_len, query_len;
  99. if (!query || !id) return TDS_FAIL;
  100. if (!IS_TDS50(tds)) {
  101. tds_client_msg(tds->tds_ctx, tds,10000,7,0,1,
  102.         "Dynamic placeholders only supported under TDS 5.0");
  103. return TDS_FAIL;
  104. }
  105. if (tds->state==TDS_PENDING) {
  106. tds_client_msg(tds->tds_ctx, tds,10000,7,0,1,
  107.         "Attempt to initiate a new SQL Server operation with results pending.");
  108. return TDS_FAIL;
  109. }
  110. tds_free_all_results(tds);
  111. /* allocate a structure for this thing */
  112. tds_alloc_dynamic(tds, id);
  113. tds->rows_affected = 0;
  114. tds->state = TDS_QUERYING;
  115. id_len = strlen(id);
  116. query_len = strlen(query);
  117. tds_put_byte(tds,0xe7); 
  118. tds_put_smallint(tds,query_len + id_len*2 + 21); 
  119. tds_put_byte(tds,0x01); 
  120. tds_put_byte(tds,0x00); 
  121. tds_put_byte(tds,id_len); 
  122. tds_put_n(tds, id, id_len);
  123. tds_put_smallint(tds,query_len + id_len + 16); 
  124. tds_put_n(tds, "create proc ", 12);
  125. tds_put_n(tds, id, id_len);
  126. tds_put_n(tds, " as ", 4);
  127. tds_put_n(tds, query, query_len);
  128. tds->out_flag=0x0F;
  129. tds_flush_packet(tds);
  130. return TDS_SUCCEED;
  131. }
  132. /* 
  133. ** tds_submit_execute() sends a previously prepared dynamic statement to the 
  134. ** server.
  135. ** Currently works only with TDS 5.0 
  136. */
  137. int tds_submit_execute(TDSSOCKET *tds, char *id)
  138. {
  139. TDSDYNAMIC *dyn;
  140. TDSINPUTPARAM *param;
  141. int elem, id_len;
  142. int i;
  143. int one = 1;
  144.      tdsdump_log(TDS_DBG_FUNC, "%L inside tds_submit_execute() %sn",id);
  145. id_len = strlen(id);
  146.      elem = tds_lookup_dynamic(tds, id);
  147.      dyn = tds->dyns[elem];
  148. /* dynamic id */
  149. tds_put_byte(tds,0xe7); 
  150. tds_put_smallint(tds,id_len + 5); 
  151. tds_put_byte(tds,0x02); 
  152. tds_put_byte(tds,0x01); 
  153. tds_put_byte(tds,id_len); 
  154. tds_put_n(tds, id, id_len);
  155. tds_put_byte(tds,0x00); 
  156. tds_put_byte(tds,0x00); 
  157. /* column descriptions */
  158. tds_put_byte(tds,0xec); 
  159. /* size */
  160. tds_put_smallint(tds, 9 * dyn->num_params + 2); 
  161. /* number of parameters */
  162. tds_put_byte(tds,dyn->num_params); 
  163. /* column detail for each parameter */
  164. for (i=0;i<dyn->num_params;i++) {
  165. param = dyn->params[i];
  166. tds_put_byte(tds,0x00); 
  167. tds_put_byte(tds,0x00); 
  168. tds_put_byte(tds,0x00); 
  169. tds_put_byte(tds,0x00); 
  170. tds_put_byte(tds,0x00); 
  171. tds_put_byte(tds,0x00); 
  172. tds_put_byte(tds,0x00); 
  173. tds_put_byte(tds,tds_get_null_type(param->column_type)); 
  174. if (param->column_bindlen) { 
  175. tds_put_byte(tds,param->column_bindlen);
  176. } else {
  177. tds_put_byte(tds,0xff);
  178. }
  179. }
  180. tds_put_byte(tds,0x00); 
  181. /* row data */
  182. tds_put_byte(tds,0xd7); 
  183. for (i=0;i<dyn->num_params;i++) {
  184. param = dyn->params[i];
  185. if (param->column_bindlen) {
  186. tds_put_byte(tds,param->column_bindlen); 
  187. param->varaddr = (char *)&one;
  188. tds_put_n(tds, param->varaddr,param->column_bindlen); 
  189. } else {
  190. tds_put_byte(tds,strlen(param->varaddr)); 
  191. tds_put_n(tds, param->varaddr,strlen(param->varaddr)); 
  192. }
  193. }
  194. /* send it */
  195. tds->out_flag=0x0F;
  196. tds_flush_packet(tds);
  197. return TDS_SUCCEED;
  198. }
  199. /*
  200. ** tds_send_cancel() sends an empty packet (8 byte header only)
  201. ** tds_process_cancel should be called directly after this.
  202. */
  203. int tds_send_cancel(TDSSOCKET *tds)
  204. {
  205.         tds->out_flag=0x06;
  206.         tds_flush_packet(tds);
  207.         return 0;
  208. }