⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 boundio.htm

📁 The goal of this library is to make ODBC recordsets look just like an STL container. As a user, you
💻 HTM
📖 第 1 页 / 共 2 页
字号:

<p><font size="2" face="Courier New">map&lt;string, BoundIO&gt;</font></p>

<h3>Notation:</h3>

<table border="0">
    <tr>
        <td valign="top"><tt>X</tt> </td>
        <td valign="top">A type that is a model of <font size="2"
        face="Courier New">BoundIO</font></td>
    </tr>
    <tr>
        <td valign="top"><tt>a</tt> </td>
        <td valign="top">Object of type <tt>X</tt> </td>
    </tr>
</table>

<h3>Expression semantics: BoundIO</h3>

<table border="1">
    <tr>
        <th>Name </th>
        <th>Expression </th>
        <th>Precondition </th>
        <th>Semantics </th>
        <th>Postcondition </th>
    </tr>
    <tr>
        <td valign="top">Default constructor </td>
        <td valign="top"><pre>X a()</pre>
        </td>
        <td valign="top">&nbsp; </td>
        <td valign="top">Construct an empty <font size="2"
        face="Courier New">BoundIO</font></td>
        <td valign="top">&nbsp;</td>
    </tr>
    <tr>
        <td valign="top">Copy constructor </td>
        <td valign="top"><pre>X a(constX &amp;b)</pre>
        </td>
        <td valign="top">&nbsp; </td>
        <td valign="top">Copy construct a <font size="2"
        face="Courier New">BoundIO</font>.</td>
        <td valign="top">&nbsp;</td>
    </tr>
    <tr>
        <td valign="top">Assignment operator</td>
        <td valign="top"><pre>X&amp; operator=(const X&amp;b)</pre>
        </td>
        <td valign="top">&nbsp; </td>
        <td valign="top">Assignment copy</td>
        <td valign="top">&nbsp;</td>
    </tr>
    <tr>
        <td valign="top">Binding operator</td>
        <td valign="top"><font size="2" face="Courier New">template&lt;class
        T&gt; void operator==(T &amp;memberToBind)</font> </td>
        <td valign="top">&nbsp; </td>
        <td valign="top">Create an association between SQL column
        names / parameter numbers and object field names. This is
        done by inserting elements into the <font size="2"
        face="Courier New">BoundIOs</font> map. The syntax for
        inserting elements into the BoundIOs map is to call <font
        size="2" face="Courier New">BoundIOs[&quot;SQL FIELD NAME&quot;
        / SQL Parameter Number] == RowObject.FieldName</font>.
        This invokes the<font size="2" face="Courier New"> ==</font>
        operator for the<font size="2" face="Courier New">
        BoundIO</font> class. We use the<font size="2"
        face="Courier New"> == </font>syntax here as a mnemonic
        to remind end users that this is a two way association.
        Once the association is created, values can either be
        read from the database to the field, or written from the
        field to the database. Internally, this syntax does two
        things. First, the <font size="2" face="Courier New">operator==()
        </font>analyzes the <font size="2" face="Courier New">RowObject.FieldName</font>
        parameter to determine what type of field we are binding
        to and the memory address of the given field name (<strong>there
        are some restrictions! see </strong><a href="#foot2"><strong>[1]</strong></a>).
        Based on this information, <font size="2"
        face="Courier New">operator==()</font>, determines the <font
        size="2" face="Courier New">SQL_TYPE</font>, the <font
        size="2" face="Courier New">SQL_C_TYPE</font>, the data
        size, and the address to pass to <font size="2"
        face="Courier New">SQLBindCol()</font> or <font size="2"
        face="Courier New">SQLBindParam()</font>. All of this
        information gets stored in what is known as a <font
        size="2" face="Courier New">BoundIO</font> object.
        Finally, the resulting <font size="2" face="Courier New">BoundIO</font>
        object is inserted into the<font size="2"
        face="Courier New"> BoundIOs</font> map using the <font
        size="2" face="Courier New">BoundIOs::operator[]() </font>described
        below.</td>
        <td valign="top">&nbsp;</td>
    </tr>
    <tr>
        <td valign="top">Column Indicator</td>
        <td valign="top"><pre>bool IsColumn()</pre>
        </td>
        <td valign="top">&nbsp; </td>
        <td valign="top">Returns <font size="2"
        face="Courier New">true</font> if this <font size="2"
        face="Courier New">BoundIO </font>represents a SQL field.</td>
        <td valign="top">&nbsp;</td>
    </tr>
    <tr>
        <td valign="top">Parameter Indicator</td>
        <td valign="top"><pre>bool IsParam()</pre>
        </td>
        <td valign="top">&nbsp; </td>
        <td valign="top">Returns <font size="2"
        face="Courier New">true </font>if this <font size="2"
        face="Courier New">BoundIO</font> represents a SQL
        parameter.</td>
        <td valign="top">&nbsp;</td>
    </tr>
    <tr>
        <td valign="top">NULL data Indicator</td>
        <td valign="top"><pre>bool IsNull()</pre>
        </td>
        <td valign="top">&nbsp; </td>
        <td valign="top">Returns <font size="2"
        face="Courier New">true </font>if value held in this
        field by the current <font size="2" face="Courier New">rowbuf</font>
        object holds <font size="2" face="Courier New">NULL</font>
        data. Typically this is used by the <a
        href="SelVal.htm"><font size="2" face="Courier New">SelVal</font></a>
        function.</td>
        <td valign="top">&nbsp;</td>
    </tr>
</table>

<h3>Expression semantics: BoundIOs</h3>

<p>As per STL <a
href="http://www.sgi.com/tech/stl/Map.html"><font size="2"
face="Courier New">map</font></a><font size="2"
face="Courier New"> </font>but with the following modifications:</p>

<table border="1">
    <tr>
        <th>Name </th>
        <th>Expression </th>
        <th>Precondition </th>
        <th>Semantics </th>
        <th>Postcondition </th>
    </tr>
    <tr>
        <td valign="top">Parameter operator</td>
        <td valign="top"><pre>BoundIO &amp;operator[](unsigned int paramNum)</pre>
        </td>
        <td valign="top">&nbsp; </td>
        <td valign="top">This is used to insert/find a <font
        size="2" face="Courier New">BoundIO</font> in the <font
        size="2" face="Courier New">BoundIO</font>s map using a
        stringified version of the number as the key. If this
        operator does not find an existing <font size="2"
        face="Courier New">BoundIO</font> with the given key, it
        creates a new <font size="2" face="Courier New">BoundIO</font>
        object that is marked as a SQL <strong>parameter</strong>
        with the name given by the key string. This new <font
        size="2" face="Courier New">BoundIO</font> object is then
        inserted into the<font size="2" face="Courier New">
        BoundIOs</font> list. SQL parameters are represented in
        the SQL string passed to a <font size="2"
        face="Courier New">DBView</font> by a <font size="2"
        face="Courier New">'(?)'</font>. </td>
        <td valign="top">&nbsp;</td>
    </tr>
    <tr>
        <td valign="top">Column operator</td>
        <td valign="top"><pre>BoundIO &amp;operator[](const string &amp;colName)</pre>
        </td>
        <td valign="top">&nbsp; </td>
        <td valign="top">This is used to insert/find a <font
        size="2" face="Courier New">BoundIO</font> in the <font
        size="2" face="Courier New">BoundIOs </font>map using a
        the given string as the key. If this operator does not
        find an existing<font size="2" face="Courier New">
        BoundIO </font>with the given key, it creates a new <font
        size="2" face="Courier New">BoundIO</font> object that is
        marked as a SQL <strong>field</strong> with the name
        given by the key string. This new <font size="2"
        face="Courier New">BoundIO</font> object is then inserted
        into the <font size="2" face="Courier New">BoundIOs</font>
        list.</td>
        <td valign="top">&nbsp;</td>
    </tr>
</table>

<h3>Notes</h3>

<p><a name="foot2">[1] </a>If you are only using this BCA/BPA
with a <font size="2" face="Courier New">DBView</font> template
then the field you are binding to can be either statically or
dynamically allocated by the <font size="2" face="Courier New">DataObj,</font>
as long as the object has a correct copy and assigment operator
for copying the field. <strong>If you want to use an </strong><font
size="2" face="Courier New"><strong>IndexedDBView </strong></font><strong>with
your BCA, then the field must be a statically allocated member of
the </strong><font size="2" face="Courier New"><strong>DataObj</strong></font><strong>.</strong>
The reason for this is that <font size="2" face="Courier New">IndexedDBView</font>
computes a relative fieldoffset via <font size="2"
face="Courier New">&amp;(rowbuf.Field) - &amp;rowbuf</font> that
it uses for comparison functions for automatic indexing and
update routines in the <font size="2" face="Courier New">IndexedDBView</font>.
This kind of offset logic is only valid if the field is not
dynamically allocated via <font size="2" face="Courier New">operator
new() </font>or<font size="2" face="Courier"> malloc()</font>.
So, if you want to use <font size="2" face="Courier New">IndexedDBView</font>
we recommend that your fields be statically allocated members. (In
fact, there is a complicated way around this restriction if you
allocate your fields as a contiguous block. You can check out <font
size="2" face="Fixedsys">DynamicRowBCA</font> in <font size="2"
face="Courier New">DynaDBView.h</font> and the <font size="2"
face="Courier New">data_ptr()</font> function that we define for
the <font size="2" face="Courier New">variant_row</font> class in
<font size="2" face="Courier New">variant_row.h</font> for an
example of how we worked around this to accomodate dynamically
sized rows. The result is not for the faint of heart.) <strong>Here
is an example of what we are talking about:</strong></p>

<pre>#define DYNAMIC_SIZE 100 
class BCADynamicObj;
class Dynamic {
	char **szDynamicString;

public:

	Dynamic() {
		szDynamicString = (char **)malloc(DYNAMIC_SIZE);
	}

	Dynamic(const Dynamic &amp;other) {
		szDynamicString = (char **)malloc(DYNAMIC_SIZE);	
		memcpy(szDynamicString, other.szDynamicString, DYNAMIC_SIZE);
	}

	const Dynamic &amp; operator=(const Dynamic &amp;other) {
		if (this != &amp;other) {
			if (szDynamicString == NULL)
				szDynamicString = (char **)malloc(DYNAMIC_SIZE);	
			memcpy(szDynamicString, other.szDynamicString, DYNAMIC_SIZE);
		}

	}
	

	~Dynamic() {
		if (szDynamicString != NULL)
			free(szDynamicString);
	}

	friend class BCADynamicObj;
};

// This BCA will work with DBView but not IndexedDBView because szDynamicString is dynamic
class BCADynamicObj
{
public:
	void operator()(BoundIOs &amp;boundIOs, Dynamic &amp;rowbuf)
    	{
	   boundIOs[&quot;STRING_VALUE&quot;] == *(rowbuf.szDynamicString);
	}
};
</pre>

<h3>See also</h3>

<p><a href="BPA.htm"><font size="2" face="Courier New">BPA</font></a><font
size="2" face="Courier New">, </font><a href="BCA.htm"><font
size="2" face="Courier New">BCA</font></a><font size="2"
face="Courier New">, </font><a href="InsVal.htm"><font size="2"
face="Courier New">InsVal</font></a><font size="2"
face="Courier New">, </font><a href="SelVal.htm"><font size="2"
face="Courier New">SelVal</font></a><font size="2"
face="Courier New">, </font><a href="DBView.htm"><font
size="2" face="Courier New">DBView</font></a><font size="2"
face="Courier New">, </font><a
href="IndexedDBView.htm"><font size="2"
face="Courier New">IndexedDBView</font><font size="2"><!--start footer--></font></a></p>


<hr>

<p><a href="index.htm"><img src="dtl_home.gif" alt="[DTL Home]"
width="54" height="54"></a> <br>
</p>

<p>Copyright 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -