[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    playground/office/alkimia/alkquotes/backend
From:       Brian Cappello <cappellokde () gmail ! com>
Date:       2010-07-07 3:58:42
Message-ID: 20100707035842.16B49AC85D () svn ! kde ! org
[Download RAW message or body]

SVN commit 1146937 by bcappello:

some refactoring in the ctors of Backend.cpp and StatsManager.cpp, moved plugins to \
their own directories

 M  +4 -14     CMakeLists.txt  
 M  +65 -21    backend.cpp  
 M  +17 -2     backend.h  
 D             companyinfoplugin.cpp  
 D             companyinfoplugin.h  
 D             plugininterfaces.h  
 A             plugins (directory)  
 A             plugins/CMakeLists.txt  
 A             plugins/companyinfoplugin (directory)  
 A             plugins/companyinfoplugin/CMakeLists.txt  
 A             plugins/companyinfoplugin/companyinfoplugin.cpp   [License: LGPL]
 A             plugins/companyinfoplugin/companyinfoplugin.h   [License: LGPL]
 A             plugins/plugininterfaces.h   [License: LGPL]
 A             plugins/symbolsuggesterplugin (directory)  
 A             plugins/symbolsuggesterplugin/CMakeLists.txt  
 A             plugins/symbolsuggesterplugin/symbolsuggesterplugin.cpp   [License: \
LGPL]  A             plugins/symbolsuggesterplugin/symbolsuggesterplugin.h   \
[License: LGPL]  M  +44 -29    statsmanager.cpp  
 M  +5 -0      statsmanager.h  
 D             symbolsuggesterplugin.cpp  
 D             symbolsuggesterplugin.h  


--- trunk/playground/office/alkimia/alkquotes/backend/CMakeLists.txt #1146936:1146937
@@ -7,6 +7,8 @@
 SET( QT_USE_QTNETWORK true )
 SET( QT_USE_QTSCRIPT true )
 
+ADD_SUBDIRECTORY(plugins)
+
 INCLUDE( ${QT_USE_FILE} )
 ADD_DEFINITIONS( ${QT_DEFINITIONS} )
 ADD_DEFINITIONS( -DQT_PLUGIN )
@@ -14,7 +16,8 @@
 INCLUDE_DIRECTORIES( ${QT_INCUDE_DIR} 
 		     ${QT_QTNETWORK_INCLUDE_DIR} 
 		     ${QDBUS_INCLUDE_DIRS} 
-		     ${QT_QTSQL_INCLUDE_DIR} )
+		     ${QT_QTSQL_INCLUDE_DIR}
+		     ${CMAKE_CURRENT_SOURCE_DIR}/plugins )
 
 SET( backend_SRCs
      main.cpp
@@ -22,8 +25,6 @@
      symbolmanager.cpp
      statsmanager.cpp
      downloader.cpp 
-     symbolsuggesterplugin.cpp
-     companyinfoplugin.cpp
       )
 
 # set all QObjects to have their MOC files generated
@@ -32,9 +33,6 @@
      symbolmanager.h
      statsmanager.h
      downloader.h 
-     plugininterfaces.h
-     symbolsuggesterplugin.h
-     companyinfoplugin.h
       )
 
 QT4_WRAP_CPP( backend_MOC_SRCs ${backend_MOC_Headers} )
@@ -43,18 +41,10 @@
 QT4_ADD_DBUS_ADAPTOR( backend_SRCs org.kde.quotebackend.symbolmanager.xml \
symbolmanager.h SymbolManager )  QT4_ADD_DBUS_ADAPTOR( backend_SRCs \
org.kde.quotebackend.statsmanager.xml statsmanager.h StatsManager )  
-
-ADD_LIBRARY(symbolsuggesterplugin SHARED ${backend_SRCs} ${backend_MOC_SRCs} )
-#ADD_LIBRARY(companyinfoplugin SHARED ${backend_SRCs} ${backend_MOC_SRCs} )
-
 ADD_EXECUTABLE( quotebackend ${backend_SRCs} ${backend_MOC_SRCs} )
 TARGET_LINK_LIBRARIES( quotebackend ${QT_LIBRARIES} )
 INSTALL( TARGETS quotebackend ${INSTALL_TARGETS_DEFAULT_ARGS} )
 
-TARGET_LINK_LIBRARIES( symbolsuggesterplugin  ${QT_LIBRARIES}  ) #companyinfoplugin
-
-INSTALL( TARGETS symbolsuggesterplugin ${INSTALL_TARGETS_DEFAULT_ARGS} LIBRARY \
                DESTINATION plugins ) #companyinfoplugin
-
 # install the adaptor xml description files so clients can build against them (is \
--prefix/interfaces the correct place for these?)  FILE(GLOB adaptorfiles \
"${CMAKE_CURRENT_SOURCE_DIR}/*.xml")  INSTALL(FILES ${adaptorfiles} DESTINATION \
interfaces) \ No newline at end of file
--- trunk/playground/office/alkimia/alkquotes/backend/backend.cpp #1146936:1146937
@@ -29,25 +29,18 @@
 Backend::Backend( QObject *parent ) 
 	: QObject(parent)
 {
-  /// Set the columns contained in the database. These names should be the same as \
                key names used elsewhere.
-  // TODO: Adding/removing columns to/from a db table must be gracefully handled. \
                google ALTER TABLE
-  columns << "symbol"
-	  << "name"
-	  << "date"
-	  << "time"
-	  << "open"
-	  << "high"
-	  << "low"
-	  << "close"
-	  << "volume"
-	  << "mktcap";
+  // set the master list of columns we want stored in the 'symbolinfo' db table
+  initializeDBColumnsList();
 	  
-  // load the SQLITE database. This will load existing tables, or create new ones if \
necessary. +  // load the SQLITE database. This will load the existing 'symbolinfo' \
table, or create a new one if necessary  loadDatabase( "quotebackend.db" );
  
+  // make sure the loaded 'symbolinfo' table's columns are the same as the master \
list db_columns +  updateDBColumns();
+  
   // initialize private objects
   m_symbolManager = new SymbolManager(db, this);
-  m_statsManager = new StatsManager(db, columns, this);
+  m_statsManager = new StatsManager(db, db_columns, this);
   
   // Whenever a DBus client wants to initialize new symbols, connect that signal to \
backend's private function  // so that we can tell private objects to do their thing \
without symbolManager needing to know about them @@ -97,6 +90,57 @@
   delete m_statsManager;
 }
 
+void Backend::initializeDBColumnsList()
+{  
+  /// Set the all the column-keys we want to store in the database. 
+  //These names should be the same as key names used throughout the rest of the \
program +  db_columns << "symbol"
+	      << "name"
+	      << "date"
+	      << "time"
+	      << "open"
+	      << "high"
+	      << "low"
+	      << "close"
+	      << "volume"
+	      << "mktcap";
+}
+
+void Backend::updateDBColumns()
+{
+  QStringList tmpColumns;
+  
+  /// query what columns already exist in the on-disk database
+  QSqlQuery query;
+  query.exec("PRAGMA table_info('symbolinfo')");
+  query.first(); // skip the id PRIMARY KEY column
+  if( query.isValid() )
+  {
+    while( query.next() )
+      tmpColumns << query.value(1).toString(); // read the existing column names \
into a list +    
+    /// check to see if any columns in db_columns aren't yet stored in the on-disk \
database +    if( tmpColumns.size() != db_columns.size() )
+    {
+      for( int i = 0; i < db_columns.size(); ++i )
+      {
+	if( !tmpColumns.contains( db_columns.at(i) ) )
+	{
+	  /// add any new columns
+	  query.exec("ALTER TABLE symbolinfo ADD COLUMN " + db_columns.at(i) + " TEXT");
+	  qDebug() << "Backend::updateDBColumns: Adding column: " + query.lastQuery();
+	}
+      }
+    }
+    else
+      qDebug() << "Backend::updateDBColumns: db_columns and tmpColumns sizes \
matched."; +    
+  }
+  else
+    qDebug() << "Backend::updateDBColumns: PRAGMA table_info failed: " + \
query.lastError().text(); +  
+}
+
 void Backend::symbolDeleted( const QString &symbol )
 {
   db_listTable( "symbolinfo" );
@@ -129,7 +173,7 @@
     if( query.isValid() )
     {
       qDebug() << "loadDatabase: data already exists";
-      db_listTable("symbolinfo");
+      
       /*
       query.exec("SELECT * FROM symbolinfo");
       if( query.isActive() )
@@ -146,9 +190,9 @@
       QString queryCreate = "CREATE TABLE symbolinfo (id INTEGER PRIMARY KEY";
       
       // set the column names to create. for now everything is stored as TEXT
-      for( int i = 0; i < columns.size(); i++ )
+      for( int i = 0; i < db_columns.size(); i++ )
       {
-	queryCreate += ", " + columns.at(i) + " TEXT";
+	queryCreate += ", " + db_columns.at(i) + " TEXT";
       }
       queryCreate += ')';
       qDebug() << "Backend::loadDatabase: createQuery: " + queryCreate;
@@ -185,8 +229,8 @@
   qDebug() << "Backend::db_listTable: " + tableName;
   
   QString selectColumns = "id";
-  for( int i = 0; i < columns.size(); ++i )
-    selectColumns += ',' + columns.at(i);
+  for( int i = 0; i < db_columns.size(); ++i )
+    selectColumns += ',' + db_columns.at(i);
   
   QSqlQuery query;
   query.exec( "SELECT " + selectColumns + " FROM " + tableName );
@@ -194,8 +238,8 @@
   {
     QString tmp;
     tmp += "id=" + query.value(0).toString();
-    for( int i = 1; i <= columns.size(); ++i )
-      tmp += ", " + columns.at(i-1) + '=' + query.value(i).toString();
+    for( int i = 1; i <= db_columns.size(); ++i )
+      tmp += ", " + db_columns.at(i-1) + '=' + query.value(i).toString();
     
     qDebug() << tmp;
   }
--- trunk/playground/office/alkimia/alkquotes/backend/backend.h #1146936:1146937
@@ -48,7 +48,6 @@
   Q_OBJECT
   
   public:
-    
     Backend( QObject *parent = 0 );
     ~Backend();
     
@@ -63,10 +62,21 @@
     */
     void initializeSymbols( const QStringList &symbols, bool saveHistory );
     
+  /**
+    * symbolDeleted is connected to SymbolManager's symbolDeleted signal. For now \
this doesn't do +    * anything other than list the contents of the updated table.
+    */
     void symbolDeleted( const QString &symbol );
     
   private:
     
+  /**
+    * initializeDBColumnsList gets called by the ctor to populate db_columns with \
the master list of +    * columns we want stored in the database. db_columns is also \
used as the default list of keys to +    * initialize a symbol with.
+    */
+    void initializeDBColumnsList();
+    
   /** loadDatabase( const QString &filename )
     * This function will load an existing SQLITE db from disk, or create a new db if \
                one doesn't exist.
     * If a new database was created, this function will also create any new tables.
@@ -76,6 +86,11 @@
     */
     bool loadDatabase( const QString &filename );
     
+  /**
+    * updateDBColumns gets called from the ctor to update an existing table with new \
columns, if necessary +    */
+    void updateDBColumns();
+    
   /** db_listTable( const QString &tableName )
     * Call this to print tableName's entire contents to the console.
     *
@@ -85,7 +100,7 @@
     
     // Private Objects
     QSqlDatabase db;
-    QStringList columns; // Columns contained in the database. 
+    QStringList db_columns; // Columns contained in the database. 
 			 // Also used as the list of default keys to initialize new symbols with
     
     SymbolManager *m_symbolManager;
--- trunk/playground/office/alkimia/alkquotes/backend/statsmanager.cpp \
#1146936:1146937 @@ -33,21 +33,37 @@
 {
   //loadPlugins();
   
+  // initialize this object's private objects
+  m_downloader = new Downloader(this);
+  connect( m_downloader, SIGNAL( dataDownloaded( const QUrl &, QStringList * ) ),
+	   this, SLOT( dataDownloaded( const QUrl &, QStringList * ) ) );
+  
+  m_currentlyDownloading = new QHash<QString, QStringList*>;
+  
+  m_yahooKeys = new QHash<QString, QString>;
+  m_keysToInitialize = new QStringList;
+  initializeKeysLists();
+  
   // setup dbus for this object
   new StatsManagerAdaptor(this);
   QDBusConnection dbus = QDBusConnection::sessionBus();
   dbus.registerObject( "/StatsManager", this );
   dbus.registerService("org.kde.quotebackend");
+}
   
-  // initialize this object's private objects
-  m_downloader = new Downloader(this);
-  connect( m_downloader, SIGNAL( dataDownloaded( const QUrl &, QStringList * ) ),
-	   this, SLOT( dataDownloaded( const QUrl &, QStringList * ) ) );
+StatsManager::~StatsManager()
+{
+  QDBusConnection::sessionBus().unregisterObject("/StatsManager");
   
-  m_currentlyDownloading = new QHash<QString, QStringList*>;
+  delete m_downloader;
+  delete m_yahooKeys;
+  delete m_keysToInitialize;
+}
   
-  // create a look-up hash of the keys yahoo uses for downloading data
-  m_yahooKeys = new QHash<QString, QString>;
+void StatsManager::initializeKeysLists()
+{ 
+  /// create a look-up hash of the keys yahoo uses for downloading data
+  // for all possible definitions see http://www.gummy-stuff.org/Yahoo-data.htm
   m_yahooKeys->insert("error", "e1");
   m_yahooKeys->insert("symbol", "s");
   m_yahooKeys->insert("name", "n");
@@ -61,26 +77,32 @@
 				      //   if signed into yahoo? Or paid for? Always returns 'N/A' for me)
   m_yahooKeys->insert("volume", "v");
   m_yahooKeys->insert("mktcap", "j1");
+  m_yahooKeys->insert("change", "c6"); // 'c1' for delayed, 'c6' for real-time // \
both are from previous open +  m_yahooKeys->insert("eps", "e");
+  m_yahooKeys->insert("ebitda", "j4");
   
-  // create a look-up list of the default key names to initialize
-  m_keysToInitialize = new QStringList;
+  /// create a look-up list of the default key names to initialize
   for( int i = 0; i < db_columns.size(); ++i )
+    if( m_yahooKeys->contains( db_columns.at(i) ) )
     m_keysToInitialize->append( db_columns.at(i) );
   
   // the database stores time in its own column, but we can't download the time (at \
least not independent of the close)  m_keysToInitialize->removeAt( \
                m_keysToInitialize->indexOf( "time" ) );
-
 }
 
 void StatsManager::loadPlugins()
 {
   QDir pluginsDir( QCoreApplication::applicationDirPath() );
+  qDebug() << "StatsManager: ApplicationDirPath=" + pluginsDir.path();
   
+  pluginsDir.cdUp();
   if( !pluginsDir.cd("plugins") )
   {
-    qDebug() << "StatsManager: couldn't find plugin dir";
+    qDebug() << "StatsManager: Couldn't find plugin directory";
     return;
   }
+  else
+    qDebug() << "StatsManager: PluginDirPath=" + pluginsDir.path();
   
   foreach( const QString& filename, pluginsDir.entryList(QDir::Files) )
   {
@@ -88,20 +110,11 @@
     if( KeysInterface *interface = qobject_cast<KeysInterface *>(loader.instance()) \
)  {
       interfaces.append(interface);
-      qDebug() << "StatsManager: successfully loaded test plugin";
+      qDebug() << "StatsManager: successfully loaded plugin: " + \
interface->pluginName();  }
   } 
 }
 
-StatsManager::~StatsManager()
-{
-  QDBusConnection::sessionBus().unregisterObject("/StatsManager");
-  
-  delete m_downloader;
-  delete m_yahooKeys;
-  delete m_keysToInitialize;
-}
-
 /** initializeSymbols( const QStringList &symbols )
   *
   * This gets called by Backend whenever new symbols are added. Also used for \
individual symbols. @@ -472,12 +485,10 @@
   queryUpdate += " WHERE symbol=:symbol";
   
   //qDebug() << "db_updateSymbol query: " + queryUpdate;
-  
   query.prepare(queryUpdate);
   for( int i = 0; i < keys->size(); ++i )
     query.bindValue(':' + keys->at(i), results->at(i) );
   
-  if( !keys->contains("symbol") )
     query.bindValue(":symbol", symbol );
   
   query.exec();
@@ -524,20 +535,24 @@
 {
   qDebug() << "StatsManager::db_listTable: " + tableName;
   
-  QString selectColumns = "id";
-  for( int i = 0; i < db_columns.size(); ++i )
-    selectColumns += ',' + db_columns.at(i);
+  QSqlQuery query;
+  QStringList selectColumns;
   
-  QSqlQuery query;
-  query.exec( "SELECT " + selectColumns + " FROM " + tableName );
+  // read all of symbolinfo's column names into a list
+  if( query.exec("PRAGMA table_info('symbolinfo')") )
+  {
   while( query.next() )
+      selectColumns << query.value(1).toString(); 
+  }
+  
+  query.exec( "SELECT " + selectColumns.join(",") + " FROM " + tableName );
+  while( query.next() )
   {
     QString tmp;
     tmp += "id=" + query.value(0).toString();
     for( int i = 1; i <= db_columns.size(); ++i )
       tmp += ", " + db_columns.at(i-1) + '=' + query.value(i).toString();
     
-    //tmp.remove(0,1); // strip leading comma
     qDebug() << tmp;
   }
 }
--- trunk/playground/office/alkimia/alkquotes/backend/statsmanager.h #1146936:1146937
@@ -128,6 +128,11 @@
     QString formatDownloadedResult( QStringList *keys, QStringList &results );
     
   /**
+    * initializeKeysLists() gets called from the ctor to populate m_yahooKeys and \
m_keysToInitialize +    */
+    void initializeKeysLists();
+    
+  /**
     * Call db_insertSymbol to initialize a new entry in the database for the symbol.
     *
     * @param symbol The symbol to add to the database.


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic