DumontEXE 0.0.1
cmcRowSet.cpp
00001 /* ***************************************************************************
00002 **
00003 ** Copyright (C) 2007 Lorimark Solutions, LLC. All rights reserved.
00004 **
00005 ** This file is part of the DumontEXE Scripting Extension Kit
00006 **
00007 ** This file may be used under the terms of the GNU General Public
00008 ** License version 2.0 as published by the Free Software Foundation
00009 ** and appearing in the file LICENSE.GPL included in the packaging of
00010 ** this file.  Please review the following information to ensure GNU
00011 ** General Public Licensing requirements will be met:
00012 ** http://dumont.showoff-db.org/opensource.html
00013 **
00014 ** If you are unsure which license is appropriate for your use, please
00015 ** review the following information:
00016 ** http://dumont.showoff-db.org/licensing.html 
00017 ** or contact the sales department at sales@lorimarksolutions.com.
00018 **
00019 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00020 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00021 **
00022 ** author: Mark Petryk ~ Lorimark Solutions, LLC
00023 ** **************************************************************************/
00024 
00025 #include <QUuid>
00026 
00027 #include "cmcApplication.h"
00028 #include "cmcCursor.h"
00029 #include "cmcRowSet.h"
00030 #include "cmcCategoryDef.h"
00031 #include "cmcFieldDef.h"
00032 
00033 namespace cmcDatabaseApi {
00034 
00035 cmcRowSet::cmcRowSet( const cmcRowSet & copy ):
00036   cmcApi( copy )
00037 {
00038 }
00039 
00040 cmcRowSet::cmcRowSet
00041 (
00042   long rowCount,
00043   long flags,
00044   const QString & name,
00045   long type,
00046   cmcCursor * cursor,
00047   IDispatch * dispatch,
00048   QObject * parent
00049 ):
00050   cmcApi( name, dispatch, cursor-> app(), parent ),
00051   m_categoryName( cursor-> categoryName() ),
00052   m_cursor( cursor ),
00053   m_flags( flags ),
00054   m_type( type ),
00055   m_rowCount( rowCount ),
00056   m_colCount( -1 ),
00057   m_dirty( false ),
00058   m_currentSelection( 0 )
00059 {
00060 //  TRACE_FUNCTION
00061 }
00062 
00063 cmcRowSet::~cmcRowSet()
00064 {
00065 //  TRACE_FUNCTION
00066 }
00067 
00068 
00069 QString cmcRowSet::typeName( long type )
00070 {
00071   QString retVal = "unknown";
00072 
00073   switch( type )
00074   {
00075     case RowSetQuery:  retVal = "Query";  break;
00076     case RowSetAdd:    retVal = "Add";    break;
00077     case RowSetDelete: retVal = "Delete"; break;
00078     case RowSetEdit:   retVal = "Edit";   break;
00079   }
00080 
00081   return( retVal );
00082 }
00083 
00084 QString cmcRowSet::typeName()
00085 {
00086   return( typeName(type()) );
00087 }
00088 
00089 long cmcRowSet::type()
00090 {
00091   return( m_type );
00092 }
00093 
00094 QString cmcRowSet::categoryName()
00095 {
00096   return( m_categoryName );
00097 }
00098 
00099 cmcCategoryDef * cmcRowSet::categoryDef()
00100 {
00101 //  if( !m_categoryDef )
00102 //       m_categoryDef = app()-> categoryDefs( categoryName() );
00103 //
00104 //  return( m_categoryDef );
00105 
00106   return( app()-> categoryDef(categoryName()) );
00107 
00108 }
00109 
00110 cmcCursor * cmcRowSet::cursor()
00111 {
00112   return( m_cursor );
00113 }
00114 
00115 long cmcRowSet::rowCount()
00116 {
00117   if( m_rowCount == -1 )
00118       m_rowCount = GetServerLong("RowCount");
00119 
00120   return( m_rowCount );
00121 }
00122 
00123 long cmcRowSet::columnCount()
00124 {
00125   if( m_colCount == -1 )
00126       m_colCount = GetServerLong( "ColumnCount" );
00127 
00128   return( m_colCount );
00129 }
00130 
00131 long cmcRowSet::colCount()
00132 {
00133   return( columnCount() );
00134 }
00135 
00136 bool cmcRowSet::rowInRange( long row )
00137 {
00138   if( row < firstRow() || row > lastRow() )
00139   {
00140     err.set( cmcRowSet::RowRange, "row out of range" );
00141     return( false );
00142   }
00143 
00144   return( true );
00145 }
00146 
00147 bool cmcRowSet::colInRange( long col )
00148 {
00149   if( col < firstCol() || col > lastCol() )
00150   {
00151     err.set( cmcRowSet::ColRange, "column out of range" );
00152     return( false );
00153   }
00154 
00155   return( true );
00156 }
00157 
00158 long cmcRowSet::getColumnIndex( const QString & col, long flags )
00159 {
00160   /*
00161   ** If we have a cursor then use that to look up the index.
00162   **
00163   */
00164   if( cursor() )
00165   {
00166     /*
00167     ** Try to get the column index from the cursor.
00168     **
00169     */
00170     long retVal = cursor()-> getColumnIndex( col );
00171 
00172     /*
00173     ** If the cursor has a column index then we can return that
00174     **  value, since it's the same as the rowset, and faster.
00175     **
00176     */
00177     if( retVal > -1 ) return( retVal );
00178 
00179   } // endif( cursor() )
00180 
00181   /*
00182   ** Check the column cache to see if we already know the index of this
00183   **  column.  If so, we just return that and spare the application from
00184   **  yet another API call.
00185   **
00186   */
00187   if( m_columns.contains(col) )
00188     return( m_columns.value(col) );
00189 
00190   /*
00191   ** Nothing in the cache, we'll have to fetch it afterall.
00192   **
00193   */
00194   VARIANTARG varg[2];
00195   ::VariantInit(&varg[0]);     // Initialize the VARIANT.
00196   ::VariantInit(&varg[1]);
00197 
00198   // Convert the wide-character string to a BSTR.
00199   BSTR bstrIn = ::SysAllocString((OLECHAR*)col.utf16());
00200 
00201   // load the variant
00202   varg[1].vt = VT_BSTR; varg[1].bstrVal = bstrIn;
00203   varg[0].vt = VT_I4;   varg[0].lVal    = flags;
00204 
00205   // Fill in the DISPPARAMS structure.
00206   DISPPARAMS param;
00207   param.cArgs             = 2;     // Number of arguments
00208   param.rgvarg            = varg;  // Arguments
00209   param.cNamedArgs        = 0;     // Number of named args
00210   param.rgdispidNamedArgs = NULL;  // Named arguments
00211 
00212   // Allocate a variant for the returned parameter.
00213   VARIANT varResult;
00214   ::VariantInit(&varResult);
00215 
00216   // Invoke the function.
00217   HRESULT hr = Invoke
00218   (
00219     "GetColumnIndex",
00220     IID_NULL,
00221     GetUserDefaultLCID(),
00222     DISPATCH_METHOD,
00223     &param,
00224     &varResult,
00225     NULL,
00226     NULL
00227   );
00228 
00229   ::SysFreeString(bstrIn);
00230 
00231   if( FAILED(hr) )
00232   {
00233     qDebug( "getColumnIndex failed hr" );
00234     return -1;
00235   }
00236 
00237   // Display the returned string.
00238   if( varResult.vt == VT_I4 )
00239   {
00240     long    retVal = varResult.lVal;
00241 
00242     /*
00243     ** Record the column index position in the cache.
00244     **
00245     */
00246     m_columns.insert( col, retVal );
00247 
00248 //    qDebug( "getColumnIndex for %s is %ld", qPrintable(column), retVal );
00249 
00250     return  retVal;
00251   }
00252 
00253   qDebug( "getColumnIndex failed -1" );
00254   return -1;
00255 
00256 } // endlong QCommenceRowSet::getColumnIndex( QString i_label, long i_flags )
00257 
00258 QString cmcRowSet::getColumnLabel( long col, long flags )
00259 {
00260   if( !colInRange(col) ) return( "" );
00261 
00262   VARIANTARG varg[2];
00263   ::VariantInit(&varg[0]);     // Initialize the VARIANT.
00264   ::VariantInit(&varg[1]);
00265 
00266   // load the variant
00267   varg[1].vt = VT_I4; varg[1].lVal = col;
00268   varg[0].vt = VT_I4; varg[0].lVal = flags;
00269 
00270   // Fill in the DISPPARAMS structure.
00271   DISPPARAMS param;
00272   param.cArgs             = 2;     // Number of arguments
00273   param.rgvarg            = varg;  // Arguments
00274   param.cNamedArgs        = 0;     // Number of named args
00275   param.rgdispidNamedArgs = NULL;  // Named arguments
00276 
00277   // Allocate a variant for the returned parameter.
00278   VARIANT varResult;
00279   ::VariantInit(&varResult);
00280 
00281   // Invoke the function.
00282   HRESULT hr = Invoke
00283   (
00284     "GetColumnLabel",
00285     IID_NULL,
00286     GetUserDefaultLCID(),
00287     DISPATCH_METHOD,
00288     &param,
00289     &varResult,
00290     NULL,
00291     NULL
00292   );
00293 
00294   if( FAILED(hr) )
00295   {
00296     return QString();
00297   }
00298 
00299   // Display the returned string.
00300   if( varResult.vt == VT_BSTR )
00301   {
00302     return  QString::fromWCharArray(varResult.bstrVal);
00303   }
00304 
00305   return QString();
00306 
00307 } // endQString QCommenceRowSet::getColumnLabel( long i_col, long i_flags )
00308 
00309 
00310 QString cmcRowSet::getRowValue( long col )
00311 {
00312   return( getRowValue( currentSelection(), col, 0 ) );
00313 }
00314 
00315 QString cmcRowSet::getRowValue( long row, long col, long flags )
00316 {
00317   if( !rowInRange(row) ) return( QString("bad row %1. rowSet('%2').rowCount == %3").arg(row).arg(categoryName()).arg(rowCount()) );
00318   if( !colInRange(col) ) return( QString("bad col %1. rowSet('%2').rowCount == %3").arg(col).arg(categoryName()).arg(rowCount()) );
00319 
00320   /*
00321   ** Remember the row number
00322   **
00323   */
00324   currentSelection(row);
00325 
00326   VARIANTARG varg[3];
00327   ::VariantInit(&varg[0]);     // Initialize the VARIANT.
00328   ::VariantInit(&varg[1]);
00329   ::VariantInit(&varg[2]);
00330 
00331   // load the variant
00332   varg[2].vt = VT_I4; varg[2].lVal = row;
00333   varg[1].vt = VT_I4; varg[1].lVal = col;
00334   varg[0].vt = VT_I4; varg[0].lVal = flags;
00335 
00336   // Fill in the DISPPARAMS structure.
00337   DISPPARAMS param;
00338   param.cArgs             = 3;     // Number of arguments
00339   param.rgvarg            = varg;  // Arguments
00340   param.cNamedArgs        = 0;     // Number of named args
00341   param.rgdispidNamedArgs = NULL;  // Named arguments
00342 
00343   // Allocate a variant for the returned parameter.
00344   VARIANT varResult;
00345   ::VariantInit(&varResult);
00346 
00347   // Invoke the function.
00348   HRESULT hr = Invoke
00349   (
00350     "GetRowValue",
00351     IID_NULL,
00352     GetUserDefaultLCID(),
00353     DISPATCH_METHOD,
00354     &param,
00355     &varResult,
00356     NULL,
00357     NULL
00358   );
00359 
00360   if (FAILED(hr))
00361   {
00362 //    qDebug( "getRowValue failed hr=%lx", hr ); 
00363     return QString();
00364   }
00365 
00366   // Display the returned string.
00367   if( varResult.vt == VT_BSTR )
00368   {
00369     QString retVal = QString::fromWCharArray(varResult.bstrVal);
00370 //    TRACE_MESSAGE( qPrintable( "\"" + getColumnLabel(column) + "\" returning: " + retVal) )
00371     return  retVal;
00372   }
00373 
00374 //  qDebug( "getRowValue bad var type=%x", varResult.vt ); 
00375 
00376   return( QString() );
00377 }
00378 
00379 QString cmcRowSet::getRowValue( const QString & col )
00380 {
00381   return( getRowValue( currentSelection(), getColumnIndex(col), 0 ) );
00382 }
00383 
00384 QString cmcRowSet::getRowValue( long row, const QString & col )
00385 {
00386   return( getRowValue( row, getColumnIndex(col), 0 ) );
00387 }
00388 
00389 QString cmcRowSet::getRowID()
00390 {
00391   return( getRowID( currentSelection(), 0 ) );
00392 }
00393 
00394 QString cmcRowSet::getRowID
00395 (
00396   long   row,
00397   long   flags
00398 )
00399 {
00400   if( !rowInRange(row) ) return( "" );
00401 
00402   /*
00403   ** Remember the row number
00404   **
00405   */
00406   currentSelection(row);
00407 
00408   /*
00409   ** Check the cursor to see if THID's are turned on
00410   **  If not, we're going to get another cursor with
00411   **  THIDS so that we can fetch them transparently
00412   **
00413   */
00414 //  if( cursor() )
00415 //  {
00416 //    if( (cursor()-> flags()&0x100) != 256 )
00417 //    {
00418 //    }
00419 //  }
00420 
00421   VARIANTARG varg[2];
00422   ::VariantInit(&varg[0]);     // Initialize the VARIANT.
00423   ::VariantInit(&varg[1]);
00424 
00425   // load the variant
00426   varg[1].vt = VT_I4; varg[1].lVal = row;
00427   varg[0].vt = VT_I4; varg[0].lVal = flags;
00428 
00429   // Fill in the DISPPARAMS structure.
00430   DISPPARAMS param;
00431   param.cArgs             = 2;     // Number of arguments
00432   param.rgvarg            = varg;  // Arguments
00433   param.cNamedArgs        = 0;     // Number of named args
00434   param.rgdispidNamedArgs = NULL;  // Named arguments
00435 
00436   // Allocate a variant for the returned parameter.
00437   VARIANT varResult;
00438   ::VariantInit(&varResult);
00439 
00440   // Invoke the function.
00441   HRESULT hr = Invoke
00442   (
00443     "GetRowID",
00444     IID_NULL,
00445     GetUserDefaultLCID(),
00446     DISPATCH_METHOD,
00447     &param,
00448     &varResult,
00449     NULL,
00450     NULL
00451   );
00452 
00453   if( FAILED(hr) )
00454   {
00455     return QString();
00456   }
00457 
00458   // Display the returned string.
00459   if( varResult.vt == VT_BSTR )
00460   {
00461     return QString::fromWCharArray(varResult.bstrVal);
00462   }
00463 
00464   return QString();
00465 
00466 } // endQString QCommenceRowSet::get_RowID
00467 
00468 QString cmcRowSet::getRowTHID( long row )
00469 {
00470   return( getRowID(row) );
00471 }
00472 
00473 QString cmcRowSet::getRowTHID()
00474 {
00475   return( getRowTHID( currentSelection() ) );
00476 }
00477 
00478 QString cmcRowSet::getRowGUID( long row )
00479 {
00480   static QString retVal;
00481 
00482   if( categoryDef()-> hasGuidField() )
00483   {
00484     retVal = getRowValue( row, categoryDef()-> guidFieldName() );
00485   }
00486 
00487   if( retVal == "" && categoryDef()-> hasVarField() )
00488   {
00489     retVal = getRowVar( row, categoryDef()-> varFieldName(), "guid" );
00490   }
00491 
00492   return( retVal );
00493 }
00494 
00495 QString cmcRowSet::getRowGUID()
00496 {
00497   return( getRowGUID( currentSelection() ) );
00498 }
00499 
00500 QString cmcRowSet::getRowString( long row, long col )
00501 {
00502   return( getRowValue( row, col, 0 ) );
00503 }
00504 
00505 QString cmcRowSet::getRowString( long col )
00506 {
00507   return( getRowString( currentSelection(), col ) );
00508 }
00509 
00510 QString cmcRowSet::getRowString( const QString & col )
00511 {
00512   return( getRowString( currentSelection(), col ) );
00513 }
00514 
00515 QString cmcRowSet::getRowString( long row, const QString & col )
00516 {
00517   return( getRowString( row, getColumnIndex(col) ) );
00518 }
00519 
00520 bool cmcRowSet::getRowBool( long col )
00521 {
00522   return( getRowBool( currentSelection(), col )  );
00523 }
00524 
00525 bool cmcRowSet::getRowBool( long row, long col )
00526 {
00527   return( getRowValue( row, col, 0 )=="TRUE"? true:false );
00528 }
00529 
00530 bool cmcRowSet::getRowBool( const QString & col )
00531 {
00532   return( getRowBool( currentSelection(), col ) );
00533 }
00534 
00535 bool cmcRowSet::getRowBool( long row, const QString & col )
00536 {
00537   return( getRowBool(row,getColumnIndex(col)) );
00538 }
00539 
00540 long cmcRowSet::getRowLong( long col )
00541 {
00542   return( getRowLong( currentSelection(), col ) );
00543 }
00544 
00545 long cmcRowSet::getRowLong( long row, long col )
00546 {
00547   long retVal = 0;
00548   QString rowVal = getRowValue(row,col,0);
00549   if( rowVal != "" ) retVal = rowVal.toLong();
00550   return( retVal );
00551 }
00552 
00553 long cmcRowSet::getRowLong( const QString & col )
00554 {
00555   return( getRowLong( currentSelection(), col ) );
00556 }
00557 
00558 long cmcRowSet::getRowLong( long row, const QString & col )
00559 {
00560   return( getRowLong( row, getColumnIndex(col) ) );
00561 }
00562 
00563 QString cmcRowSet::getRowVar
00564 (
00565   long col,
00566   const QString & field
00567 )
00568 {
00569   return( getRowVar( currentSelection(), col, field ) );
00570 }
00571 
00572 QString cmcRowSet::getRowVar
00573 (
00574   long row,
00575   long col,
00576   const QString & field
00577 )
00578 {
00579   return( var(getRowValue(row,col,0),field) );
00580 }
00581 
00582 QString cmcRowSet::getRowVar
00583 (
00584   const QString & col,
00585   const QString & field
00586 )
00587 {
00588   return( getRowVar( currentSelection(), getColumnIndex(col), field ) );
00589 }
00590 
00591 QString cmcRowSet::getRowVar
00592 (
00593   long row,
00594   const QString & col,
00595   const QString & field
00596 )
00597 {
00598   return( getRowVar( row, getColumnIndex(col), field ) );
00599 }
00600 
00601 
00602 QString cmcRowSet::varValue
00603 (
00604   long row,
00605   long col,
00606   const QString & field
00607 )
00608 {
00609   return( getRowVar( row, col, field ) );
00610 }
00611 
00612 QString cmcRowSet::varValue
00613 (
00614   long row,
00615   const QString & col,
00616   const QString & field
00617 )
00618 {
00619   return( getRowVar( row, col, field ) );
00620 }
00621 
00622 QString cmcRowSet::varValue
00623 (
00624   long col,
00625   const QString & field
00626 )
00627 {
00628   return( getRowVar( currentSelection(), col, field ) );
00629 }
00630 
00631 QString cmcRowSet::varValue
00632 (
00633   const QString & col,
00634   const QString & field
00635 )
00636 {
00637   return( getRowVar( currentSelection(), col, field ) );
00638 }
00639 
00640 QString cmcRowSet::setRowGUID( long row )
00641 {
00642   QString retVal = getRowGUID(row);
00643 
00644   if( retVal == "" )
00645   {
00646     retVal = QUuid::createUuid().toString();
00647 
00648     if( categoryDef()-> hasGuidField() )
00649     {
00650       modifyRow( row, categoryDef()-> guidFieldName(), retVal );
00651     }
00652 
00653     if( categoryDef()-> hasVarField() )
00654     {
00655       modifyVar( row, categoryDef()-> varFieldName(), "guid", retVal );
00656     }
00657 
00658   }
00659 
00660   return( retVal );
00661 
00662 }
00663 
00664 
00665 
00666 long cmcRowSet::modifyRow( long row, long col, const QString & value, long flags )
00667 {
00668   /*
00669   ** If we are not of the correct type then we cannot run.
00670   **
00671   */
00672   if( type() == RowSetQuery ||
00673       type() == RowSetDelete ) return( -1 );
00674 
00675   /*
00676   ** Make sure the rows and columns are within range.
00677   **
00678   */
00679   if( !rowInRange(row) ) return( -1 );
00680   if( !colInRange(col) ) return( -1 );
00681 
00682   /*
00683   ** Remember the row number
00684   **
00685   */
00686   currentSelection( row );
00687 
00688 //  if( eventTrace() )
00689   {
00690 //    TRACE_FUNCTION
00691 //    qDebug
00692 //    ( "category=%s, row=%ld, col=%ld, buf=%s, flags=%ld",
00693 //      "", //qPrintable(categoryDef()-> categoryName()),
00694 //      row,
00695 //      column,
00696 //      qPrintable(value),
00697 //      flags
00698 //    );
00699   }
00700 
00701   /*
00702   ** Check the new row value against the current row value.  If they're
00703   **  the same then there's nothing to do.  This can represent a slow-down
00704   **  if there are changes, but will represent a speedup if there are a lot
00705   **  of unnecessary updates.
00706   **
00707   ** This check is normally not enabled.  It can be turned on by including
00708   **  a 1 as part of the flag parameters.  Since, presently, the rowsets
00709   **  require a 0 as the flags parameter, this value is reset to zero before
00710   **  the procedure continues.
00711   **
00712   */
00713   if( (flags & 1) == 1 )
00714     if( getRowValue(row,col,0) == value )
00715       return( 0 );
00716 
00717   VARIANTARG varg[4];
00718   ::VariantInit(&varg[0]);     // Initialize the VARIANT.
00719   ::VariantInit(&varg[1]);     // Initialize the VARIANT.
00720   ::VariantInit(&varg[2]);     // Initialize the VARIANT.
00721   ::VariantInit(&varg[3]);     // Initialize the VARIANT.
00722 
00723   // allocate the string param
00724   BSTR bstrIn = ::SysAllocString((OLECHAR*)value.utf16());
00725 
00726   // load the variant
00727   varg[3].vt = VT_I4;   varg[3].lVal    = row;
00728   varg[2].vt = VT_I4;   varg[2].lVal    = col;
00729   varg[1].vt = VT_BSTR; varg[1].bstrVal = bstrIn;
00730   varg[0].vt = VT_I4;   varg[0].lVal    = 0; // flags;
00731 
00732   // Fill in the DISPPARAMS structure.
00733   DISPPARAMS param;
00734   param.cArgs             = 4;     // Number of arguments
00735   param.rgvarg            = varg;  // Arguments
00736   param.cNamedArgs        = 0;     // Number of named args
00737   param.rgdispidNamedArgs = NULL;  // Named arguments
00738 
00739   // Allocate a variant for the returned parameter.
00740   VARIANT varResult;
00741   ::VariantInit(&varResult);
00742 
00743   // Invoke the function.
00744   HRESULT hr = Invoke
00745   (
00746     GetIDofName("ModifyRow"),
00747     IID_NULL,
00748     GetUserDefaultLCID(),
00749     DISPATCH_METHOD,
00750     &param,
00751     &varResult,
00752     NULL,
00753     NULL
00754   );
00755 
00756   ::SysFreeString(bstrIn) ;
00757 
00758   /*
00759   ** If flags==2 is set, then we don't want to check the
00760   **  hresult of the method invoke.  This is kind of weird
00761   **  but what's happening is we are getting an invoke error
00762   **  on setting a connection, but the connections are 
00763   **  actually being set properly.  So, I'm not sure what
00764   **  to do with the fact that the code is coming back with
00765   **  an error.
00766   **
00767   */
00768   if( (flags & 2) != 2 )
00769   {
00770     if( FAILED(hr) )
00771     {
00772       qDebug
00773       ( "FAILED(%lx): modifyRow(category='%s', row=%ld, col=%ld '%s', buf='%s', flags=%ld)",
00774         hr,
00775         qPrintable(categoryDef()-> categoryName()),
00776         row,
00777         col,
00778         qPrintable(getColumnLabel(col)),
00779         qPrintable(value),
00780         flags
00781       );
00782 
00783       return false;
00784     }
00785   }
00786 
00787   // Display the returned string.
00788   if( varResult.vt == VT_I4 )
00789   {
00790     m_dirty = true;
00791     return varResult.lVal;
00792   }
00793 
00794   /*
00795   ** Again, if flags==2 is set, then we don't want to
00796   **  spit out any messages.  This is an override.
00797   **
00798   */
00799   if( (flags & 2) != 2 )
00800   {
00801     qDebug( "modifyRow vartype wrong" );
00802   }
00803 
00804   return 0;
00805 
00806 }
00807 
00808 long cmcRowSet::modifyRow( long row, const QString & col, const QString & value, long flags )
00809 {
00810   return( modifyRow( row, getColumnIndex(col), value, flags ) );
00811 }
00812 
00813 long cmcRowSet::modifyRow( long row, long col, const char * value )
00814 {
00815   return( modifyRow( row, col, QString(value) ) );
00816 }
00817 
00818 long cmcRowSet::modifyRow( long row, const QString & col, const char * value )
00819 {
00820   return( modifyRow( row, getColumnIndex(col), value ) );
00821 }
00822 
00823 long cmcRowSet::modifyRow( long row, long col, bool value )
00824 {
00825   return( modifyRow( row, col, value? "TRUE":"FALSE" ) );
00826 }
00827 
00828 long cmcRowSet::modifyRow( long row, const QString & col, bool value )
00829 {
00830   return( modifyRow( row, getColumnIndex(col), value ) );
00831 }
00832 
00833 long cmcRowSet::modifyRow( long row, long col, long value )
00834 {
00835   return( modifyRow( row, col, QString::number(value) ) );
00836 }
00837 
00838 long cmcRowSet::modifyRow( long row, const QString & col, long value )
00839 {
00840   return( modifyRow( row, getColumnIndex(col), value ) );
00841 }
00842 
00843 long cmcRowSet::modifyRow( long row, long col, double value )
00844 {
00845   return( modifyRow( row, col, QString::number(value) ) );
00846 }
00847 
00848 long cmcRowSet::modifyRow( long row, const QString & col, double value )
00849 {
00850   return( modifyRow( row, getColumnIndex(col), value ) );
00851 }
00852 
00853 long cmcRowSet::modifyRow( long row, long col, const QDateTime & value )
00854 {
00855   QString rowValue;
00856 
00857   if( categoryDef() )
00858   {
00859     QString colLabel = getColumnLabel(col);
00860     if( categoryDef()-> fieldDef( colLabel ) )
00861     {
00862       switch( categoryDef()-> fieldDef( colLabel )-> typeCode() )
00863       {
00864         case cmcFieldDef::ft_text:
00865         case cmcFieldDef::ft_telephone:
00866         case cmcFieldDef::ft_name:
00867         case cmcFieldDef::ft_eMailAddress:
00868         case cmcFieldDef::ft_internetAddress:
00869         {
00870           rowValue = value.toString( Qt::TextDate );
00871           break;
00872         }
00873 
00874         case cmcFieldDef::ft_time:
00875         {
00876           rowValue = value.toString( "hh:mm:ss" );
00877           break;
00878         }
00879 
00880         case cmcFieldDef::ft_date:
00881         {
00882           rowValue = value.toString( "MM/dd/yyyy" );
00883           break;
00884         }
00885 
00886       }
00887     }
00888   }
00889 
00890   return( modifyRow( row, col, rowValue ) );
00891 }
00892 
00893 long cmcRowSet::modifyRow( long row, const QString & col, const QDateTime & value )
00894 {
00895   return( modifyRow( row, getColumnIndex(col), value ) );
00896 }
00897 
00898 long cmcRowSet::modifyVar( long row, long col, const QString & varField, const QString & newVar )
00899 {
00900   QString newValue = var( getRowValue( row, col, 0 ), varField, newVar );
00901 
00902   return( modifyRow( row, col, newValue ) );
00903 }
00904 
00905 long cmcRowSet::modifyVar( long row, const QString & col, const QString & varField, const QString & newVar )
00906 {
00907   return( modifyVar( row, getColumnIndex(col), varField, newVar ) );
00908 }
00909 
00910 long cmcRowSet::deleteRow()
00911 {
00912   return( deleteRow( currentSelection(), 0 ) );
00913 }
00914 
00915 long cmcRowSet::deleteRow( long row, long flags )
00916 {
00917   /*
00918   ** Only Delete type rowsets can implement delete Row
00919   **
00920   */
00921   if( type() != RowSetDelete )
00922     return( -1 );
00923 
00924   /*
00925   ** The row must be in range for this to work properly
00926   **
00927   */
00928   if( !rowInRange(row) )
00929     return( -1 );
00930 
00931   /*
00932   ** Remember this row
00933   **
00934   */
00935   currentSelection(row);
00936 
00937 //  qDebug( "drs::deleteRow(%ld)", i_row );
00938 
00939   VARIANTARG varg[2];
00940   ::VariantInit(&varg[0]);     // Initialize the VARIANT.
00941   ::VariantInit(&varg[1]);
00942 
00943   // load the variant
00944   varg[1].vt = VT_I4; varg[1].lVal = row;
00945   varg[0].vt = VT_I4; varg[0].lVal = flags;
00946 
00947   // Fill in the DISPPARAMS structure.
00948   DISPPARAMS param;
00949   param.cArgs             = 2;     // Number of arguments
00950   param.rgvarg            = varg;  // Arguments
00951   param.cNamedArgs        = 0;     // Number of named args
00952   param.rgdispidNamedArgs = NULL;  // Named arguments
00953 
00954   // Allocate a variant for the returned parameter.
00955   VARIANT varResult;
00956   ::VariantInit(&varResult);
00957 
00958   // Invoke the function.
00959   HRESULT hr = Invoke
00960   (
00961     GetIDofName("DeleteRow"),
00962     IID_NULL,
00963     GetUserDefaultLCID(),
00964     DISPATCH_METHOD,
00965     &param,
00966     &varResult,
00967     NULL,
00968     NULL
00969   );
00970 
00971   if( FAILED(hr) )
00972   {
00973 //    qDebug( "ers::deleteRow failed hr=%lx", hr );
00974     return 0;
00975   }
00976 
00977   // Display the returned string.
00978   if( varResult.vt == VT_I4 )
00979   {
00980     /*!
00981     ** \todo implement dirty rowset
00982     **
00983     */
00984     m_dirty         = true;
00985 //    m_dirtyRows[i_row] = true;
00986 
00987 //    qDebug( "ers::deleteRow OK %ld", varResult.lVal );
00988     return varResult.lVal;
00989   }
00990 
00991   qDebug( "ers::deleteRow bad var type=%x", varResult.vt );
00992 
00993   return( 0 );
00994 
00995 }
00996 
00997 
00998 long cmcRowSet::commit( long flags )
00999 {
01000 //  TRACE_FUNCTION
01001 
01002   /*
01003   ** Only commit if the rowset is dirty.  This isn't an error,
01004   **  it's just not necessary to commit for no reason.
01005   **
01006   */
01007   if( !isDirty() )
01008     return( 0 );
01009 
01010   /*
01011   ** Query rowsets cannot commit anything.
01012   **
01013   */
01014   if( type() == RowSetQuery )
01015     return( -1 );
01016 
01017   VARIANTARG varg[1];
01018   ::VariantInit(&varg[0]);     // Initialize the VARIANT.
01019 
01020   // load the variant
01021   varg[0].vt = VT_I4;   varg[0].lVal    = flags;
01022 
01023   // Fill in the DISPPARAMS structure.
01024   DISPPARAMS param;
01025   param.cArgs             = 1;     // Number of arguments
01026   param.rgvarg            = varg;  // Arguments
01027   param.cNamedArgs        = 0;     // Number of named args
01028   param.rgdispidNamedArgs = NULL;  // Named arguments
01029 
01030   // Allocate a variant for the returned parameter.
01031   VARIANT varResult;
01032   ::VariantInit(&varResult);
01033 
01034   // Invoke the function.
01035   HRESULT hr = Invoke
01036   (
01037     GetIDofName("Commit"),
01038     IID_NULL,
01039     GetUserDefaultLCID(),
01040     DISPATCH_METHOD,
01041     &param,
01042     &varResult,
01043     NULL,
01044     NULL
01045   );
01046 
01047   if( FAILED(hr) )
01048   {
01049     qDebug( "cmcRowSet::commit failed hr=%lx", hr );
01050     if( cursor() )
01051     {
01052       qDebug( "  cursor %s",   qPrintable(cursor()-> category()) );
01053       qDebug( "  filter:\n%s", qPrintable(cursor()-> filters())  );
01054     }
01055     return -2;
01056   }
01057 
01058   // Display the returned string.
01059   if( varResult.vt == VT_I4 )
01060   {
01061 //    qDebug( "rs_commit OK " );
01062     m_dirty = false;
01063     return varResult.lVal;
01064   }
01065 
01066   qDebug( "rs_commit bad var type=%u", varResult.vt );
01067   return 0;
01068 
01069 }
01070 
01071 long cmcRowSet::lastRow()
01072 {
01073   return( rowCount() - 1 );
01074 }
01075 
01076 long cmcRowSet::lastColumn()
01077 {
01078   return( columnCount() - 1 );
01079 }
01080 
01081 long cmcRowSet::lastCol()
01082 {
01083   return( lastColumn() );
01084 }
01085 
01086 bool cmcRowSet::isDirty()
01087 {
01088   return( m_dirty );
01089 }
01090 
01091 long cmcRowSet::currentSelection()
01092 {
01093   return( m_currentSelection );
01094 }
01095 
01096 void cmcRowSet::currentSelection( long value )
01097 {
01098   if( value < firstRow() ) value = firstRow();
01099   if( value > lastRow()  ) value = lastRow();
01100 
01101   m_currentSelection = value;
01102 }
01103 
01104 bool cmcRowSet::setShared( long row )
01105 {
01106 //  TRACE_FUNCTION
01107 
01108   /*
01109   ** If we are not of the correct type then we cannot run.
01110   **
01111   */
01112   if( type() == RowSetQuery ||
01113       type() == RowSetDelete ) return( false );
01114 
01115   /*
01116   ** Make sure the rows and columns are within range.
01117   **
01118   */
01119   if( !rowInRange(row) ) return( false );
01120 
01121   VARIANTARG varg[1];
01122   ::VariantInit(&varg[0]);     // Initialize the VARIANT.
01123 
01124   // load the variant
01125   varg[0].vt = VT_I4; varg[0].lVal = row;
01126 
01127   // Fill in the DISPPARAMS structure.
01128   DISPPARAMS param;
01129   param.cArgs             = 1;     // Number of arguments
01130   param.rgvarg            = varg;  // Arguments
01131   param.cNamedArgs        = 0;     // Number of named args
01132   param.rgdispidNamedArgs = NULL;  // Named arguments
01133 
01134   // Allocate a variant for the returned parameter.
01135   VARIANT varResult;
01136   ::VariantInit(&varResult);
01137 
01138   // Invoke the function.
01139   HRESULT hr = Invoke
01140   (
01141     "SetShared",
01142     IID_NULL,
01143     GetUserDefaultLCID(),
01144     DISPATCH_METHOD,
01145     &param,
01146     &varResult,
01147     NULL,
01148     NULL
01149   );
01150 
01151   if( FAILED(hr) )
01152   {
01153     qDebug( "setShared failed %lx %ld", hr, row );
01154     return false;
01155   }
01156 
01157   // Display the returned string.
01158   if( varResult.vt == VT_BOOL )
01159   {
01160     return varResult.boolVal;
01161   }
01162 
01163   qDebug( "setShared bad var type %ld", row );
01164 
01165   return false;
01166 
01167 }
01168 
01169 
01170 bool cmcRowSet::getShared( long row )
01171 {
01172   /*
01173   ** If we are not of the correct type then we cannot run.
01174   **
01175   */
01176   if( type() == RowSetAdd ||
01177       type() == RowSetEdit ) return( false );
01178 
01179   /*
01180   ** Make sure the rows and columns are within range.
01181   **
01182   */
01183   if( !rowInRange(row) ) return( false );
01184 
01185   VARIANTARG varg[1];
01186   ::VariantInit(&varg[0]);     // Initialize the VARIANT.
01187 
01188   // load the variant
01189   varg[0].vt = VT_I4; varg[0].lVal = row;
01190 
01191   // Fill in the DISPPARAMS structure.
01192   DISPPARAMS param;
01193   param.cArgs             = 1;     // Number of arguments
01194   param.rgvarg            = varg;  // Arguments
01195   param.cNamedArgs        = 0;     // Number of named args
01196   param.rgdispidNamedArgs = NULL;  // Named arguments
01197 
01198   // Allocate a variant for the returned parameter.
01199   VARIANT varResult;
01200   ::VariantInit(&varResult);
01201 
01202   // Invoke the function.
01203   HRESULT hr = Invoke
01204   (
01205     "GetShared",
01206     IID_NULL,
01207     GetUserDefaultLCID(),
01208     DISPATCH_METHOD,
01209     &param,
01210     &varResult,
01211     NULL,
01212     NULL
01213   );
01214 
01215   if( FAILED(hr) )
01216   {
01217     qDebug( "getShared failed %lx %ld", hr, row );
01218     return false;
01219   }
01220 
01221   // Display the returned string.
01222   if( varResult.vt == VT_BOOL )
01223   {
01224     return varResult.boolVal;
01225   }
01226 
01227   qDebug( "getShared bad var type %ld", row );
01228 
01229   return false;
01230 
01231 }
01232 
01233 
01234 bool cmcRowSet::setTimeStamp( long row )
01235 {
01236   /*
01237   ** If we are not of the correct type then we cannot run.
01238   **
01239   */
01240   if( type() == RowSetQuery ||
01241       type() == RowSetDelete ) return( false );
01242 
01243   /*
01244   ** Make sure the rows and columns are within range.
01245   **
01246   */
01247   if( !rowInRange(row) ) return( false );
01248 
01249   /*
01250   ** Make sure this category has a var field.  If it
01251   **  doesn't then we won't bother continuing.
01252   **
01253   */
01254   if( !categoryDef()-> hasVarField() ) return( false );
01255 
01256   /*
01257   ** This sets the item GUID.  If the item already has a GUID
01258   **  then nothing is done.
01259   **
01260   */
01261   setRowGUID( row );
01262 
01263   /*
01264   ** Make sure there's a spot to hold the cmcID, should we set it
01265   **  sometime in the future.
01266   **
01267   */
01268   if( varValue( row, categoryDef()-> varFieldName(), "cmcID" ) == "" )
01269   {
01270     modifyVar( row, categoryDef()-> varFieldName(), "cmcID", "nothing" );
01271   }
01272 
01273   /*
01274   ** If this row doesn't already have created information, then stamp
01275   **  it now.
01276   **
01277   */
01278   if( varValue( row, categoryDef()-> varFieldName(), "createdOn" ) == "" )
01279   {
01280     modifyVar( row, categoryDef()-> varFieldName(), "createdOn", dateTimeStamp() );
01281     modifyVar( row, categoryDef()-> varFieldName(), "createdBy", db()-> meInfo()-> abbreviation() );
01282   }
01283 
01284   /*
01285   ** Stamp the change information.
01286   **
01287   */
01288   modifyVar( row, categoryDef()-> varFieldName(), "changedOn", dateTimeStamp() );
01289   modifyVar( row, categoryDef()-> varFieldName(), "changedBy", db()-> meInfo()-> abbreviation() );
01290 
01291   return( true );
01292 
01293 } // endbool cmcRowSet::setTimeStamp( long row )
01294 
01295 
01296 } // endnamespace cmcDatabaseApi
01297 
 All Classes Namespaces Functions Variables Enumerations Enumerator Properties




~ ~ ~ ~ ~ ~
Source Code without Comments is like a Cranberry Garland
without the berries. Comment your Code!
 
Commence Database User Support Group Forum
http://newsgroup.showoff-db.org/
~ ~ ~ ~ ~ ~
Author: Mark Petryk
Lorimark Solutions, LLC
mark@lorimarksolutions.com