1 /* 2 * podbc.h 3 * 4 * Virteos ODBC Implementation for PWLib Library. 5 * 6 * Virteos is a Trade Mark of ISVO (Asia) Pte Ltd. 7 * 8 * Copyright (c) 2005 ISVO (Asia) Pte Ltd. All Rights Reserved. 9 * 10 * The contents of this file are subject to the Mozilla Public License 11 * Version 1.0 (the "License"); you may not use this file except in 12 * compliance with the License. You may obtain a copy of the License at 13 * http://www.mozilla.org/MPL/ 14 * 15 * Software distributed under the License is distributed on an "AS IS" 16 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See 17 * the License for the specific language governing rights and limitations 18 * under the License. 19 * 20 * 21 * The Original Code is derived from and used in conjunction with the 22 * pwlib Libaray of the OpenH323 Project (www.openh323.org/) 23 * 24 * The Initial Developer of the Original Code is ISVO (Asia) Pte Ltd. 25 * 26 * Portions: Simple ODBC Wrapper Article www.codeproject.com 27 * 28 * Contributor(s): ______________________________________. 29 * 30 * $Revision: 24177 $ 31 * $Author: rjongbloed $ 32 * $Date: 2010-04-05 06:52:04 -0500 (Mon, 05 Apr 2010) $ 33 */ 34 35 /** 36 ODBC Support for PWLIB 37 38 Class Description 39 PODBC : Main DataBase Connection Class (Derive Class for Error Handling) 40 PODBC::ConnectData : Class used to store information for Connecting to DataSource 41 PODBC::Table : Retrieved Data Structure (RecordSet) from Table or Select SQL Query 42 PODBC::Row : Record Pointer Class for the PODBC::Table (PArray of Fields) 43 PODBC::Field : Database Field Information (Field Structure & Data(Bound)) 44 PODBC::Field:Bind : DataTypes Bound to the RecordSet (change with Record Navigation) 45 PDSNConnection : Derived Class of PODBC for ODBC Configured Connections 46 PODBCStmt : Wrapper for RecordSet (Internal) 47 PODBCRecord : Handle Retrieve/Post/Bind Data from RecordSet (Internal) 48 49 Example of Use 50 51 <pre><code> 52 PODBC link; 53 PODBC::ConnectData data; 54 data.DBPath = "test.mdb"; 55 56 if (link.DataSource(PODBC::MSAccess,data)) { 57 // Load a Database Table (could also be a SELECT Query) 58 PODBC::Table table(&link,"FooTable"); 59 // Bind to Column 1 60 PODBC::Field & field = table.Column(1): 61 // Display Contents 62 cout << " Value " << field.AsString(); << endl; 63 // Move to Record 2 of fooTable 64 table[2]; 65 // Display contents of Record 2 Column 1 66 cout << " Value " << field.AsString(); << endl; 67 // Set New Value for Record 2 Field 1 of FooTable 68 field.SetValue("NewValue"); 69 // Send Update to Database. 70 field.Post(); 71 72 // To Add New Record.(with Default Values) 73 table.NewRow(); 74 // Alter the Value of field 1 75 field.SetValue("Somethng"); 76 // Post the New Field to the Database 77 field.Post(); 78 79 // Run General Query; 80 PString SQLStmt = "INSERT foo into [FooTable] ..." 81 Link.Query(SQLStmt); 82 } 83 // Disconnect from ODBC Source 84 link.Disconnect(); 85 86 </code></pre> 87 */ 88 //-- 89 90 #ifndef PTLIB_PODBC_H 91 #define PTLIB_PODBC_H 92 93 #if _MSC_VER > 1000 94 #pragma once 95 #endif // _MSC_VER > 1000 96 97 98 #if defined(P_ODBC) && !defined(_WIN32_WCE) 99 100 #include <odbcinst.h> 101 #include <sql.h> 102 #include <sqlext.h> 103 104 #ifdef _MSC_VER 105 #include <tchar.h> 106 #pragma comment(lib,"odbc32.lib") 107 #pragma comment(lib,"odbcCP32.lib") 108 #else 109 110 #ifdef UNICODE 111 typedef WCHAR TCHAR; 112 typedef LPWSTR LPTSTR; 113 typedef LPCWSTR LPCTSTR; 114 // Needs a definition one day ... #define _T(x) 115 #else 116 typedef CHAR TCHAR; 117 typedef LPSTR LPTSTR; 118 typedef LPCSTR LPCTSTR; 119 #define _T(x) x 120 #endif 121 122 #endif // _MSC_VER 123 124 // Max SQL String Data Length 125 #define MAX_DATA_LEN 1024 126 127 /** PODBC Statement Class 128 This class is use to parse store queries and Fetch data 129 It is not designed to process the actual data only access it. 130 PODBC::Record is used to Bind/Retrieve/Store Data Elements. . 131 */ 132 133 134 class PODBC; 135 class PODBCRecord; 136 137 138 class PODBCStmt : public PObject 139 { 140 PCLASSINFO(PODBCStmt, PObject); 141 142 public: 143 /**@name Constructor/Deconstructor */ 144 //@{ 145 /** Constructor PODBC (Datasources call) or thro' DSNConnection (Connection call). 146 In General this class is constructed within the PODBC::Table Class. 147 */ 148 PODBCStmt(PODBC * odbc); 149 150 /** Deconstructor. This Class should be available for the duration of which 151 a specific query/table is required and be deconstructed at the time of 152 the PODBC::Table deconstruction. 153 */ 154 ~PODBCStmt(); 155 //@} 156 157 /**@name Handles */ 158 //@{ 159 /** Statement Handle Created by the Query Function. 160 */ HSTMT()161 operator HSTMT() { return m_hStmt; }; 162 //@} 163 164 165 /**@name Data Management */ 166 //@{ 167 /** IsValid Checks to ensure a Handle has been allocated and 168 is effective. 169 */ 170 PBoolean IsValid(); 171 172 /** GetChangedRowCount retreives the number of rows updated/altered by 173 UPDATE/INSERT statements. 174 */ 175 DWORD GetChangedRowCount(void); 176 177 /** Query function is the Main function to pass SQL statements to retreive/ 178 add/Modify database data. It accepts generally acceptable SQL Statements. 179 ie. Select * from [table-x] 180 */ 181 PBoolean Query(PString strSQL); 182 //@} 183 184 /**@name Data Retrieval */ 185 //@{ 186 /** Fetch General call to retreive the next row of data. 187 */ 188 PBoolean Fetch(); 189 190 /** FetchRow More detailed fetching of Rows. This allows you to fetch an 191 Absolute row or a row relative to the current row fetched. 192 */ 193 PBoolean FetchRow(PINDEX nRow,PBoolean Absolute=1); 194 195 /** FetchPrevious Fetch the previous Row from current row. 196 */ 197 PBoolean FetchPrevious(); 198 199 /** FetchNext: Fetch the Next row. 200 */ 201 PBoolean FetchNext(); 202 203 /** FetchFirst Fetch the First row in the RecordSet 204 */ 205 PBoolean FetchFirst(); 206 207 /** FetchLast Fetch the Last row in the RecordSet 208 */ 209 PBoolean FetchLast(); 210 211 /** Cancel the Current Statement 212 */ 213 PBoolean Cancel(); 214 //@} 215 216 /**@name Utilities */ 217 //@{ 218 /** Retreive the List of Tables from the current Datasource 219 The option field can be used to specify the Table Types 220 ie "TABLE" for Tables or "VIEW" for preconfigured datasource 221 queries. *Further investigation is required* 222 */ 223 PStringArray TableList(PString option = ""); 224 225 226 /** Is the SQL Instruction OK 227 If an Error is detected then GetLastError is called 228 to Retrieve the SQL Error Information and Returns false 229 */ 230 PBoolean SQL_OK(SQLRETURN res); 231 232 /** Get the Last Error 233 This returns the Error ID & String to PODBC::OnSQLError 234 */ 235 void GetLastError(); 236 GetLink()237 PODBC * GetLink() const { return odbclink; } GetDBase()238 int GetDBase() const { return dbase; } 239 //@} 240 241 protected: 242 HSTMT m_hStmt; 243 PODBC * odbclink; /// Reference to the PODBC Class 244 int dbase; /// Database Type connecting to 245 }; 246 247 248 249 /** PODBC Class 250 The Main ODBC class. This Class should be used in the there is 251 not a preconfigured DSN setup in the MDAC. This class will use 252 the applicable ODBC drivers to connect to a compliant Datasource. 253 It Supports a wide variety of Datasources but others can added 254 by simply creating your custom connection string and then calling 255 PODBC::Connect. For Defined sources the PODBC::DataSource function 256 should be used. 257 */ 258 259 class PODBC : public PObject 260 { 261 PCLASSINFO(PODBC, PObject); 262 263 public: 264 /**@name Constructor/Deconstructor */ 265 //@{ 266 /** Constructor 267 */ 268 PODBC(); 269 270 /** Deconstructor 271 */ 272 ~PODBC(); 273 //@} 274 275 /**@name Enumerators */ 276 //@{ 277 /** Raw SQL data type codes Refer <sql.h> SQL_* 278 This list is not inclusive. If an item 279 is not listed or Unknown it is treated 280 as a character string. 281 282 */ 283 enum FieldTypes 284 { 285 LongVarChar =-1, 286 Binary =-2, 287 VarBinary =-3, 288 LongVarBinary =-4, 289 BigInt =-5, 290 TinyInt =-6, 291 Bit =-7, /// Boolean 292 Guid =-11, 293 Unknown = 0, 294 Char = 1, 295 Numeric = 2, 296 Decimal = 3, 297 Integer = 4, 298 SmallInt = 5, 299 Float = 6, 300 Real = 7, 301 Double = 8, 302 DateTime = 9, 303 VarChar =12, 304 Date =91, /// Structure 305 Time =92, /// Structure 306 TimeStamp =93 /// Structure PTime 307 }; 308 309 /** Converted Pwlib Field Types. 310 Data is stored as a PString 311 and the pwType enumerator indicates 312 the conversion required on the PODBC::Field. 313 */ 314 enum PwType 315 { 316 oPString, // String Value 317 oBOOL, // Boolean 318 ochar, // Character 319 oshort, // Short 320 oint, // Integer use .AsInteger() 321 olong, // long 322 odouble, // Double use .AsReal() 323 oPBYTEArray,// Binary Data 324 oPInt64, // BigInt use .AsInt64() 325 oPTime, // Time use PTime( "Value" ) 326 oPGUID // GUID use PGUID( "Value" ) To Be Implemented...? 327 }; 328 329 /** Datasources that are supported by this implementation 330 used in the PODBC::DataSource Function. 331 */ 332 333 enum DataSources 334 { 335 mySQL, 336 MSSQL, 337 Oracle, 338 IBM_DB2, 339 DBASE, 340 Paradox, 341 Excel, 342 Ascii, 343 Foxpro, 344 MSAccess, 345 postgreSQL 346 }; 347 348 /** MSSQL protocols.If your interested? 349 */ 350 enum MSSQLProtocols 351 { 352 MSSQLNamedPipes, 353 MSSQLWinSock, 354 MSSQLIPX, 355 MSSQLBanyan, 356 MSSQLRPC 357 }; 358 359 //@} 360 361 /**@name Connection Class */ 362 //@{ 363 /** This class is a multipurpose use 364 class for storing parameters when 365 initiating connection to DataSource. 366 Not all field are required. By default 367 all non-essential params are set to a 368 datasource specific default value. 369 */ 370 class ConnectData 371 { 372 public: 373 PFilePath DBPath; /// Database file Path (not Oracle,xxSQL) 374 PString DefDir; /// Used with Paradox/DBase/Excel (& mySQL db) 375 PString User; /// UserName 376 PString Pass; /// Password 377 PBoolean Excl_Trust; /// Whether Datasource is locked or Trusted. 378 PString Host; /// URL for Host Datasouce xxSQL 379 int Port; /// Port to connect to mySQL 380 int opt; /// General Option Value.mySQL & Paradox 381 }; 382 //@} 383 384 385 /**@name Database Field Class */ 386 //@{ 387 /** Class for Field Data 388 */ 389 class Row; 390 class Field : public PObject 391 { 392 PCLASSINFO(Field, PObject); 393 public: 394 395 /** SQL compliant Bound DataTypes. 396 The appropriate Field is bound 397 to the SQL Driver and alters 398 when a new record is fetched. 399 */ 400 class Bind 401 { 402 public: 403 PString sbin; /// Strings & Binary Data 404 PString sbinlong; /// Long Data 405 short int ssint; /// Short Integer SQLSMALLINT 406 long int slint; /// Integer SQLINTEGER 407 double sdoub; /// Double SQLDOUBLE 408 unsigned char sbit; /// Bit SQLCHAR 409 unsigned char * suchar; /// Unsigned char SQLCHAR * 410 PInt64 sbint; /// Bit Integer SQLBIGINT 411 DATE_STRUCT date; /// Date Structure 412 TIME_STRUCT time; /// Time Structure 413 TIMESTAMP_STRUCT timestamp; /// TimeStamp Structure 414 SQLGUID guid; /// GUID Structure (not Fully Supported) 415 SQLLEN dataLen; /// DataLength pointer (StrLen_or_Ind for Col Bind) 416 }; 417 418 /** Post the Changes back to the Database 419 */ 420 PBoolean Post(); 421 422 /** Returns a String representation of the field. 423 */ 424 PString operator=(const PString & str); 425 426 /** Display the Field Data as String 427 */ 428 PString AsString(); 429 430 /** Set the Field Data. Note a Post() must be called 431 to post the changes back to the database. 432 */ 433 void SetValue(PString value); /// Set the Value 434 435 /** Initialise/Set the Default values for Field of New Record 436 */ 437 void SetDefaultValues(); 438 439 /** DataFragment Data is broken into fragment to be passed 440 to the Database 441 */ 442 PBoolean DataFragment(PString & Buffer ,PINDEX & fragment, SQLINTEGER & size); 443 444 /** Settings 445 */ 446 /// Data 447 Bind Data; /// Data Field to ODBC Bind to 448 PwType Type; /// pwlib Type for conversion 449 FieldTypes ODBCType; /// ODBC Type (For saving/Conversion) 450 451 /// Column 452 PString Name; /// Column Name 453 PINDEX col; /// Column Number (For Saving/Conversion) 454 455 /// Column Attributes 456 PBoolean isReadOnly; /// Is Field Readonly 457 PBoolean isNullable; /// Allows Nulls 458 PBoolean isAutoInc; /// Field AutoIncrements 459 int Decimals; /// Number of decimal places to Round 460 PBoolean LongData; /// LongData Length is Required 461 462 /// RecordHolder Reference 463 Row * row; /// Back Reference to the Row 464 }; 465 //@} 466 467 468 /**@name Database Row Class */ 469 //@{ 470 /** This class functions as a simple wrapper 471 of the PODBCStmt class to fetch/Save 472 data to the Datasource. Data is fetched 473 on a need to basis and not cached except 474 to create a new row. 475 */ 476 class Row : public PObject 477 { 478 public: 479 480 /** Constructor 481 Create a Dummy row of data to act as a 482 Record Marker. Template Field are created 483 and Stored in a PARRAY. 484 */ 485 Row(PODBCStmt * stmt); 486 487 /** Retrieve Field Data given the specifed column. 488 Note: Columns atart at 1 and not exceed PODBCStmt::GetColumnCount() 489 */ 490 Field & Column(PINDEX col); 491 492 /** Retreive Field Data given the Column Name 493 */ 494 Field & Column(PString name); 495 496 /** Retrieve the Column Names 497 */ 498 PStringArray ColumnNames(); 499 500 /** Columns. The Number of Columns in the RecordSet 501 */ 502 PINDEX Columns(); 503 504 /** Rows The Number of Rows 505 */ 506 PINDEX Rows(); 507 508 /** Retrieve Field Data given specified column 509 */ 510 Field & operator[] (PINDEX col); 511 512 /** Retrieve Field Data given the column Name. 513 */ 514 Field & operator[] (PString col); 515 516 /** Navigate to Specified Row 517 */ 518 PBoolean Navigate(PINDEX row); 519 520 /** SetNewRow Set New Row for input 521 */ 522 void SetNewRow(); 523 524 /** Post the Row back to the Database. 525 When Row::NewRow is true the data 526 can be posted back to the Database; 527 If Edit Invoked then releasea the 528 RowHandler for Navigation. 529 */ 530 PBoolean Post(); 531 532 /** Delete the Current Record from the 533 RecordSet 534 */ 535 PBoolean Delete(PINDEX row =0); 536 537 PODBCRecord * rec; /// Record Structure 538 539 PINDEX CurRow; /// Current Row 540 PBoolean NewRow; /// Flag to Indicate New Row (requires either Post or Delete) 541 PINDEX RowCount; /// Number of Rows. 542 543 protected: 544 PArray<Field> Fields; /// PODBC::Field Array Cache (Used for New Row) 545 }; 546 //@} 547 548 /** PODBC::Table 549 This is the main Class to access Data returned by a Select Query. 550 The Table does not actually create the RecordSet but acts as a wrapper 551 to the driver to access the cached data in the Driver. 552 */ 553 class Table : public PObject 554 { 555 public: 556 557 /**@name Constructor/Deconstructor */ 558 //@{ 559 /** Constructor 560 Using the HDBC and TableName/Select SQL Query 561 creates a virtual Table in the OBDC driver. 562 */ 563 Table(PODBC * odbc, PString Query); 564 565 /** Deconstructor 566 */ 567 ~Table(); 568 //@} 569 570 /**@name Data Storage */ 571 //@{ 572 /** Add New Row 573 */ 574 Row NewRow(); 575 576 /** Delete Row 0 indicates Current Row 577 */ 578 PBoolean DeleteRow(PINDEX row = 0); 579 580 /** Post Update back to Database 581 */ 582 PBoolean Post(); 583 //@} 584 585 /**@name Utilities */ 586 //@{ 587 /** Rows. Returns the Number of Rows in the Resultant RecordSet 588 */ 589 PINDEX Rows(); 590 591 /** Columns. Returns the Number of Columns in the Resultant RecordSet 592 */ 593 PINDEX Columns(); 594 595 /** ColumnNames. Return the list of column Names of the Resultant RecordSet 596 */ 597 PStringArray ColumnNames(); 598 599 /** Obtain the Record Handler. This can be used as a Template to obtain 600 Record Information. A call to tablename[i] will update the recordHandler 601 with the Values contained in i Record. 602 */ 603 Row & RecordHandler(); 604 605 /** Row return the fetched row in the Cached RecordSet. An Array of PODBC::Field 606 */ 607 Row & operator[] (PINDEX row); 608 609 /** Returns the Field data at a predetermined position in the Resultant 610 RecordSet. It Fetches the Row than isolates the Column from the fetched 611 data. 612 */ 613 Field & operator() (PINDEX row, PINDEX col); 614 615 /** Returns the indicated Column Holder for the RecordSet, 616 This can be used for iterative Row calls. 617 */ 618 Field & Column(PINDEX col); 619 620 /** Returns the indicated Column Holder Name for the RecordSet, 621 */ 622 Field & Column(PString Name); 623 //@} 624 625 protected: 626 PODBCStmt stmt; /// ODBC Fetched Statement Info 627 PString tableName; /// Name of the Fetched Table (if used in Constructor) 628 Row * RowHandler; /// row Handler 629 }; 630 631 /**@name Data Queries */ 632 //@{ 633 /** Load a specified Table/Stored Query or 634 General 'SELECT' SQL Query. 635 This function will return a PODBC::Table for 636 further analysis. Do Not Use this Function for 637 any other SQL statements other than SELECT. 638 */ 639 Table LoadTable(PString table); 640 641 /** Added Information to the DataSource. Use this 642 function if you just want to use a SQL statement 643 to add data to a datasource without retreiving the 644 data itself. ie "UPDATE" "APPEND" "INSERT" queries. 645 */ 646 PBoolean Query(PString Query); 647 //@} 648 649 650 /**@name DataSource Access */ 651 //@{ 652 /** DataSource 653 This is the main function to call to contact a 654 DataSource. Source specifies the Type of DataSource 655 to contact and the Data parameter contain the relevent 656 connection information. You can choose to call this function 657 or use the specific Connection function. 658 */ 659 PBoolean DataSource(DataSources Source, ConnectData Data); 660 661 /** General Connect Function 662 Custom connection strings should call this 663 to connect Don't ask why its LPCTSTR! 664 */ 665 virtual PBoolean Connect(LPCTSTR svSource); 666 667 /** Connect to IBM DB2 DataSource 668 */ 669 PBoolean Connect_DB2(PFilePath DBPath); 670 671 /** Connect to MS Office excel spreadsheet 672 */ 673 PBoolean Connect_XLS(PFilePath XLSPath,PString DefDir = ""); 674 675 /** Connect to an ascii text or cvs file 676 */ 677 PBoolean Connect_TXT(PFilePath TXTPath); 678 679 /** Connect to a Foxpro dataSource 680 */ 681 PBoolean Connect_FOX(PFilePath DBPath,PString User = "", 682 PString Pass = "",PString Type= "DBF", 683 PBoolean Exclusive=false); 684 685 /** Connect to a MS Access *.mdb DataSource. 686 */ 687 PBoolean Connect_MDB(PFilePath MDBPath,PString User ="", 688 PString Pass = "",PBoolean Exclusive=false); 689 690 /** Connect to a paradox database datastore 691 */ 692 PBoolean Connect_PDOX(PDirectory DBPath,PDirectory DefaultDir, 693 int version =5); 694 695 /** Connect to an Oracle Datasource 696 */ 697 PBoolean Connect_Oracle(PString Server,PString User="", PString Pass=""); 698 699 /** Connect to a DBase DataStore 700 */ 701 PBoolean Connect_DBASE(PDirectory DBPath); 702 703 /** Connect to a MS SQL Server 704 */ 705 PBoolean Connect_MSSQL(PString User="",PString Pass="", 706 PString Host ="(local)",PBoolean Trusted = true, 707 MSSQLProtocols Proto=MSSQLNamedPipes); 708 709 /** Connect to a mySQL Server 710 */ 711 PBoolean Connect_mySQL(PString User="",PString Pass="", 712 PString Host= "localhost", 713 int Port=3306,int Option=0); 714 715 /** Connect to a mySQL Server's specified DataBase. 716 */ 717 PBoolean ConnectDB_mySQL(PString DB,PString User="", 718 PString Pass="",PString Host= "localhost", 719 int Port=3306,int Option=0); 720 721 /** Connect to a postgreSQL Server 722 */ 723 PBoolean Connect_postgreSQL(PString DB,PString User, 724 PString Pass,PString Host, int Port=5432,int Option=0); 725 726 /** General Disconnect from DataSource. 727 */ 728 void Disconnect(); 729 //@} 730 731 /**@name Utilities */ 732 //@{ 733 /** Retrieve a List of Tables in the Datasource 734 use the option field to specify the type of 735 data to access. ie "TABLE" or "VIEW" (further dev req'd) 736 */ 737 PStringArray TableList(PString option = ""); 738 739 /** Check whether their is a limit to Datalength 740 when obtaining Long Data 741 */ 742 PBoolean NeedLongDataLen(); 743 744 /** OnSQL Error 745 */ OnSQLError(PString RetCode,PString RetString)746 virtual void OnSQLError(PString RetCode, PString RetString) {}; 747 748 749 /** Set the Number of Decimal places to 750 round to By Default it is 4. However if the field 751 decimal places is less then Precision Value the 752 field rounding will be used. This must be set prior 753 to calling LoadTable() 754 */ 755 void SetPrecision(int Digit); 756 757 /** Set the Time Display Format 758 */ 759 void SetTimeFormat(PTime::TimeFormat tformat); 760 761 /** Operator Handle DataBase Connection 762 */ HDBC()763 operator HDBC() { return m_hDBC; }; 764 //@} 765 766 PODBC::DataSources dbase; /// Database Type connected to 767 768 protected: 769 SQLRETURN m_nReturn; // Internal SQL Error code 770 HENV m_hEnv; // Handle to environment 771 HDBC m_hDBC; // Handle to database connection 772 }; 773 774 775 /** 776 DSN (Data Source Name) Connection. The connection settings 777 have been preconfiured in the MDAC (Microsoft Data Access Component) 778 and is called using those Preset Settings. Calling the PDSNConnection::Connect 779 has the same effect and is a replaceable for PODBC::DataSource, 780 */ 781 class PDSNConnection : public PODBC 782 { 783 PCLASSINFO(PDSNConnection, PODBC); 784 785 public: 786 /**@name Constructor/Deconstructor */ 787 //@{ 788 PDSNConnection(); 789 ~PDSNConnection(); 790 //@} 791 792 /**@name Connection/Disconnect */ 793 //@{ 794 /** Connect to the MDAC using a pre-existing MDAC Defined DataSource 795 This is different than calling PODBC::DataSource in that the 796 Data Source is known defined externally within MDAC, 797 */ 798 PBoolean Connect( PString Source ,PString Username, PString Password); 799 }; 800 801 802 //-- 803 /** PODBCRecord 804 This Class is used to analyse the fetched data and handles 805 Data Conversion/Read Write operations. It is used in conjuction 806 with the PODBCStmt Class 807 */ 808 809 class PODBCRecord : public PObject 810 { 811 PCLASSINFO(PODBCRecord, PObject); 812 813 public: 814 /**@name Constructor/Deconstructor */ 815 //@{ 816 /** Constructor 817 */ 818 PODBCRecord(PODBCStmt * hStmt); 819 820 /** Deconstructor 821 */ ~PODBCRecord()822 ~PODBCRecord(){}; 823 //@} 824 825 /**@name Data Collection/Saving */ 826 //@{ 827 /** Data: Main Call to retrieve and convert Field Data 828 and return the information in the PODBC::Field structure. 829 */ 830 void Data(PINDEX Column, PODBC::Field & field); 831 832 /** InternalGetData is call when retrieving string or large binary 833 data where the size is indetermined. The Function can be iteratively 834 called until the function returns false. 835 */ 836 PBoolean InternalGetData( 837 USHORT Column, 838 LPVOID pBuffer, 839 ULONG pBufLen, 840 SQLINTEGER * dataLen=NULL, 841 int Type=SQL_C_DEFAULT 842 ); 843 844 /* Get Long Character Data. Long Data fields cannot be bound 845 and Data must be Got from the RecordSet. 846 */ 847 PString GetLongData(PINDEX Column); 848 849 /** Post the new record back to the RecordSet; 850 */ 851 PBoolean PostNew(PODBC::Row & rec); 852 853 /** Post the Updated record back to the RecordSet; 854 */ 855 PBoolean PostUpdate(PODBC::Row & rec); 856 857 /** Post a Delete command to the RecordSet; Default 858 1 Row is deleted. 859 */ 860 PBoolean PostDelete(PINDEX row= 1); 861 862 /** Check for and Save Long Data 863 */ 864 PBoolean InternalSaveLongData(SQLRETURN nRet,PODBC::Row & rec); 865 866 /** InternalBindColumn for Data input. 867 */ 868 PBoolean InternalBindColumn( 869 USHORT Column,LPVOID pBuffer, 870 ULONG pBufferSize, 871 LONG * pReturnedBufferSize=NULL, 872 USHORT nType=SQL_C_TCHAR 873 ); 874 //@} 875 876 /**@name Data Information */ 877 //@{ 878 /** ColumnByName returns the column number of the column name 879 If not found returns column value of 0; 880 */ 881 PINDEX ColumnByName(PString Column); 882 883 /** ColumnCount No of columns 884 */ 885 PINDEX ColumnCount(); 886 887 /** ColumnTypes 888 */ 889 PODBC::FieldTypes ColumnType(PINDEX Column ); 890 891 /** Column Size 892 */ 893 DWORD ColumnSize( PINDEX Column ); 894 895 /** Column Scale 896 */ 897 DWORD ColumnScale( PINDEX Column ); 898 899 /** Column Name 900 */ 901 PString ColumnName( PINDEX Column); 902 903 /** ColumnPrecision Get the Number of Decimal places 904 if Precision is set the precision is set to the 905 lessor of the Two. 906 */ 907 unsigned int ColumnPrecision( PINDEX Column ); 908 909 /** IsColumn Nullable. Accepts NULL value 910 */ 911 PBoolean IsColumnNullable( PINDEX Column ); 912 913 /** IsColumn Updateable ie is not ReadOnly 914 */ 915 PBoolean IsColumnUpdatable( PINDEX Column ); 916 917 /** IsColumnAutoIndex (ie don't give default Value) 918 */ 919 PBoolean IsColumnAutoIndex( PINDEX Column ); 920 921 //@} 922 923 /**@name Data Conversion Settings */ 924 //@{ 925 /** Conversion Settings 926 */ 927 static unsigned int Precision; /// Double Real Float Decimal digit rounding def= 4; 928 static int MaxCharSize; /// Long Data Limit KBytes def = 56; (56 Kbytes) 929 static PTime::TimeFormat TimeFormat;/// Time Format 930 //@} 931 932 protected: 933 HSTMT m_hStmt; 934 PODBCStmt * Stmt; /// Statement Class 935 PODBC::DataSources dbase; /// Database Type connecting to 936 937 friend class PODBC::Field; 938 friend class PODBC::Row; 939 }; 940 941 #endif // P_ODBC 942 943 #endif // PTLIB_PODBC_H 944 945 946 // End Of File /////////////////////////////////////////////////////////////// 947