Understanding visual c ++ extensions for ado

Source: Internet
Author: User

[Preface]

When we use visual c ++ for ADO programming, processing the variant field type is a headache. The common practice is to first convert the variant type to a similar C ++ type, and then store the converted data in a class or structure. Even so, the processing of the variant data type also affects the program performance to a certain extent.

ADO provides us with an interface that allows us to directly read data locally, bypassing the processing of complex variant data types. In addition, ADO defines a set of preprocessing macros to simplify the use of interfaces. Using this tool will make programming easier and more efficient.

Generally, we obtain the recordset dataset from ado, define a C/C ++ structure type, and then bind the record in recordset to the structure member variable. When the variant type is encountered, the situation becomes complicated. You must solve the problem of converting the variant data type (database) to the C/C ++ data type (local. Visual c ++ extensions for ADO (easy to describe, hereinafter referred to as adoext) aims to make it easy.

[Iadorecordbinding interface Introduction]

Adoext binds the fields in the recordset record set to the C/C ++ variable. Once the data in the current row of the recordset changes, the data will be immediately copied to the bound C/C ++ variable. Data is converted to the specified C/C ++ data type as needed.

The bindtorecordset member method of the iadorecordbinding interface is used to bind database fields to local C/C ++ variables. If you want to add a record to the recordset, you can use the addnew method. The update method is used to update and upgrade the bound C/C ++ variable data to the database.

We don't have to worry about implementing the iadorecordbinding interface. The recordset object quietly completes all this behind the scenes.

[Binding entries]

Adoext maps the field type of the recordset object to the local C/C ++ variable, the process definition that maps a database field to a C/C ++ variable is called a binding entries ). The binding is completed by a macro. The types that can be bound include numeric, fixed length, and variable length data. The basic process of binding is to define the class derived from cadorecordbinding (cadorecordbinding class itself is actually a set of macro definitions), and use a specific macro in the class to bind data. Then, declare the corresponding C/C ++ variable in the class.

Ado maps macro parameters to an ole db dbbinding structure internally, and creates an ole db access object to manage data movement and format conversion between fields and variables. The data definition of ole db consists of three parts: a buffer for storing data, a buffer for marking the data access status, how to extract the State bit of the variable, and the length of the data.

[Header file inclusion]
To use visual c ++ adoext, You need to include the following header files in your application:
# Include <icrsint. h>

[Bind the recordset field]
■ Create a class derived from cadorecordsetbinding.

■ Set the binding unit in the derived class and define the corresponding C/C ++ variable. These binding units are defined between begin_ado_binding and end_ado_binding. Do not place commas or semicolons between macro definitions. These tasks are automatically implemented by the macro internally.

■ Specify a binding unit for each database Field mapped to the C/C ++ variable. Select one macro from ado_fixed_length_entry, ado_numeric_entry, or ado_variable_length_entry as needed, and enter the correct parameters.

■ Create an instance of this class in your reference program. Obtain the iadorecordbinding interface from recordset. Then, bindtorecordset is called to bind data.

[Interface method definition]
The iadorecordbinding interface has three methods: bindtorecordset, addnew, and update. These methods have only one pointer type parameter, which points to a class instance derived from cadorecordbinding. In fact, the addnew and updage Methods call methods of the same name in ADO respectively.

Syntax:

The bindtorecordset method binds the recordset field to the C/C ++ variable.

Bindtorecordset (cadorecordbinding * binding)

The addnew method calls its method of the same name. The addnew method in ADO adds a new record to the recordset.

Addnew (cadorecordbinding * binding)

The update method calls the method with the same name in ADO to update the recordset data.

Update (cadorecordbinding * binding)

[Understand the Macros in the bound unit]
The binding Unit defines the relationship between the recordset field and the variable. Macro begin_ado_binding (class) (start macro) and end_ado_binding () (end macro) define a group of binding units.

Macros in the binding Unit provide support for the following field types:
■ Fixed-length data. For example, addate or adboolean
■ Numeric data. For example, adtinyint, adinteger, and addouble
■ Variable-length data. Such as adchar, advarchar, and advarbinary

All numeric data, except the advarnumeric type, are also fixed-length data.

Different macro definitions use different types of parameters, so that you can exclude uninterested binding information.

■ Start data binding

Begin_ado_binding (class)

■ Fixed-length data

Ado_fixed_length_entry (ordinal, ype, buffer, status, modify)
Ado_fixed_length_entry2 (ordinal, ype, buffer, modify)

■ Numeric data

Ado_numeric_entry (ordinal, datatype, buffer, precision, scale, status, modify)
Ado_numeric_entry2 (ordinal, ype, buffer, precision, scale, modify)

■ Variable-length data

Ado_variable_length_entry (ordinal, ype, buffer, size, status, length, modify)
Ado_variable_length_entry2 (ordinal, ype, buffer, size, status, modify)
Ado_variable_length_entry3 (ordinal, ype, buffer, size, length, modify)
Ado_variable_length_entry4 (ordinal, ype, buffer, size, modify)

■ End Data Binding

End_ado_binding ()

---------------------------------------------------
Parameter: Description

Class: the class where the bound unit and C/C ++ variable definitions are located.
Ordinal: sequence number of the recordset field counted from 1. This field corresponds to the specified C/C ++ variable.
Datatype: C/C ++ data type equivalent to the Data Type in ADO. The corresponding recordset field is converted to this data type as needed.
Buffer: the buffer name used to store the recordset field.
Size: the maximum size of the buffer.
Status: Status bit. Indicates the validity of the buffer content and whether the field conversion is successful. There are two important values. One is adfldok, indicating that the conversion is successful; the other is adfldnull, indicating that the field value is null. For more status values, see msdn
Modify: boolean type. If it is true, ADO allows updating data in the buffer. If it is false, the data is read-only.
Precision: the precision of the numeric type.
Scale: number of decimal places of the numeric type. Number of decimal places in a numeric variable.
Length: a four-Byte variable. The actual length of the data in the buffer zone.
----------------------------------------------------

[Visual c ++ extensions routine]
// Introduce the msado15.dll file to declare the ADO Type Library
# Import "C:/program files/common files/system/ADO/msado15.dll" no_namespace Rename ("EOF", "endoffile ")

# Include <stdio. h>
# Include <icrsint. h> // contains the icrsint. h header file.

// _ Com_smartptr_typedef macro defines a _ com_ptr_t smart pointer iadorecordbingingptr
_ Com_smartptr_typedef (iadorecordbinding, _ uuidof (iadorecordbinding ));

// Define a test function
Inline void testhr (hresult _ hr) {if failed (_ hr) _ com_issue_error (_ hr );}

// Define a class derived from cadorecordbinding
Class ccustomrs: Public cadorecordbinding
{
// Start Data Type Binding
Begin_ado_binding (ccustomrs)
// Bind the 2nd advarchar fields of recordset to the C/C ++ variable m_ch_fname.
Ado_variable_length_entry2 (2, advarchar, m_ch_fname,
Sizeof (m_ch_fname), m_ul_fnamestatus, false)
Ado_variable_length_entry2 (4, advarchar, m_ch_lname,
Sizeof (m_ch_lname), m_ul_lnamestatus, false)
// End binding
End_ado_binding ()

// Then define the C/C ++ variables used in the above macro
Public:
Char m_ch_fname [22];
Char m_ch_lname [32];
Ulong m_ul_fnamestatus;
Ulong m_ul_lnamestatus;
};

// Start Program Execution
Void main (void)
{
: Coinitialize (null); // initialize the COM Object
Try
{
// Typedef _ com_ptr_t <_ recordset, _ uuidof (_ recordset)> _ recordsetptr: A smart pointer to a _ recordset
_ Recordsetptr PRS ("ADODB. recordset ");

// Define a ccustomrs: Public cadorecordbinding class instance
Ccustomrs RS;

// Specify the iadorecordbindingptr interface type object picrs to the PRS object to realize the association between interfaces and objects.
Iadorecordbindingptr picrs (PRS );

// Call the _ recordset open method to obtain the recordset object
PRS-> open ("select * from employee order by lname ",
"DSN = pubs; uid = sa; Pwd = ;",
Adopenstatic, adlockoptimistic, adshorttext );

// Use the macro definition in the ccustomrs class to bind data.
// If the binding succeeds, we can use the attributes of the RS object.
Testhr (picrs-> bindtorecordset (& RS ));

// Note that the endoffile corresponds to the rename ("EOF", "endoffile") in the preceding Import Statement, which is actually EOF. Rename is used to prevent name conflicts.
While (! PRS-> endoffile)
{
// Process data in the ccustomrs C ++ instance variables.
Printf ("name = % S % s/n ",
(Rs. m_ul_fnamestatus = adfldok? Rs. m_ch_fname: "<error> "),
(Rs. m_ul_lnamestatus = adfldok? Rs. m_ch_lname: "<error> "));

// Move to the next row of the recordset.
// Fields in the new row will automatically be
// Placed in the ccustomrs C ++ instance variables.

PRS-> movenext ();
}
}
Catch (_ com_error & E)
{
Printf ("error:/N ");
Printf ("code = % 08lx/N", E. Error ());
Printf ("meaning = % s/n", E. errormessage ());
Printf ("Source = % s/n", (lpcstr) E. Source ());
Printf ("Description = % s/n", (lpcstr) E. Description ());
}

// Clear the COM object instance
: Couninitialize ();
}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.