DumontEXE 0.0.1
cmcCdaItem.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 <QString>
00026 #include <QObject>
00027 #include <QDateTime>
00028 
00029 #include "cmcCda.h"
00030 #include "cmcCdaItem.h"
00031 #include "cmcApplication.h"
00032 #include "cmcCursor.h"
00033 #include "cmcRowSet.h"
00034 
00035 namespace cmcDatabaseApi {
00036 
00037 static char * idNull = "{00000000-0000-0000-0000-000000000000}";
00038 
00039 cmcCdaItem::cmcCdaItem( const cmcCdaItem & copy ):
00040   cmcObject( copy ),
00041   m_valid(false),
00042   m_dirty(true)
00043 {
00044 //  m_cda = copy.cda();
00045 
00046 //  TRACE_FUNCTION
00047 }
00048 
00049 cmcCdaItem::cmcCdaItem( QObject * parent ):
00050   cmcObject( parent ),
00051   m_valid(false),
00052   m_dirty(true)
00053 {
00054 //  TRACE_FUNCTION
00055 
00056   m_cda = NULL;
00057 
00058 } // endctor
00059 
00060 cmcCdaItem::cmcCdaItem( const QString & name, cmcCda * cda, cmcCdaItem * parent ):
00061   cmcObject( name, cda-> app(), parent ),
00062   m_cda(cda),
00063   m_valid(false),
00064   m_dirty(true)
00065 {
00066 //  TRACE_FUNCTION
00067 
00068   /*
00069   ** Clear any existing values.  Values will be overwritten
00070   **  unless an item couldn't be found in the store.
00071   **
00072   */
00073   clear();
00074 
00075   /*
00076   ** Immediately try to load an item.
00077   **
00078   */
00079   load();
00080 
00081 } // endctor
00082 
00083 cmcCdaItem::cmcCdaItem( const QUuid & uuid, cmcCda * cda, cmcCdaItem * parent ):
00084   cmcObject( "", cda-> app(), parent ),
00085   m_cda(cda),
00086   m_valid(false), 
00087   m_dirty(true)
00088 {
00089 //  TRACE_FUNCTION
00090 
00091   /*
00092   ** Clear any existing values.  Values will be overwritten
00093   **  unless an item couldn't be found in the store.
00094   **
00095   */
00096   clear();
00097 
00098   /*
00099   ** Immediately try to load an item.
00100   **
00101   */
00102   load();
00103 
00104 } // endctor
00105 
00106 cmcCdaItem::~cmcCdaItem()
00107 {
00108 //  TRACE_FUNCTION
00109 
00110   if( dirty() ) save();
00111 
00112   m_cda = NULL;
00113 
00114 } // enddtor
00115 
00116 cmcCda * cmcCdaItem::cda()
00117 {
00118   return( m_cda );
00119 }
00120 
00121 cmcCdaItem * cmcCdaItem::childItem( const QString & name )
00122 {
00123   return( new cmcCdaItem( name, cda(), this ) );
00124 }
00125 
00126 cmcCdaItem * cmcCdaItem::childItem( const QUuid & uuid )
00127 {
00128   return( new cmcCdaItem( uuid, cda(), this ) );
00129 }
00130 
00131 
00132 bool cmcCdaItem::valid()
00133 {
00134   return( m_valid );
00135 }
00136 
00137 bool cmcCdaItem::dirty()
00138 {
00139   return( m_dirty );
00140 }
00141 
00142 QString cmcCdaItem::itemName()
00143 {
00144   return( name() );
00145 }
00146 
00147 QUuid cmcCdaItem::id()
00148 {
00149   return( m_id );
00150 }
00151 
00152 cmcCdaItem * cmcCdaItem::parentItem()
00153 {
00154   return( qobject_cast<cmcCdaItem*>(parent()) );
00155 }
00156 
00157 QUuid cmcCdaItem::idParent()
00158 {
00159   /*
00160   ** If we actually have a parent item then return its ID
00161   **
00162   */
00163   if( parentItem() != NULL )
00164     return( parentItem()-> id() );
00165 
00166   /*
00167   ** If we don't have a parent item, then just return an
00168   **  empty uuid.
00169   **
00170   */
00171   return( idNull );
00172 }
00173 
00174 QUuid cmcCdaItem::idGroup()
00175 {
00176   return( m_idGroup );
00177 }
00178 
00179 QUuid cmcCdaItem::idOwner()
00180 {
00181   return( m_idOwner );
00182 }
00183 
00184 QUuid cmcCdaItem::idLock()
00185 {
00186   return( m_idLock );
00187 }
00188 
00189 QUuid cmcCdaItem::idSymlink()
00190 {
00191   return( m_idSymlink );
00192 }
00193 
00194 QString cmcCdaItem::itemType()
00195 {
00196   return( m_itemType );
00197 }
00198 
00199 bool cmcCdaItem::isDeleted()
00200 {
00201   return( m_isDeleted );
00202 }
00203 
00204 bool cmcCdaItem::isHidden()
00205 {
00206   return( m_isHidden );
00207 }
00208 
00209 bool cmcCdaItem::isLocked()
00210 {
00211   return( m_isLocked );
00212 }
00213 
00214 bool cmcCdaItem::isParent()
00215 {
00216   return( m_isParent );
00217 }
00218 
00219 bool cmcCdaItem::isShared()
00220 {
00221   return( m_isShared );
00222 }
00223 
00224 long cmcCdaItem::itemAutoId()
00225 {
00226   return( m_itemAutoId );
00227 }
00228 
00229 QString cmcCdaItem::itemData()
00230 {
00231   return( m_itemData );
00232 }
00233 
00234 long cmcCdaItem::itemMode()
00235 {
00236   return( m_itemMode );
00237 }
00238 
00239 QString cmcCdaItem::itemSort()
00240 {
00241   return( m_itemSort );
00242 }
00243 
00244 QString cmcCdaItem::onCreated()
00245 {
00246   return( m_onCreated );
00247 }
00248 
00249 QString cmcCdaItem::onChanged()
00250 {
00251   return( m_onChanged );
00252 }
00253 
00254 QString cmcCdaItem::onDeleted()
00255 {
00256   return( m_onDeleted );
00257 }
00258 
00259 QString cmcCdaItem::version()
00260 {
00261   return( m_version );
00262 }
00263 
00264 QVariant cmcCdaItem::value( const QString & key )
00265 {
00266   return( QVariant("") );
00267 }
00268 
00269 void cmcCdaItem::setValue( const QString & key, const QVariant & value )
00270 {
00271 }
00272 
00273 void cmcCdaItem::setDirty( bool state )
00274 {
00275   m_dirty = state;
00276   m_onChanged = dateTimeStamp();
00277   emit updated();
00278 }
00279 
00280 
00281 void cmcCdaItem::setId( const QUuid & value )
00282 {
00283   m_id = value;
00284   setDirty(true);
00285 }
00286 
00287 void cmcCdaItem::setIdGroup( const QUuid & value )
00288 {
00289   m_idGroup = value;
00290   setDirty(true);
00291 }
00292 
00293 void cmcCdaItem::setIdLock( const QUuid & value )
00294 {
00295   m_idLock = value;
00296   setDirty(true);
00297 }
00298 
00299 void cmcCdaItem::setIdOwner( const QUuid & value )
00300 {
00301   m_idOwner = value;
00302   setDirty(true);
00303 }
00304 
00305 void cmcCdaItem::setIdSymlink( const QUuid & value )
00306 {
00307   m_idSymlink = value;
00308   setDirty(true);
00309 }
00310 
00311 void cmcCdaItem::setIsDeleted( bool value )
00312 {
00313   m_isDeleted = value;
00314   setDirty(true);
00315 }
00316 
00317 void cmcCdaItem::setIsHidden( bool value )
00318 {
00319   m_isHidden = value;
00320   setDirty(true);
00321 }
00322 
00323 void cmcCdaItem::setIsLocked( bool value )
00324 {
00325   m_isLocked = value;
00326   setDirty(true);
00327 }
00328 
00329 void cmcCdaItem::setIsParent( bool value )
00330 {
00331   m_isParent = value;
00332   setDirty(true);
00333 }
00334 
00335 void cmcCdaItem::setIsShared( bool value )
00336 {
00337   m_isShared = value;
00338   setDirty(true);
00339 }
00340 
00341 void cmcCdaItem::setItemData( const QString & value )
00342 {
00343   m_itemData = value;
00344   setDirty(true);
00345 }
00346 
00347 void cmcCdaItem::setItemMode( long value )
00348 {
00349   m_itemMode = value;
00350   setDirty(true);
00351 }
00352 
00353 void cmcCdaItem::setItemName( const QString & value )
00354 {
00355   setObjectName( value );
00356   setDirty(true);
00357 }
00358 
00359 void cmcCdaItem::setItemSort( const QString & value )
00360 {
00361   m_itemSort = value;
00362   setDirty(true);
00363 }
00364 
00365 void cmcCdaItem::setItemType( const QString & value )
00366 {
00367   m_itemType = value;
00368   setDirty(true);
00369 }
00370 
00371 void cmcCdaItem::setOnCreated( const QString & value )
00372 {
00373   m_onCreated = value;
00374   setDirty(true);
00375 }
00376 
00377 void cmcCdaItem::setOnChanged( const QString & value )
00378 {
00379   setDirty(true);
00380 }
00381 
00382 void cmcCdaItem::setOnDeleted( const QString & value )
00383 {
00384   m_onDeleted = value;
00385   setDirty(true);
00386 }
00387 
00388 void cmcCdaItem::setVersion( const QString & value )
00389 {
00390   m_version = value;
00391   setDirty(true);
00392 }
00393 
00394 
00395 
00396 
00397 
00398 
00399 cmcCursor * cmcCdaItem::getCursor()
00400 {
00401   /*
00402   ** Get a cursor.  Note that the caller is responsible for destroying this cursor.
00403   **
00404   */
00405   cmcCursor * cursor = app()-> database()-> getCursor( "~cda" );
00406 
00407   /*
00408   ** If our ID is set, then we can just fetch the item directly. No need
00409   **  to search by parent and item name.
00410   **
00411   */
00412   if( !id().isNull() )
00413   {
00414     cursor-> setFilter("[ViewFilter(1,F,,id,Equal to," + dq(id().toString()) + ")]");
00415     return( cursor );
00416   }
00417 
00418   /*
00419   ** We don't have an item ID, therefore we must search by parent ID and item
00420   **  name.  If we have a parent then we set a filter that includes reference to our
00421   **  parent ID.  If we don't have a parent, then we look for any items that
00422   **  have a parent ID set to all zeros.
00423   **
00424   */
00425   cursor-> setFilter( "[ViewFilter(1,F,,idParent,Equal to," + dq(idParent().toString()) + ")]" );
00426 
00427   /*
00428   ** Now that we've established a relationship to a parent item, set a filter
00429   **  that's equal to our item's name.  Items under a particular parent cannot
00430   **  have duplicate names.  This does not mean that names cannot be duplicated,
00431   **  only items with the same parent cannot be duplicated.  It's just like a
00432   **  file-system.
00433   **
00434   */
00435   cursor-> setFilter( "[ViewFilter(2,F,,itemName,Equal to," + dq(itemName()) + ")]" );
00436 
00437   /*
00438   ** Technically we're only suppose to end up with a single item.  If we get more
00439   **  than one then this really should be a fatal error.  For now, we'll just post
00440   **  a message.
00441   **
00442   */
00443   if( cursor-> rowCount() > 1 )
00444   {
00445     TRACE_MESSAGE( "row count too high!  Watch out!" );
00446   }
00447 
00448   /*
00449   ** Return the cursor - filtered or not.
00450   **
00451   */
00452   return( cursor );
00453 
00454 } // endcmcCursor * cmcCdaItem::getCursor()
00455 
00456 
00457 bool cmcCdaItem::clear()
00458 {
00459   setId          ( idNull );
00460   setIdGroup     ( idNull );
00461   setIdLock      ( idNull );
00462   setIdOwner     ( idNull );
00463   setIdSymlink   ( idNull );
00464   setIsDeleted   ( false  );
00465   setIsHidden    ( false  );
00466   setIsLocked    ( false  );
00467   setIsParent    ( false  );
00468   setIsShared    ( false  );
00469   m_itemAutoId   = -1;
00470   setItemMode    ( 0  );
00471   setItemSort    ( "" );
00472   setItemType    ( "" );
00473   setOnChanged   ( dateTimeStamp() );
00474   setOnCreated   ( dateTimeStamp() );
00475   setOnDeleted   ( "" );
00476   setVersion     ( "1" );
00477 
00478   m_itemData.clear();
00479 
00480   return( true );
00481 }
00482 
00483 bool cmcCdaItem::load()
00484 {
00485   /*
00486   ** Get a local-wrapped cursor.  Local-wrapped means it will be 
00487   **  automatically destroyed when this function exits.
00488   **
00489   */
00490 #ifdef USE_SCOPED_POINTER
00491   QScopedPointer<cmcCursor> cursor( getCursor() );
00492 #else
00493   std::auto_ptr<cmcCursor> cursor( getCursor() );
00494 #endif
00495 
00496   /*
00497   ** Check the row count.  If it is not exactly one row, then we cannot
00498   **  continue.
00499   **
00500   */
00501   if( cursor-> rowCount() != 1 )
00502   {
00503     /*
00504     ** Default the uuid to something new.
00505     **
00506     */
00507     m_id = QUuid::createUuid();
00508 
00509     /*
00510     ** Return that we were not able to load this item.
00511     **
00512     */
00513     return( false );
00514 
00515   }
00516 
00517   /*
00518   ** Get a query rowset on the cursor.  We'll use that to load the data.
00519   **
00520   */
00521 #ifdef USE_SCOPED_POINTER
00522   QScopedPointer<cmcRowSet> qrs( cursor-> getQueryRowSet(1) );
00523 #else
00524   std::auto_ptr<cmcRowSet> qrs( cursor-> getQueryRowSet(1) );
00525 #endif
00526 
00527 #ifdef USE_SCOPED_POINTER
00528   if( qrs.data() == 0 )
00529 #else
00530   if( qrs.get() == 0 )
00531 #endif
00532     return( false );
00533 
00534   /*
00535   ** The query should also return exactly one row.  If it does not
00536   **  then we must quit.
00537   **
00538   */
00539   if( qrs-> rowCount() != 1 )
00540     return( false );
00541 
00542   /*
00543   ** Read out all the column values into this object.
00544   **
00545   */
00546   setObjectName( qrs-> getRowString ( 0, "itemName"   ) );
00547 
00548   m_id          = qrs-> getRowString ( 0, "id"         );
00549   m_idGroup     = qrs-> getRowString ( 0, "idGroup"    );
00550   m_idLock      = qrs-> getRowString ( 0, "idLock"     );
00551   m_idOwner     = qrs-> getRowString ( 0, "idOwner"    );
00552   m_idSymlink   = qrs-> getRowString ( 0, "idSymlink"  );
00553   m_isDeleted   = qrs-> getRowBool   ( 0, "isDeleted"  );
00554   m_isHidden    = qrs-> getRowBool   ( 0, "isHidden"   );
00555   m_isLocked    = qrs-> getRowBool   ( 0, "isLocked"   );
00556   m_isParent    = qrs-> getRowBool   ( 0, "isParent"   );
00557   m_isShared    = qrs-> getRowBool   ( 0, "isShared"   );
00558   m_itemAutoId  = qrs-> getRowLong   ( 0, "itemAutoId" );
00559   m_itemData    = qrs-> getRowString ( 0, "itemData"   );
00560   m_itemMode    = qrs-> getRowLong   ( 0, "itemMode"   );
00561   m_itemSort    = qrs-> getRowString ( 0, "itemSort"   );
00562   m_itemType    = qrs-> getRowString ( 0, "ItemType"   );
00563   m_onChanged   = qrs-> getRowString ( 0, "onChanged"  );
00564   m_onCreated   = qrs-> getRowString ( 0, "onCreated"  );
00565   m_onDeleted   = qrs-> getRowString ( 0, "onDeleted"  );
00566   m_version     = qrs-> getRowString ( 0, "version  "  );
00567 
00568   /*
00569   ** Return 'success' that we were able to load this item
00570   **
00571   */
00572   return( true );
00573 
00574 } // endbool cmcCdaItem::load()
00575 
00576 long cmcCdaItem::updateRowSet( cmcRowSet * rowSet )
00577 {
00578   /*
00579   ** Update all the fields in the row set.
00580   **
00581   */
00582   rowSet-> modifyRow( 0, "id",        id()         );
00583   rowSet-> modifyRow( 0, "idGroup",   idGroup()    );
00584   rowSet-> modifyRow( 0, "idLock",    idLock()     );
00585   rowSet-> modifyRow( 0, "idOwner",   idOwner()    );
00586   rowSet-> modifyRow( 0, "idParent",  idParent()   );
00587   rowSet-> modifyRow( 0, "idSymlink", idSymlink()  );
00588   rowSet-> modifyRow( 0, "isDeleted", isDeleted()  );
00589   rowSet-> modifyRow( 0, "isHidden",  isHidden()   );
00590   rowSet-> modifyRow( 0, "isLocked",  isLocked()   );
00591   rowSet-> modifyRow( 0, "isParent",  isParent()   );
00592   rowSet-> modifyRow( 0, "isShared",  isShared()   );
00593   rowSet-> modifyRow( 0, "itemData",  itemData()   );
00594   rowSet-> modifyRow( 0, "itemMode",  itemMode()   );
00595   rowSet-> modifyRow( 0, "itemName",  itemName()   );
00596   rowSet-> modifyRow( 0, "itemSort",  itemSort()   );
00597   rowSet-> modifyRow( 0, "ItemType",  itemType()   );
00598   rowSet-> modifyRow( 0, "onChanged", onChanged()  );
00599   rowSet-> modifyRow( 0, "onCreated", onCreated()  );
00600   rowSet-> modifyRow( 0, "onDeleted", onDeleted()  );
00601   rowSet-> modifyRow( 0, "version",   version()    );
00602   
00603   return( rowSet-> commit() );
00604 
00605 } // endlong cmcCdaItem::updateRowSet( cmcRowSet * rowSet )
00606 
00607 bool cmcCdaItem::save()
00608 {
00609   /*
00610   ** Get a local-wrapped cursor.  Local-wrapped means it will be 
00611   **  automatically destroyed when this function exits.
00612   **
00613   */
00614 #ifdef USE_SCOPED_POINTER
00615   QScopedPointer<cmcCursor> cursor( getCursor() );
00616 #else
00617   std::auto_ptr<cmcCursor> cursor( getCursor() );
00618 #endif
00619 
00620   /*
00621   ** We do different things depending on what we've got to work with.
00622   **
00623   */
00624   switch( cursor-> rowCount() )
00625   {
00626     /*
00627     ** No records means we have to write out this item newly.
00628     **
00629     */
00630     case 0:
00631     {
00632 #ifdef USE_SCOPED_POINTER
00633       QScopedPointer<cmcRowSet> ars( cursor-> getAddRowSet(1) );
00634       updateRowSet( ars.data() );
00635 #else
00636       std::auto_ptr<cmcRowSet> ars( cursor-> getAddRowSet(1) );
00637       updateRowSet( ars.get() );
00638 #endif
00639 
00640       break;
00641 
00642     } // endcase 0:
00643 
00644     /*
00645     ** One record means we have to update the existing item.
00646     **
00647     */
00648     case 1:
00649     {
00650 #ifdef USE_SCOPED_POINTER
00651       QScopedPointer<cmcRowSet> ers( cursor-> getEditRowSet(1) );
00652       updateRowSet( ers.data() );
00653 #else
00654       std::auto_ptr<cmcRowSet> ers( cursor-> getEditRowSet(1) );
00655       updateRowSet( ers.get() );
00656 #endif
00657       break;
00658 
00659     } // endcase 1:
00660 
00661     /*
00662     ** This is a problem.  We should have 1 or zero rows, not more than
00663     **  1.  If there is more than one then that means there is a duplicate
00664     **  item somewhere in our database, and this doesn't work!  That's like
00665     **  having two sub-directories in the same directory with the same name,
00666     **  or a directory and a filename with the same name - it just doesn't
00667     **  work.
00668     **
00669     */
00670     default:
00671     {
00672       TRACE_MESSAGE( "cmcCdaItem::save() too many rows" );
00673       return( false );
00674 
00675     } // enddefault:
00676 
00677   } // endswitch( cursor-> rowCount() )
00678 
00679   /*
00680   ** Indicate that this item is no longer dirty.
00681   **
00682   */
00683   m_dirty = false;
00684 
00685   /*
00686   ** Save all the children
00687   **
00688   */
00689   QList<cmcCdaItem*> items = findChildren<cmcCdaItem*>();
00690   foreach( cmcCdaItem * item, items )
00691   {
00692     if( item-> dirty() ) item-> save();
00693   }
00694 
00695   return( true );
00696 
00697 } // endbool cmcCdaItem::save()
00698 
00699 
00700 void cmcCdaItem::dumpInfo()
00701 {
00702   qDebug( "id         :%s",  qPrintable(id().toString())        );
00703   qDebug( "idGroup    :%s",  qPrintable(idGroup().toString())   );
00704   qDebug( "idLock     :%s",  qPrintable(idLock().toString())    );
00705   qDebug( "idOwner    :%s",  qPrintable(idOwner().toString())   );
00706   qDebug( "idParent   :%s",  qPrintable(idParent().toString())  );
00707   qDebug( "idSymlink  :%s",  qPrintable(idSymlink().toString()) );
00708   qDebug( "isDeleted  :%s",  isDeleted()? "true":"false"        );
00709   qDebug( "isHidden   :%s",  isHidden()? "true":"false"         );
00710   qDebug( "isLocked   :%s",  isLocked()? "true":"false"         );
00711   qDebug( "isParent   :%s",  isParent()? "true":"false"         );
00712   qDebug( "isShared   :%s",  isShared()? "true":"false"         );
00713   qDebug( "itemAutoId :%ld", itemAutoId()                       );
00714   qDebug( "itemData   :%s",  qPrintable(itemData())             );
00715   qDebug( "itemMode   :%ld", itemMode()                         );
00716   qDebug( "itemName   :%s",  qPrintable(itemName())             );
00717   qDebug( "itemSort   :%s",  qPrintable(itemSort())             );
00718   qDebug( "itemType   :%s",  qPrintable(itemType())             );
00719   qDebug( "onChanged  :%s",  qPrintable(onChanged())            );
00720   qDebug( "onCreated  :%s",  qPrintable(onCreated())            );
00721   qDebug( "onDeleted  :%s",  qPrintable(onDeleted())            );
00722   qDebug( "version    :%s",  qPrintable(version())              );
00723 }
00724 
00725 
00726 } // endnamespace cmcDatabaseApi 
00727 
 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