<br><br><div class="gmail_quote">On Thu, Jul 1, 2010 at 8:35 AM, Alvaro Soliverez <span dir="ltr">&lt;<a href="mailto:asoliverez@gmail.com">asoliverez@gmail.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
Hello Brian,<br>
see my comments below.<br>
<div class="im"><br>
On Thu, Jul 1, 2010 at 12:36 AM, Brian Cappello &lt;<a href="mailto:briancappello@gmail.com">briancappello@gmail.com</a>&gt; wrote:<br>
&gt; Hi Alvaro,<br>
&gt; Thanks so much for taking the time to review and write out all of these<br>
&gt; insightful comments! Now the challenge of fixing them :) I noticed too that<br>
&gt; you were accepted to KDE e.V., congratulations!<br>
&gt;<br>
&gt; On Tue, Jun 29, 2010 at 10:46 PM, Alvaro Soliverez &lt;<a href="mailto:asoliverez@gmail.com">asoliverez@gmail.com</a>&gt;<br>
&gt; wrote:<br>
&gt;&gt;<br>
&gt;&gt; Hello Brian,<br>
&gt;&gt; here is a first review of the code:<br>
&gt;&gt;<br>
&gt;&gt; - For strings that will be displayed to the user, please use i18n, so<br>
&gt;&gt; the strings can be translated<br>
&gt;&gt; - Create a folder to drop all CMake modules there<br>
&gt;&gt; - Add unit tests, at least for all public methods in the backend classes<br>
&gt;<br>
&gt;<br>
&gt; From reading Wikipedia I gather unit tests are a collection of calls to<br>
&gt; methods that verify if expected outcomes are met? How is it best to<br>
&gt; integrate these into my code? Should they be contained in their own method,<br>
&gt; or a separate class, or the UI frontend even? Is there any kind of<br>
&gt; best-practice with regards to unit tests?<br>
&gt;<br>
</div>Here is a link to QTest, the recommended unit testing framework for Qt.<br>
Unit testing is more easily done for backend classes (ui classes can<br>
be tested, it&#39;s just more cumbersome). With cmake, you can run cmake<br>
test, and it will execute all tests and inform the result.<br>
<br>
For every backend class &lt;class&gt;, you should have a class &lt;class&gt;test.<br>
It should have a test method for each public method of &lt;class&gt;. Try to<br>
test for those corner cases in the class that might be hard to find if<br>
not looking exactly at it.<br>
<br>
Also, look for &quot;test-drive development&quot;, which relies on creating the<br>
unit tests first, and the main code later.<br></blockquote><div><br> I must have missed the link, were you referring to the perl based QTest at <a href="http://qtest.qbilt.org">qtest.qbilt.org</a> or Qt&#39;s QTestLib? Anyway, I&#39;ve been doing some reading on test-driven development so I&#39;ll definitely work on adjusting my work flow to design the class methods around the test requirements... might need to rethink how some things are currently done, though I really need to get my feet wet with unit testing before I can know for sure. I&#39;m assuming I should take a tangent from developing more features and functionality to make sure what&#39;s there is properly testable first? Seems like it should be higher priority, even though I&#39;m beginning to slip from the schedule I laid out for myself... thoughts?<br>
</div><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
<div class="im"><br>
<br>
&gt;&gt;<br>
&gt;&gt; - When initializing a class, QString should be initialized on the same<br>
&gt;&gt; call and not on the body.<br>
&gt;&gt;<br>
&gt;&gt; CompanyInfoPlugin::CompanyInfoPlugin()<br>
&gt;&gt; {<br>
&gt;&gt;  m_pluginName = &quot;CompanyInfoPlugin&quot;;<br>
&gt;&gt;<br>
&gt;&gt; should be<br>
&gt;&gt;<br>
&gt;&gt; CompanyInfoPlugin::CompanyInfoPlugin():<br>
&gt;&gt;  m_pluginName(&quot;CompanyInfoPlugin&quot;)<br>
&gt;&gt; {<br>
&gt;&gt;<br>
&gt;&gt; That is more efficient, because it saves a QString instance.<br>
&gt;<br>
&gt; OK that&#39;s easy enough. Can the same pre-body initialization be done for<br>
&gt; things like QStringList/QHash too?<br>
<br>
</div>No, in that case you have to initialize that in the body. Create a<br>
separate method for those initialization, so you leave the body code<br>
as clean as possible.<br>
<div class="im"><br>
&gt;&gt;<br>
&gt;&gt; - Avoid using &quot;select *&quot; on queries. That&#39;s prone to errors in the<br>
&gt;&gt; future and less efficient as tables start growing<br>
&gt;<br>
&gt; OK, tried to fix those.<br>
&gt;&gt;<br>
&gt;&gt; - You should use queries with bind values as opposed to create the<br>
&gt;&gt; whole query string each time.<br>
&gt;<br>
&gt; I&#39;m pretty confused by what can be a bound variable, and how to use them<br>
&gt; when the number of columns/values isn&#39;t known ahead of time. For example,<br>
&gt; populating a QString with some columns and then saying this doesn&#39;t work:<br>
&gt; query.prepare(&quot;select :columns from ... &quot;)<br>
&gt; query.bindValue(:columns, mySelectColumnsQString);<br>
&gt; query.exec();<br>
&gt; qDebug() &lt;&lt; query.lastQuery() == &quot;select ? from ...&quot;<br>
&gt;<br>
<br>
</div>Why do you not know which columns you are retrieving?<br></blockquote><div><br>Sorry, guess I wasn&#39;t too clear with what I meant. That &quot;select ? from ...&quot; is Qt&#39;s way of saying it didn&#39;t understand my bind variable, I think. (I had initialized mySelectColumnsQString to symbol,name,date,time,open,high,low,close,volume but the last-executed query only came back with the &quot;?&quot;.) The way I have the db-storage/retrieval methods set up now is to take a generic list of keys (which are also the column names) as input. Currently there is only support for a few keys/columns implemented, but, to add more simply requires modifying backend.cpp&#39;s master column list and statsmanager.cpp&#39;s m_yahooKeys look-up hash; the rest of the (current) code is meant to be key/column-generic. So, at least the way things are currently structured, the column names are known but the specific columns are flexible. <br>
<br>For a predefined query, such as looking up the last price quote which will always require the same columns, I could add bind variables the same way that Qt doc you linked suggests. But, I&#39;m confused with how to do bind variables once support for more keys has been added and the specific keys/columns requested by clients becomes unpredictable. Which leads me to your comment about just retrieving all the columns: since QSqlQuery doesn&#39;t support accessing results by column name (at least not directly), in order to return just the requested keys/columns, the &quot;index&quot; of the column in the database would need to be looked up by doing something like query.value( db_columns.indexOf( &quot;keyName&quot; ) ).toString(), for each requested key, where db_columns is the list of all the column names used to initially create the table. At least, that&#39;s the only way I know how to do it, but that&#39;s obviously not saying much. I guess I&#39;m just a little lost with what&#39;s the best way to integrate bind variables into the way I&#39;ve currently structured my code or if I should try to group related keys as predefined queries and let clients deal with selecting what they need or something else entirely...<br>
<br></div><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
In some cases, if you are retrieving 3-4-5 columns depending on the<br>
case, it&#39;s better to just retrieve all 5 columns, and use the data you<br>
need that to keep building the query on-the-fly.<br>
<br>
Unless you are retrieving big blobs, the performance degradation from<br>
retrieving an extra column is minimal, and you gain on simplicity and<br>
maintainability.<br>
<div><div></div><div class="h5"><br>
<br>
&gt; I&#39;ll keep playing around with it though, there must be a way...<br>
&gt;&gt;<br>
&gt;&gt; query.exec( &quot;SELECT * FROM symbolinfo WHERE symbol=&#39;&quot; + symbolCAPS + &#39;\&#39;&#39;<br>
&gt;&gt; );<br>
&gt;&gt;<br>
&gt;&gt; should be similar to this example in<br>
&gt;&gt; <a href="http://doc.trolltech.com/4.6/qsqlquery.html#details" target="_blank">http://doc.trolltech.com/4.6/qsqlquery.html#details</a><br>
&gt;&gt;<br>
&gt;&gt; QSqlQuery query;<br>
&gt;&gt;     query.prepare(&quot;INSERT INTO person (id, forename, surname) &quot;<br>
&gt;&gt;                   &quot;VALUES (:id, :forename, :surname)&quot;);<br>
&gt;&gt;     query.bindValue(0, 1001);<br>
&gt;&gt;     query.bindValue(1, &quot;Bart&quot;);<br>
&gt;&gt;     query.bindValue(2, &quot;Simpson&quot;);<br>
&gt;&gt;     query.exec();<br>
&gt;&gt;<br>
&gt;&gt; That&#39;s much more efficient, and much more secure if the queries are<br>
&gt;&gt; open to user intervention.<br>
&gt;&gt;<br>
&gt;&gt; - Get rid of QDebug statements on the commited code. That suggests<br>
&gt;&gt; that unit tests are extremely necessary. As a rule, don&#39;t commit code<br>
&gt;&gt; with QDebug (unless it is commented out, of course)<br>
&gt;<br>
&gt; Good to know. And definitely does suggest I need unit tests - most of my<br>
&gt; &quot;unit testing&quot; is done manually, verifying results on the debug output...<br>
&gt; definitely time to change that work flow :)<br>
&gt;&gt;<br>
&gt;&gt; - I see that a number of classes have an interesting amount of<br>
&gt;&gt; parameters which all seem to be related.<br>
&gt;&gt; For example:<br>
&gt;&gt; searchResults( const QString &amp;searchTerm,<br>
&gt;&gt;                        const QStringList &amp;symbols,<br>
&gt;&gt;                        const QStringList &amp;names,<br>
&gt;&gt;                        const QStringList &amp;exchanges,<br>
&gt;&gt;                        const QStringList &amp;types );<br>
&gt;&gt;<br>
&gt;&gt; You should create a class to contain these values and just pass an<br>
&gt;&gt; instance of it. The patter is called Data Transfer Object (DTO)<br>
&gt;<br>
&gt; OK. When you say instance, is it best to create a DTO using new or to<br>
&gt; pass-by-reference?<br>
<br>
</div></div>When possible, try to pass by reference, like you are doing here.<br>
<br>
Just fill in the object with the same data you were passing, and pass<br>
only one object by reference.<br>
You could use a QList&lt;QList&gt;, for example, if you have trouble sending<br>
custom classes across DBus.<br>
<div class="im"><br>
 I&#39;ve always been kind of confused about understanding<br>
&gt; when non-pointer objects get automatically deleted from memory. In this<br>
&gt; specific example, that signal ends up getting emitted across DBus, so, first<br>
&gt; I need to figure how to pass custom types through adaptors before I can fix<br>
&gt; that one :/<br>
&gt;&gt;<br>
&gt;&gt; - I&#39;ve noticed you added some krazy excludes. Is there a reason for that?<br>
&gt;&gt;  Krazy excludes should be added only as last-instance, when it is<br>
&gt;&gt; certain there is a false positive.<br>
&gt;&gt;<br>
&gt;&gt; *  Copyright (c) 2010 Brian Cappello            //krazy:exclude=copyright<br>
&gt;&gt;  *  briancappello [at] gmail [dot] com<br>
&gt;&gt;<br>
&gt;&gt; In this case, Krazy could not find the email, probably. Using [at] and<br>
&gt;&gt; [dot] won&#39;t stop the email harvesters, so use the proper form and<br>
&gt;&gt; relay on the gmail spam filter.<br>
&gt;<br>
&gt; OK, that was dumb, will remove those.<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt; And, to emphasize, test, test, and test. :)<br>
&gt;&gt;<br>
&gt;&gt; I still have to review the design. I&#39;ll get to it during the next few<br>
&gt;&gt; days.<br>
&gt;&gt;<br>
</div><div><div></div><div class="h5">_______________________________________________<br>
Kde-finance-apps mailing list<br>
<a href="mailto:Kde-finance-apps@kde.org">Kde-finance-apps@kde.org</a><br>
<a href="https://mail.kde.org/mailman/listinfo/kde-finance-apps" target="_blank">https://mail.kde.org/mailman/listinfo/kde-finance-apps</a><br>
</div></div></blockquote></div><br>