1 /* $Id: parameters.cpp 535289 2017-05-08 13:38:35Z ivanov $
2 * ===========================================================================
3 *
4 * PUBLIC DOMAIN NOTICE
5 * National Center for Biotechnology Information
6 *
7 * This software/database is a "United States Government Work" under the
8 * terms of the United States Copyright Act. It was written as part of
9 * the author's official duties as a United States Government employee and
10 * thus cannot be copyrighted. This software/database is freely available
11 * to the public for use. The National Library of Medicine and the U.S.
12 * Government have not placed any restriction on its use or reproduction.
13 *
14 * Although all reasonable efforts have been taken to ensure the accuracy
15 * and reliability of the software and data, the NLM and the U.S.
16 * Government do not and cannot warrant the performance or results that
17 * may be obtained by using this software or data. The NLM and the U.S.
18 * Government disclaim all warranties, express or implied, including
19 * warranties of performance, merchantability or fitness for any particular
20 * purpose.
21 *
22 * Please cite the author in any work or product based on this material.
23 *
24 * ===========================================================================
25 *
26 * Author: Vladimir Soussov
27 *
28 * File Description: Param container implementation
29 *
30 */
31
32 #include <ncbi_pch.hpp>
33 #include <corelib/ncbimisc.hpp>
34 #include <dbapi/driver/util/parameters.hpp>
35 #include <dbapi/error_codes.hpp>
36 #include <dbapi/driver/exception.hpp>
37
38
39 #define NCBI_USE_ERRCODE_X Dbapi_DrvrUtil
40
41
42 BEGIN_NCBI_SCOPE
43
44 namespace impl {
45
46 ////////////////////////////////////////////////////////////////////////////////
SParam(void)47 CDB_Params::SParam::SParam(void) :
48 m_Param(NULL),
49 m_Status(0)
50 {
51 }
52
~SParam(void)53 CDB_Params::SParam::~SParam(void)
54 {
55 DeleteParam();
56 }
57
58
59 void
Bind(const string & param_name,CDB_Object * param,bool is_out)60 CDB_Params::SParam::Bind(const string& param_name, CDB_Object* param, bool is_out)
61 {
62 DeleteParam();
63
64 m_Param = param;
65 m_Name = param_name;
66 m_Status |= fBound | (is_out ? fOutput : 0) ;
67 }
68
69 void
Set(const string & param_name,CDB_Object * param,bool is_out)70 CDB_Params::SParam::Set(const string& param_name, CDB_Object* param, bool is_out)
71 {
72 if ((m_Status & fSet) != 0) {
73 if (m_Param->GetType() == param->GetType()) {
74 // types are the same
75 m_Param->AssignValue(*param);
76 } else {
77 // we need to delete the old one
78 DeleteParam();
79
80 m_Param = param->Clone();
81 }
82 } else {
83 m_Param = param->Clone();
84 }
85
86 m_Name = param_name;
87 m_Status |= fSet | (is_out ? fOutput : 0);
88 }
89
90
91 ////////////////////////////////////////////////////////////////////////////////
CDB_Params(void)92 CDB_Params::CDB_Params(void)
93 : m_Locked(false)
94 {
95 }
96
97
98 bool
GetParamNumInternal(const string & param_name,unsigned int & param_num) const99 CDB_Params::GetParamNumInternal(const string& param_name, unsigned int& param_num) const
100 {
101 // try to find this name
102 for (param_num = 0; param_num < m_Params.size(); ++param_num) {
103 const SParam& param = m_Params[param_num];
104 if (param.m_Status != 0 && param_name == param.m_Name) {
105 // We found it ...
106 return true;
107 }
108 }
109
110 return false;
111 }
112
113
114 unsigned int
GetParamNum(const string & param_name) const115 CDB_Params::GetParamNum(const string& param_name) const
116 {
117 unsigned int param_no = 0;
118
119 if (!GetParamNumInternal(param_name, param_no)) {
120 // Parameter not found ...
121 DATABASE_DRIVER_ERROR("Invalid parameter's name: " + param_name, 122510 );
122 }
123
124 return param_no;
125 }
126
127 unsigned int
GetParamNum(unsigned int param_no,const string & param_name)128 CDB_Params::GetParamNum(unsigned int param_no, const string& param_name)
129 {
130 if (param_no == CDB_Params::kNoParamNumber) {
131 if (!param_name.empty()) {
132 // try to find this name
133 if (!GetParamNumInternal(param_name, param_no)) {
134 // Parameter not found ...
135 CHECK_DRIVER_ERROR(IsLocked(), "Parameters are locked. New bindins are not allowed.", 20001);
136 m_Params.resize(m_Params.size() + 1);
137 return (unsigned int)(m_Params.size() - 1);
138 }
139 }
140 } else {
141 if (param_no >= m_Params.size()) {
142 CHECK_DRIVER_ERROR(IsLocked(), "Parameters are locked. New bindins are not allowed.", 20001);
143 m_Params.resize(param_no + 1);
144 }
145 }
146
147 return param_no;
148 }
149
150
BindParam(unsigned int param_no,const string & param_name,CDB_Object * param,bool is_out)151 bool CDB_Params::BindParam(unsigned int param_no, const string& param_name,
152 CDB_Object* param, bool is_out)
153 {
154 param_no = GetParamNum(param_no, param_name);
155 m_Params[param_no].Bind(param_name, param, is_out);
156 return true;
157 }
158
159
SetParam(unsigned int param_no,const string & param_name,CDB_Object * param,bool is_out)160 bool CDB_Params::SetParam(unsigned int param_no, const string& param_name,
161 CDB_Object* param, bool is_out)
162 {
163 param_no = GetParamNum(param_no, param_name);
164 m_Params[param_no].Set(param_name, param, is_out);
165 return true;
166 }
167
168
SemiShallowClone(void) const169 CDB_Params* CDB_Params::SemiShallowClone(void) const
170 {
171 unique_ptr<CDB_Params> result(new CDB_Params);
172 SParam empty_param;
173 ITERATE (deque<SParam>, it, m_Params) {
174 result->m_Params.push_back(empty_param);
175 SParam& p = result->m_Params.back();
176
177 p.m_Name = it->m_Name;
178 p.m_Param = ((it->m_Param == NULL) ? NULL
179 : it->m_Param->ShallowClone());
180 p.m_Status = (it->m_Status & ~fBound) | fSet;
181 }
182 return result.release();
183 }
184
185
~CDB_Params()186 CDB_Params::~CDB_Params()
187 {
188 }
189
190
191 string
g_SubstituteParam(const string & query,const string & name,const string & val)192 g_SubstituteParam(const string& query, const string& name, const string& val)
193 {
194 string result = query;
195 size_t name_len = name.length();
196 size_t val_len = val.length();
197 size_t len = result.length();
198 char q = 0;
199
200 for (size_t pos = 0; pos < len; pos++) {
201 if (q) {
202 if (result[pos] == q)
203 q = 0;
204 continue;
205 }
206 if (result[pos] == '"' || result[pos] == '\'') {
207 q = result[pos];
208 continue;
209 }
210 if (NStr::Compare(result, pos, name_len, name) == 0
211 && (pos == 0 || !isalnum((unsigned char) result[pos - 1]))
212 && (pos + name_len >= result.size()
213 || (!isalnum((unsigned char) result[pos + name_len])
214 && result[pos + name_len] != '_')))
215 {
216 result.replace(pos, name_len, val);
217 len = result.length();
218 pos += val_len;
219 }
220 }
221
222 return result;
223 }
224
225 }
226
227 END_NCBI_SCOPE
228
229
230