1 <!DOCTYPE html PUBLIC
"-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
2 <html lang=
"et" xmlns=
"http://www.w3.org/1999/xhtml" xml:
lang=
"et">
5 <meta http-equiv=
"CONTENT-TYPE" content=
"text/html; charset=utf-8" />
6 <title>eVaf Tutorial -
07 - Storage Module
</title>
7 <meta name=
"Author" content=
"Enar Väikene" />
8 <meta name=
"description" content=
"eVaf Tutorial" />
9 <meta name=
"keywords" content=
"evaf c++ application development framework tutorial password generator" />
10 <link rel=
"StyleSheet" href=
"evaf.css" type=
"text/css" media=
"all" />
11 <link rel=
"StyleSheet" href=
"highlight.css" type=
"text/css" media=
"all" />
16 <h1>eVaf Tutorial
</h1>
18 <h2>07 - Storage Module
</h2>
20 <p>Create the
<tt>module.cpp
</tt> file in the
<tt>src/apps/PswGen/Storage
</tt> directory:
</tt>
22 <pre class=
"hl"><span class=
"hl com">/**
</span>
23 <span class=
"hl com"> *
@file PswGen/Storage/module.cpp
</span>
24 <span class=
"hl com"> */
</span>
26 <span class=
"hl ppc">#include
</span> <span class=
"hl pps">"module.h
"</span><span class=
"hl ppc"></span>
27 <span class=
"hl ppc">#include
<QtCore
></span></pre>
29 <p>Copy version information files from the
<tt>Generator
<tt> module:
</p>
31 <pre>evaf/src/apps/PswGen/Storage $
<code>cp ../Generator/version.{h,rc} .
</code></pre>
33 <p>Modify the
<tt>version.h
</tt> file:
</p>
35 <pre class=
"hl"><span class=
"hl com">/**
</span>
36 <span class=
"hl com"> *
@file PswGen/Storage/version.h
</span>
37 <span class=
"hl com"> */
</span>
39 <span class=
"hl ppc">#ifndef __PSWGEN_STORAGE_VERSION_H
</span>
40 <span class=
"hl ppc">#define __PSWGEN_STORAGE_VERSION_H
</span>
42 <span class=
"hl ppc">#include
<version_rc.h
></span>
44 <span class=
"hl com">/**
</span>
45 <span class=
"hl com"> * Module/library version number in the form major,minor,release,build
</span>
46 <span class=
"hl com"> */
</span>
47 <span class=
"hl ppc">#define VER_FILE_VERSION
0,
1,
1,
1</span>
49 <span class=
"hl com">/**
</span>
50 <span class=
"hl com"> * Module/library version number in the string format (shall end with \
0)
</span>
51 <span class=
"hl com"> */
</span>
52 <span class=
"hl ppc">#define VER_FILE_VERSION_STR
</span> <span class=
"hl pps">"0.1.1.1\
0"</span><span class=
"hl ppc"></span>
54 <span class=
"hl com">/**
</span>
55 <span class=
"hl com"> * Module/library name (shall end with \
0)
</span>
56 <span class=
"hl com"> */
</span>
57 <span class=
"hl ppc">#define VER_MODULE_NAME_STR
</span> <span class=
"hl pps">"PswStorage\
0"</span><span class=
"hl ppc"></span>
59 <span class=
"hl com">/**
</span>
60 <span class=
"hl com"> * Module type (see version_rc.h for all the types)
</span>
61 <span class=
"hl com"> */
</span>
62 <span class=
"hl ppc">#define VER_MODULE_TYPE MT_GENERIC
</span>
64 <span class=
"hl com">/**
</span>
65 <span class=
"hl com"> * Module type in the string format (see version_rc for all the types)
</span>
66 <span class=
"hl com"> */
</span>
67 <span class=
"hl ppc">#define VER_MODULE_TYPE_STR MT_GENERIC
</span>
69 <span class=
"hl com">/**
</span>
70 <span class=
"hl com"> * Original file name for windows (shall end with \
0)
</span>
71 <span class=
"hl com"> */
</span>
72 <span class=
"hl ppc">#define VER_ORIGINAL_FILE_NAME_STR
</span> <span class=
"hl pps">"PswStorage.dll\
0"</span><span class=
"hl ppc"></span>
74 <span class=
"hl com">/**
</span>
75 <span class=
"hl com"> * Description of the module/library (shall end with \
0)
</span>
76 <span class=
"hl com"> */
</span>
77 <span class=
"hl ppc">#define VER_FILE_DESCRIPTION_STR
</span> <span class=
"hl pps">"Module that stores data for generating strong passwords.\
0"</span><span class=
"hl ppc"></span>
79 <span class=
"hl ppc">#endif
</span> <span class=
"hl slc">// version.h
</span><span class=
"hl ppc"></span></pre>
81 <p>Include the
<tt>version.h
</tt> header file in
<tt>module.cpp
</tt> and export version information:
</p>
84 <span class=
"hl ppc">#include
</span> <span class=
"hl pps">"version.h
"</span><span class=
"hl ppc"></span>
86 <span class=
"hl kwd">VER_EXPORT_VERSION_INFO
</span><span class=
"hl opt">()
</span></pre>
88 <p>Make it a proper Qt plugin by using the
<tt>Q_EXPORT_PLUGIN2()
</tt> macro:
</p>
90 <pre class=
"hl"><span class=
"hl kwd">Q_EXPORT_PLUGIN2
</span><span class=
"hl opt">(
</span>VER_MODULE_NAME_STR
<span class=
"hl opt">,
</span> eVaf
<span class=
"hl opt">::
</span>PswGen
<span class=
"hl opt">::
</span>Storage
<span class=
"hl opt">::
</span>Module
<span class=
"hl opt">)
</span></pre>
92 <p>The
<tt>Module
</tt> class creates the internal
<tt>StorageImpl
</tt> object in the constructor, but initializes it in the
93 <tt>init()
</tt> method. This way we can return errors from the module if initialization fails. Similarly, we finalize the
94 internal
<tt>StorageImpl
</tt> object in the
<tt>done()
</tt> method and delete in the destructor.
</p>
96 <p>The module is ready when the internal
<tt>StorageImpl
</tt> object is initalized and we set the
<tt>mReady
</tt> flag to
97 <tt>true
</tt> when the initialization is done and back to
<tt>false
</tt> in the
<tt>done()
</tt> method.
</p>
99 <p>The rest of the code sets the name of the object and outputs info messages.
</p>
101 <pre class=
"hl">Module
<span class=
"hl opt">::
</span><span class=
"hl kwd">Module
</span><span class=
"hl opt">()
</span>
102 <span class=
"hl opt">:
</span> Plugins
<span class=
"hl opt">::
</span><span class=
"hl kwd">iPlugin
</span><span class=
"hl opt">()
</span>
103 <span class=
"hl opt">,
</span> <span class=
"hl kwd">mReady
</span><span class=
"hl opt">(
</span><span class=
"hl kwa">false
</span><span class=
"hl opt">)
</span>
104 <span class=
"hl opt">{
</span>
105 <span class=
"hl kwd">setObjectName
</span><span class=
"hl opt">(
</span><span class=
"hl kwd">QString
</span><span class=
"hl opt">(
</span><span class=
"hl str">"%
1.%
2"</span><span class=
"hl opt">).
</span><span class=
"hl kwd">arg
</span><span class=
"hl opt">(
</span>VER_MODULE_NAME_STR
<span class=
"hl opt">).
</span><span class=
"hl kwd">arg
</span><span class=
"hl opt">(
</span>__FUNCTION__
<span class=
"hl opt">));
</span>
107 mStorage
<span class=
"hl opt">=
</span> <span class=
"hl kwa">new
</span> Internal
<span class=
"hl opt">::
</span>StorageImpl
<span class=
"hl opt">;
</span>
109 <span class=
"hl kwd">EVAF_INFO
</span><span class=
"hl opt">(
</span><span class=
"hl str">"%s created
"</span><span class=
"hl opt">,
</span> <span class=
"hl kwd">qPrintable
</span><span class=
"hl opt">(
</span><span class=
"hl kwd">objectName
</span><span class=
"hl opt">()));
</span>
110 <span class=
"hl opt">}
</span>
112 Module
<span class=
"hl opt">::~
</span><span class=
"hl kwd">Module
</span><span class=
"hl opt">()
</span>
113 <span class=
"hl opt">{
</span>
114 <span class=
"hl kwa">delete
</span> mStorage
<span class=
"hl opt">;
</span>
116 <span class=
"hl kwd">EVAF_INFO
</span><span class=
"hl opt">(
</span><span class=
"hl str">"%s destroyed
"</span><span class=
"hl opt">,
</span> <span class=
"hl kwd">qPrintable
</span><span class=
"hl opt">(
</span><span class=
"hl kwd">objectName
</span><span class=
"hl opt">()));
</span>
117 <span class=
"hl opt">}
</span>
119 <span class=
"hl kwb">bool
</span> Module
<span class=
"hl opt">::
</span><span class=
"hl kwd">init
</span><span class=
"hl opt">(
</span>QString
<span class=
"hl kwb">const
</span> <span class=
"hl opt">&</span> args
<span class=
"hl opt">)
</span>
120 <span class=
"hl opt">{
</span>
121 <span class=
"hl kwd">Q_UNUSED
</span><span class=
"hl opt">(
</span>args
<span class=
"hl opt">);
</span>
123 <span class=
"hl kwa">if
</span> <span class=
"hl opt">(!
</span>mStorage
<span class=
"hl opt">-
></span><span class=
"hl kwd">init
</span><span class=
"hl opt">())
</span>
124 <span class=
"hl kwa">return false
</span><span class=
"hl opt">;
</span>
126 mReady
<span class=
"hl opt">=
</span> <span class=
"hl kwa">true
</span><span class=
"hl opt">;
</span>
128 <span class=
"hl kwd">EVAF_INFO
</span><span class=
"hl opt">(
</span><span class=
"hl str">"%s initialized
"</span><span class=
"hl opt">,
</span> <span class=
"hl kwd">qPrintable
</span><span class=
"hl opt">(
</span><span class=
"hl kwd">objectName
</span><span class=
"hl opt">()));
</span>
130 <span class=
"hl kwa">return true
</span><span class=
"hl opt">;
</span>
131 <span class=
"hl opt">}
</span>
133 <span class=
"hl kwb">void
</span> Module
<span class=
"hl opt">::
</span><span class=
"hl kwd">done
</span><span class=
"hl opt">()
</span>
134 <span class=
"hl opt">{
</span>
135 mReady
<span class=
"hl opt">=
</span> <span class=
"hl kwa">false
</span><span class=
"hl opt">;
</span>
137 mStorage
<span class=
"hl opt">-
></span><span class=
"hl kwd">done
</span><span class=
"hl opt">();
</span>
139 <span class=
"hl kwd">EVAF_INFO
</span><span class=
"hl opt">(
</span><span class=
"hl str">"%s finalized
"</span><span class=
"hl opt">,
</span> <span class=
"hl kwd">qPrintable
</span><span class=
"hl opt">(
</span><span class=
"hl kwd">objectName
</span><span class=
"hl opt">()));
</span>
140 <span class=
"hl opt">}
</span></pre>
142 <p>The
<tt>StorageImpl
</tt> class does very little in the constructor and in the destructor:
</p>
144 <pre class=
"hl">StorageImpl
<span class=
"hl opt">::
</span><span class=
"hl kwd">StorageImpl
</span><span class=
"hl opt">()
</span>
145 <span class=
"hl opt">:
</span> <span class=
"hl kwd">QAbstractListModel
</span><span class=
"hl opt">()
</span>
146 <span class=
"hl opt">{
</span>
147 <span class=
"hl kwd">setObjectName
</span><span class=
"hl opt">(
</span><span class=
"hl kwd">QString
</span><span class=
"hl opt">(
</span><span class=
"hl str">"%
1.iGenerator
"</span><span class=
"hl opt">).
</span><span class=
"hl kwd">arg
</span><span class=
"hl opt">(
</span>VER_MODULE_NAME_STR
<span class=
"hl opt">));
</span>
149 <span class=
"hl kwd">EVAF_INFO
</span><span class=
"hl opt">(
</span><span class=
"hl str">"%s created
"</span><span class=
"hl opt">,
</span> <span class=
"hl kwd">qPrintable
</span><span class=
"hl opt">(
</span><span class=
"hl kwd">objectName
</span><span class=
"hl opt">()));
</span>
150 <span class=
"hl opt">}
</span>
152 StorageImpl
<span class=
"hl opt">::~
</span><span class=
"hl kwd">StorageImpl
</span><span class=
"hl opt">()
</span>
153 <span class=
"hl opt">{
</span>
154 <span class=
"hl kwd">EVAF_INFO
</span><span class=
"hl opt">(
</span><span class=
"hl str">"%s destroyed
"</span><span class=
"hl opt">,
</span> <span class=
"hl kwd">qPrintable
</span><span class=
"hl opt">(
</span><span class=
"hl kwd">objectName
</span><span class=
"hl opt">()));
</span>
155 <span class=
"hl opt">}
</span></pre>
157 <p>Initialization of the
<tt>StorageImpl
</tt> class happens in the
<tt>init()
</tt> method, where we open the database connection,
158 create tables if necessary and load data from the database. We also register the
<tt>iStorage
</tt> interface in the global
159 registry of interfaces.
</p>
161 <p>We use the
<tt>Common::iApp
</tt> interface to find the data root directory where the SQLITE database file is going to be
164 <pre class=
"hl"><span class=
"hl kwb">bool
</span> StorageImpl
<span class=
"hl opt">::
</span><span class=
"hl kwd">init
</span><span class=
"hl opt">()
</span>
165 <span class=
"hl opt">{
</span>
166 <span class=
"hl slc">// Open the database
</span>
167 <span class=
"hl kwa">if
</span> <span class=
"hl opt">(!
</span>QSqlDatabase
<span class=
"hl opt">::
</span><span class=
"hl kwd">contains
</span><span class=
"hl opt">(
</span>DbConnectionName
<span class=
"hl opt">)) {
</span>
168 <span class=
"hl slc">// No database connection yet
</span>
169 mDb
<span class=
"hl opt">=
</span> QSqlDatabase
<span class=
"hl opt">::
</span><span class=
"hl kwd">addDatabase
</span><span class=
"hl opt">(
</span><span class=
"hl str">"QSQLITE
"</span><span class=
"hl opt">,
</span> DbConnectionName
<span class=
"hl opt">);
</span>
170 mDb
<span class=
"hl opt">.
</span><span class=
"hl kwd">setDatabaseName
</span><span class=
"hl opt">(
</span>Common
<span class=
"hl opt">::
</span>iApp
<span class=
"hl opt">::
</span><span class=
"hl kwd">instance
</span><span class=
"hl opt">()-
></span><span class=
"hl kwd">dataRootDir
</span><span class=
"hl opt">() +
</span> DbName
<span class=
"hl opt">);
</span>
171 <span class=
"hl kwa">if
</span> <span class=
"hl opt">(!
</span>mDb
<span class=
"hl opt">.
</span><span class=
"hl kwd">open
</span><span class=
"hl opt">()) {
</span>
172 QSqlError err
<span class=
"hl opt">=
</span> mDb
<span class=
"hl opt">.
</span><span class=
"hl kwd">lastError
</span><span class=
"hl opt">();
</span>
173 <span class=
"hl kwd">EVAF_ERROR
</span><span class=
"hl opt">(
</span><span class=
"hl str">"Failed to open database : %s
"</span><span class=
"hl opt">,
</span> <span class=
"hl kwd">qPrintable
</span><span class=
"hl opt">(
</span>err
<span class=
"hl opt">.
</span><span class=
"hl kwd">text
</span><span class=
"hl opt">()));
</span>
174 <span class=
"hl kwa">return false
</span><span class=
"hl opt">;
</span>
175 <span class=
"hl opt">}
</span>
176 <span class=
"hl opt">}
</span>
177 <span class=
"hl kwa">else
</span> <span class=
"hl opt">{
</span>
178 <span class=
"hl slc">// Database connection already exists
</span>
179 mDb
<span class=
"hl opt">=
</span> QSqlDatabase
<span class=
"hl opt">::
</span><span class=
"hl kwd">database
</span><span class=
"hl opt">(
</span>DbConnectionName
<span class=
"hl opt">);
</span>
180 <span class=
"hl opt">}
</span>
182 <span class=
"hl slc">// Create tables if necessary
</span>
183 <span class=
"hl kwa">if
</span> <span class=
"hl opt">(!
</span><span class=
"hl kwd">createTables
</span><span class=
"hl opt">())
</span>
184 <span class=
"hl kwa">return false
</span><span class=
"hl opt">;
</span>
186 <span class=
"hl slc">// Load data
</span>
187 <span class=
"hl kwa">if
</span> <span class=
"hl opt">(!
</span><span class=
"hl kwd">loadData
</span><span class=
"hl opt">())
</span>
188 <span class=
"hl kwa">return false
</span><span class=
"hl opt">;
</span>
190 <span class=
"hl slc">/// Register our interface
</span>
191 Common
<span class=
"hl opt">::
</span>iRegistry
<span class=
"hl opt">::
</span><span class=
"hl kwd">instance
</span><span class=
"hl opt">()-
></span><span class=
"hl kwd">registerInterface
</span><span class=
"hl opt">(
</span><span class=
"hl str">"iStorage
"</span><span class=
"hl opt">,
</span> <span class=
"hl kwa">this
</span><span class=
"hl opt">);
</span>
193 <span class=
"hl kwd">EVAF_INFO
</span><span class=
"hl opt">(
</span><span class=
"hl str">"%s initialized
"</span><span class=
"hl opt">,
</span> <span class=
"hl kwd">qPrintable
</span><span class=
"hl opt">(
</span><span class=
"hl kwd">objectName
</span><span class=
"hl opt">()));
</span>
195 <span class=
"hl kwa">return true
</span><span class=
"hl opt">;
</span>
196 <span class=
"hl opt">}
</span></pre>
198 <p>The finalization of the
<tt>StorageImpl
</tt> class happens in the
<tt>done()
</tt> method, where we only need to clear the list
199 of shared data objects:
</p>
201 <pre class=
"hl"><span class=
"hl kwb">void
</span> StorageImpl
<span class=
"hl opt">::
</span><span class=
"hl kwd">done
</span><span class=
"hl opt">()
</span>
202 <span class=
"hl opt">{
</span>
203 mData
<span class=
"hl opt">.
</span><span class=
"hl kwd">clear
</span><span class=
"hl opt">();
</span>
204 <span class=
"hl kwd">EVAF_INFO
</span><span class=
"hl opt">(
</span><span class=
"hl str">"%s finalized
"</span><span class=
"hl opt">,
</span> <span class=
"hl kwd">qPrintable
</span><span class=
"hl opt">(
</span><span class=
"hl kwd">objectName
</span><span class=
"hl opt">()));
</span>
205 <span class=
"hl opt">}
</span></pre>
207 <p>The
<tt>StorageImpl::save()
</tt> method verifies that the shared data object is valid and the name not empty. Then it either
208 adds a new data record to the database or updates an existing one.
</p>
210 <pre class=
"hl"><span class=
"hl kwb">bool
</span> StorageImpl
<span class=
"hl opt">::
</span><span class=
"hl kwd">save
</span><span class=
"hl opt">(
</span>QString
<span class=
"hl kwb">const
</span> <span class=
"hl opt">&</span> name
<span class=
"hl opt">,
</span> QExplicitlySharedDataPointer
<span class=
"hl opt"><</span>Storage
<span class=
"hl opt">::
</span>Data
<span class=
"hl opt">></span> data
<span class=
"hl opt">)
</span>
211 <span class=
"hl opt">{
</span>
212 <span class=
"hl kwd">EVAF_TEST_X
</span><span class=
"hl opt">(
</span>data
<span class=
"hl opt">,
</span> <span class=
"hl str">"Data cannot be null
"</span><span class=
"hl opt">);
</span>
213 <span class=
"hl kwd">EVAF_TEST_X
</span><span class=
"hl opt">(!
</span>name
<span class=
"hl opt">.
</span><span class=
"hl kwd">isEmpty
</span><span class=
"hl opt">(),
</span> <span class=
"hl str">"Name cannot be empty
"</span><span class=
"hl opt">);
</span>
215 <span class=
"hl slc">// Is it an update or a new data record?
</span>
216 <span class=
"hl kwa">if
</span> <span class=
"hl opt">(
</span>mData
<span class=
"hl opt">.
</span><span class=
"hl kwd">constFind
</span><span class=
"hl opt">(
</span>name
<span class=
"hl opt">) !=
</span> mData
<span class=
"hl opt">.
</span><span class=
"hl kwd">constEnd
</span><span class=
"hl opt">()) {
</span>
217 <span class=
"hl slc">// This is an update
</span>
218 <span class=
"hl kwa">if
</span> <span class=
"hl opt">(
</span>data
<span class=
"hl opt">-
></span><span class=
"hl kwd">modified
</span><span class=
"hl opt">()) {
</span>
219 QSqlQuery
<span class=
"hl kwd">q
</span><span class=
"hl opt">(
</span>mDb
<span class=
"hl opt">);
</span>
220 <span class=
"hl kwa">if
</span> <span class=
"hl opt">(!
</span>q
<span class=
"hl opt">.
</span><span class=
"hl kwd">exec
</span><span class=
"hl opt">(
</span><span class=
"hl kwd">QString
</span><span class=
"hl opt">(
</span><span class=
"hl str">"UPDATE data SET length =
</span> <span class=
"hl esc">\'
</span><span class=
"hl str">%
1</span><span class=
"hl esc">\'
</span><span class=
"hl str">, flags =
</span> <span class=
"hl esc">\'
</span><span class=
"hl str">%
2</span><span class=
"hl esc">\'
</span> <span class=
"hl str">WHERE name =
</span> <span class=
"hl esc">\'
</span><span class=
"hl str">%
3</span><span class=
"hl esc">\'
</span><span class=
"hl str">;
"</span><span class=
"hl opt">)
</span>
221 <span class=
"hl opt">.
</span><span class=
"hl kwd">arg
</span><span class=
"hl opt">(
</span>data
<span class=
"hl opt">-
></span><span class=
"hl kwd">length
</span><span class=
"hl opt">()).
</span><span class=
"hl kwd">arg
</span><span class=
"hl opt">(
</span>data
<span class=
"hl opt">-
></span><span class=
"hl kwd">flags
</span><span class=
"hl opt">()).
</span><span class=
"hl kwd">arg
</span><span class=
"hl opt">(
</span>name
<span class=
"hl opt">))) {
</span>
222 QSqlError err
<span class=
"hl opt">=
</span> mDb
<span class=
"hl opt">.
</span><span class=
"hl kwd">lastError
</span><span class=
"hl opt">();
</span>
223 <span class=
"hl kwd">EVAF_ERROR
</span><span class=
"hl opt">(
</span><span class=
"hl str">"Failed to update
</span> <span class=
"hl esc">\'
</span><span class=
"hl str">%s
</span><span class=
"hl esc">\'
</span> <span class=
"hl str">: %s
"</span><span class=
"hl opt">,
</span> <span class=
"hl kwd">qPrintable
</span><span class=
"hl opt">(
</span>name
<span class=
"hl opt">),
</span> <span class=
"hl kwd">qPrintable
</span><span class=
"hl opt">(
</span>err
<span class=
"hl opt">.
</span><span class=
"hl kwd">text
</span><span class=
"hl opt">()));
</span>
224 <span class=
"hl kwa">return false
</span><span class=
"hl opt">;
</span>
225 <span class=
"hl opt">}
</span>
226 <span class=
"hl opt">}
</span>
227 <span class=
"hl opt">}
</span>
228 <span class=
"hl kwa">else
</span> <span class=
"hl opt">{
</span>
229 <span class=
"hl slc">// Store to the database
</span>
230 QSqlQuery
<span class=
"hl kwd">q
</span><span class=
"hl opt">(
</span>mDb
<span class=
"hl opt">);
</span>
231 <span class=
"hl kwa">if
</span> <span class=
"hl opt">(!
</span>q
<span class=
"hl opt">.
</span><span class=
"hl kwd">exec
</span><span class=
"hl opt">(
</span><span class=
"hl kwd">QString
</span><span class=
"hl opt">(
</span><span class=
"hl str">"INSERT INTO data (name, length, flags) VALUES (
</span><span class=
"hl esc">\'
</span><span class=
"hl str">%
1</span><span class=
"hl esc">\'
</span><span class=
"hl str">, %
2, %
3);
"</span><span class=
"hl opt">)
</span>
232 <span class=
"hl opt">.
</span><span class=
"hl kwd">arg
</span><span class=
"hl opt">(
</span>name
<span class=
"hl opt">).
</span><span class=
"hl kwd">arg
</span><span class=
"hl opt">(
</span>data
<span class=
"hl opt">-
></span><span class=
"hl kwd">length
</span><span class=
"hl opt">())
</span>
233 <span class=
"hl opt">.
</span><span class=
"hl kwd">arg
</span><span class=
"hl opt">(
</span><span class=
"hl kwb">int
</span><span class=
"hl opt">(
</span>data
<span class=
"hl opt">-
></span><span class=
"hl kwd">flags
</span><span class=
"hl opt">())))) {
</span>
234 QSqlError err
<span class=
"hl opt">=
</span> mDb
<span class=
"hl opt">.
</span><span class=
"hl kwd">lastError
</span><span class=
"hl opt">();
</span>
235 <span class=
"hl kwd">EVAF_ERROR
</span><span class=
"hl opt">(
</span><span class=
"hl str">"Failed to insert
</span> <span class=
"hl esc">\'
</span><span class=
"hl str">%s
</span><span class=
"hl esc">\'
</span> <span class=
"hl str">: %s
"</span><span class=
"hl opt">,
</span> <span class=
"hl kwd">qPrintable
</span><span class=
"hl opt">(
</span>name
<span class=
"hl opt">),
</span> <span class=
"hl kwd">qPrintable
</span><span class=
"hl opt">(
</span>err
<span class=
"hl opt">.
</span><span class=
"hl kwd">text
</span><span class=
"hl opt">()));
</span>
236 <span class=
"hl kwa">return false
</span><span class=
"hl opt">;
</span>
237 <span class=
"hl opt">}
</span>
239 <span class=
"hl slc">// Store also into the local hash
</span>
240 mData
<span class=
"hl opt">.
</span><span class=
"hl kwd">insert
</span><span class=
"hl opt">(
</span>name
<span class=
"hl opt">,
</span> data
<span class=
"hl opt">);
</span>
242 <span class=
"hl slc">// Reset the model
</span>
243 <span class=
"hl kwd">reset
</span><span class=
"hl opt">();
</span>
244 <span class=
"hl opt">}
</span>
246 data
<span class=
"hl opt">-
></span><span class=
"hl kwd">reset
</span><span class=
"hl opt">();
</span>
248 <span class=
"hl kwa">return true
</span><span class=
"hl opt">;
</span>
249 <span class=
"hl opt">}
</span></pre>
251 <p>Calling the
<tt>reset()
</tt> method resets the
<tt>QAbstractItemModel
</tt> data model and assures that the associated widget
252 updates the
<tt>QCompleter
</tt> with a fresh list of auto completion words. Resetting the data model in this case is fine as
253 long as the data model is simple and the list short. The proper way would be finding out the actual insertion point and using
254 <tt>beginInsertRows()
</tt> and
<tt>endInsertRows()
</tt> methods.
</p>
256 <p>Querying data is much simpler thanks to the internal
<tt>QMap
</tt> container:
</p>
258 <pre class=
"hl">QExplicitlySharedDataPointer
<span class=
"hl opt"><</span>Storage
<span class=
"hl opt">::
</span>Data
<span class=
"hl opt">></span> StorageImpl
<span class=
"hl opt">::
</span><span class=
"hl kwd">query
</span><span class=
"hl opt">(
</span>QString
<span class=
"hl kwb">const
</span> <span class=
"hl opt">&</span> name
<span class=
"hl opt">)
</span> <span class=
"hl kwb">const
</span>
259 <span class=
"hl opt">{
</span>
260 QMap
<span class=
"hl opt"><</span>QString
<span class=
"hl opt">,
</span> QExplicitlySharedDataPointer
<span class=
"hl opt"><</span>Storage
<span class=
"hl opt">::
</span>Data
<span class=
"hl opt">> >::
</span>const_iterator it
<span class=
"hl opt">=
</span> mData
<span class=
"hl opt">.
</span><span class=
"hl kwd">constFind
</span><span class=
"hl opt">(
</span>name
<span class=
"hl opt">);
</span>
261 <span class=
"hl kwa">if
</span> <span class=
"hl opt">(
</span>it
<span class=
"hl opt">!=
</span> mData
<span class=
"hl opt">.
</span><span class=
"hl kwd">constEnd
</span><span class=
"hl opt">())
</span>
262 <span class=
"hl kwa">return
</span> it
<span class=
"hl opt">.
</span><span class=
"hl kwd">value
</span><span class=
"hl opt">();
</span>
263 <span class=
"hl kwa">else
</span>
264 <span class=
"hl kwa">return
</span> QExplicitlySharedDataPointer
<span class=
"hl opt"><</span>Storage
<span class=
"hl opt">::
</span>Data
<span class=
"hl opt">>();
</span>
265 <span class=
"hl opt">}
</span></pre>
267 <p>We return an empty
<tt>QExplicitlySharedDataPointer
</tt> object if no data objects with the given name exists.
</p>
269 <p>The
<tt>data()
</tt> method returns names of data objects for the
<tt>QCompleter
</tt> auto completion list of words:
</p>
271 <pre class=
"hl">QVariant StorageImpl
<span class=
"hl opt">::
</span><span class=
"hl kwd">data
</span><span class=
"hl opt">(
</span>QModelIndex
<span class=
"hl kwb">const
</span> <span class=
"hl opt">&</span> index
<span class=
"hl opt">,
</span> <span class=
"hl kwb">int
</span> role
<span class=
"hl opt">)
</span> <span class=
"hl kwb">const
</span>
272 <span class=
"hl opt">{
</span>
273 <span class=
"hl kwa">if
</span> <span class=
"hl opt">(!
</span>index
<span class=
"hl opt">.
</span><span class=
"hl kwd">isValid
</span><span class=
"hl opt">() ||
</span> index
<span class=
"hl opt">.
</span><span class=
"hl kwd">row
</span><span class=
"hl opt">()
<</span> <span class=
"hl num">0</span> <span class=
"hl opt">||
</span> index
<span class=
"hl opt">.
</span><span class=
"hl kwd">row
</span><span class=
"hl opt">()
>=
</span> mData
<span class=
"hl opt">.
</span><span class=
"hl kwd">size
</span><span class=
"hl opt">() ||
</span> index
<span class=
"hl opt">.
</span><span class=
"hl kwd">column
</span><span class=
"hl opt">() !=
</span> <span class=
"hl num">0</span><span class=
"hl opt">)
</span>
274 <span class=
"hl kwa">return
</span> <span class=
"hl kwd">QVariant
</span><span class=
"hl opt">();
</span>
276 <span class=
"hl kwa">if
</span> <span class=
"hl opt">(
</span>role
<span class=
"hl opt">==
</span> Qt
<span class=
"hl opt">::
</span>EditRole
<span class=
"hl opt">||
</span> role
<span class=
"hl opt">==
</span> Qt
<span class=
"hl opt">::
</span>DisplayRole
<span class=
"hl opt">)
</span>
277 <span class=
"hl kwa">return
</span> mData
<span class=
"hl opt">.
</span><span class=
"hl kwd">keys
</span><span class=
"hl opt">().
</span><span class=
"hl kwd">at
</span><span class=
"hl opt">(
</span>index
<span class=
"hl opt">.
</span><span class=
"hl kwd">row
</span><span class=
"hl opt">());
</span>
279 <span class=
"hl kwa">return
</span> <span class=
"hl kwd">QVariant
</span><span class=
"hl opt">();
</span>
280 <span class=
"hl opt">}
</span></pre>
282 <p>The
<tt>createTabled()
</tt> method creates the
<tt>data
</tt> table if it does not exist. This function could be improved to
283 alter the
<tt>data
</tt> table if it exists, but is from an older version. Right now we assume that if the table exists, it
284 is good for our application:
</p>
286 <pre class=
"hl"><span class=
"hl kwb">bool
</span> StorageImpl
<span class=
"hl opt">::
</span><span class=
"hl kwd">createTables
</span><span class=
"hl opt">()
</span>
287 <span class=
"hl opt">{
</span>
288 QSqlQuery
<span class=
"hl kwd">q
</span><span class=
"hl opt">(
</span>mDb
<span class=
"hl opt">);
</span>
289 <span class=
"hl kwa">if
</span> <span class=
"hl opt">(!
</span>q
<span class=
"hl opt">.
</span><span class=
"hl kwd">exec
</span><span class=
"hl opt">(
</span><span class=
"hl str">"SELECT name FROM sqlite_master WHERE type=
</span><span class=
"hl esc">\'
</span><span class=
"hl str">table
</span><span class=
"hl esc">\'
</span> <span class=
"hl str">AND name=
</span><span class=
"hl esc">\'
</span><span class=
"hl str">data
</span><span class=
"hl esc">\'
</span><span class=
"hl str">;
"</span><span class=
"hl opt">)) {
</span>
290 QSqlError err
<span class=
"hl opt">=
</span> mDb
<span class=
"hl opt">.
</span><span class=
"hl kwd">lastError
</span><span class=
"hl opt">();
</span>
291 <span class=
"hl kwd">EVAF_ERROR
</span><span class=
"hl opt">(
</span><span class=
"hl str">"Failed to query database : %s
"</span><span class=
"hl opt">,
</span> <span class=
"hl kwd">qPrintable
</span><span class=
"hl opt">(
</span>err
<span class=
"hl opt">.
</span><span class=
"hl kwd">text
</span><span class=
"hl opt">()));
</span>
292 <span class=
"hl kwa">return false
</span><span class=
"hl opt">;
</span>
293 <span class=
"hl opt">}
</span>
295 <span class=
"hl kwa">if
</span> <span class=
"hl opt">(
</span>q
<span class=
"hl opt">.
</span><span class=
"hl kwd">isActive
</span><span class=
"hl opt">()
&&</span> q
<span class=
"hl opt">.
</span><span class=
"hl kwd">isSelect
</span><span class=
"hl opt">()
&&</span> q
<span class=
"hl opt">.
</span><span class=
"hl kwd">first
</span><span class=
"hl opt">())
</span>
296 <span class=
"hl kwa">return true
</span><span class=
"hl opt">;
</span> <span class=
"hl slc">// We already have a table called 'data'
</span>
298 <span class=
"hl slc">// Create the 'data' table
</span>
299 <span class=
"hl kwa">if
</span> <span class=
"hl opt">(!
</span>q
<span class=
"hl opt">.
</span><span class=
"hl kwd">exec
</span><span class=
"hl opt">(
</span><span class=
"hl str">"CREATE TABLE data (name text primary key not null, length integer, flags integer);
"</span><span class=
"hl opt">)) {
</span>
300 QSqlError err
<span class=
"hl opt">=
</span> mDb
<span class=
"hl opt">.
</span><span class=
"hl kwd">lastError
</span><span class=
"hl opt">();
</span>
301 <span class=
"hl kwd">EVAF_ERROR
</span><span class=
"hl opt">(
</span><span class=
"hl str">"Failed to create table
</span> <span class=
"hl esc">\'
</span><span class=
"hl str">data
</span><span class=
"hl esc">\'
</span> <span class=
"hl str">: %s
"</span><span class=
"hl opt">,
</span> <span class=
"hl kwd">qPrintable
</span><span class=
"hl opt">(
</span>err
<span class=
"hl opt">.
</span><span class=
"hl kwd">text
</span><span class=
"hl opt">()));
</span>
302 <span class=
"hl kwa">return false
</span><span class=
"hl opt">;
</span>
303 <span class=
"hl opt">}
</span>
305 <span class=
"hl kwa">return true
</span><span class=
"hl opt">;
</span>
306 <span class=
"hl opt">}
</span></pre>
308 <p>Finally, the
<tt>loadData()
</tt> method loads all the data records from the database to the memory:
</p>
310 <pre class=
"hl"><span class=
"hl kwb">bool
</span> StorageImpl
<span class=
"hl opt">::
</span><span class=
"hl kwd">loadData
</span><span class=
"hl opt">()
</span>
311 <span class=
"hl opt">{
</span>
312 QSqlQuery
<span class=
"hl kwd">q
</span><span class=
"hl opt">(
</span>mDb
<span class=
"hl opt">);
</span>
313 <span class=
"hl kwa">if
</span> <span class=
"hl opt">(!
</span>q
<span class=
"hl opt">.
</span><span class=
"hl kwd">exec
</span><span class=
"hl opt">(
</span><span class=
"hl str">"SELECT name, length, flags FROM data;
"</span><span class=
"hl opt">)) {
</span>
314 QSqlError err
<span class=
"hl opt">=
</span> mDb
<span class=
"hl opt">.
</span><span class=
"hl kwd">lastError
</span><span class=
"hl opt">();
</span>
315 <span class=
"hl kwd">EVAF_ERROR
</span><span class=
"hl opt">(
</span><span class=
"hl str">"Failed to query database : %s
"</span><span class=
"hl opt">,
</span> <span class=
"hl kwd">qPrintable
</span><span class=
"hl opt">(
</span>err
<span class=
"hl opt">.
</span><span class=
"hl kwd">text
</span><span class=
"hl opt">()));
</span>
316 <span class=
"hl kwa">return false
</span><span class=
"hl opt">;
</span>
317 <span class=
"hl opt">}
</span>
319 <span class=
"hl kwa">while
</span> <span class=
"hl opt">(
</span>q
<span class=
"hl opt">.
</span><span class=
"hl kwd">next
</span><span class=
"hl opt">()) {
</span>
320 QString name
<span class=
"hl opt">=
</span> q
<span class=
"hl opt">.
</span><span class=
"hl kwd">value
</span><span class=
"hl opt">(
</span><span class=
"hl num">0</span><span class=
"hl opt">).
</span><span class=
"hl kwd">toString
</span><span class=
"hl opt">();
</span>
321 QExplicitlySharedDataPointer
<span class=
"hl opt"><</span>Storage
<span class=
"hl opt">::
</span>Data
<span class=
"hl opt">></span> <span class=
"hl kwd">data
</span><span class=
"hl opt">(
</span><span class=
"hl kwa">new
</span> Storage
<span class=
"hl opt">::
</span><span class=
"hl kwd">Data
</span><span class=
"hl opt">(
</span>name
<span class=
"hl opt">,
</span> q
<span class=
"hl opt">.
</span><span class=
"hl kwd">value
</span><span class=
"hl opt">(
</span><span class=
"hl num">1</span><span class=
"hl opt">).
</span><span class=
"hl kwd">toInt
</span><span class=
"hl opt">(),
</span> <span class=
"hl kwd">uint
</span><span class=
"hl opt">(
</span>q
<span class=
"hl opt">.
</span><span class=
"hl kwd">value
</span><span class=
"hl opt">(
</span><span class=
"hl num">2</span><span class=
"hl opt">).
</span><span class=
"hl kwd">toInt
</span><span class=
"hl opt">())));
</span>
322 mData
<span class=
"hl opt">.
</span><span class=
"hl kwd">insert
</span><span class=
"hl opt">(
</span>name
<span class=
"hl opt">,
</span> data
<span class=
"hl opt">);
</span>
323 <span class=
"hl opt">}
</span>
325 <span class=
"hl kwd">reset
</span><span class=
"hl opt">();
</span>
327 <span class=
"hl kwa">return true
</span><span class=
"hl opt">;
</span>
328 <span class=
"hl opt">}
</span></pre>
330 <p>Resetting the
<tt>QAbstractItemModel
</tt> data model here is ok, becase before loading any data the model is supposed to be
333 <p>Here is the complete
<tt>module.cpp
</tt> file:
335 <pre class=
"hl"><span class=
"hl com">/**
</span>
336 <span class=
"hl com"> *
@file PswGen/Storage/module.cpp
</span>
337 <span class=
"hl com"> */
</span>
339 <span class=
"hl ppc">#include
</span> <span class=
"hl pps">"module.h
"</span><span class=
"hl ppc"></span>
340 <span class=
"hl ppc">#include
</span> <span class=
"hl pps">"version.h
"</span><span class=
"hl ppc"></span>
342 <span class=
"hl ppc">#include
<Common/Globals
></span>
343 <span class=
"hl ppc">#include
<Common/iLogger
></span>
344 <span class=
"hl ppc">#include
<Common/iRegistry
></span>
345 <span class=
"hl ppc">#include
<Common/iApp
></span>
347 <span class=
"hl ppc">#include
<QtCore
></span>
348 <span class=
"hl ppc">#include
<QtSql/QtSql
></span>
350 <span class=
"hl kwd">VER_EXPORT_VERSION_INFO
</span><span class=
"hl opt">()
</span>
351 <span class=
"hl kwd">Q_EXPORT_PLUGIN2
</span><span class=
"hl opt">(
</span>VER_MODULE_NAME_STR
<span class=
"hl opt">,
</span> eVaf
<span class=
"hl opt">::
</span>PswGen
<span class=
"hl opt">::
</span>Storage
<span class=
"hl opt">::
</span>Module
<span class=
"hl opt">)
</span>
353 <span class=
"hl kwa">using namespace
</span> eVaf
<span class=
"hl opt">;
</span>
354 <span class=
"hl kwa">using namespace
</span> eVaf
<span class=
"hl opt">::
</span>PswGen
<span class=
"hl opt">;
</span>
355 <span class=
"hl kwa">using namespace
</span> eVaf
<span class=
"hl opt">::
</span>PswGen
<span class=
"hl opt">::
</span>Storage
<span class=
"hl opt">;
</span>
357 Module
<span class=
"hl opt">::
</span><span class=
"hl kwd">Module
</span><span class=
"hl opt">()
</span>
358 <span class=
"hl opt">:
</span> Plugins
<span class=
"hl opt">::
</span><span class=
"hl kwd">iPlugin
</span><span class=
"hl opt">()
</span>
359 <span class=
"hl opt">,
</span> <span class=
"hl kwd">mReady
</span><span class=
"hl opt">(
</span><span class=
"hl kwa">false
</span><span class=
"hl opt">)
</span>
360 <span class=
"hl opt">{
</span>
361 <span class=
"hl kwd">setObjectName
</span><span class=
"hl opt">(
</span><span class=
"hl kwd">QString
</span><span class=
"hl opt">(
</span><span class=
"hl str">"%
1.%
2"</span><span class=
"hl opt">).
</span><span class=
"hl kwd">arg
</span><span class=
"hl opt">(
</span>VER_MODULE_NAME_STR
<span class=
"hl opt">).
</span><span class=
"hl kwd">arg
</span><span class=
"hl opt">(
</span>__FUNCTION__
<span class=
"hl opt">));
</span>
363 mStorage
<span class=
"hl opt">=
</span> <span class=
"hl kwa">new
</span> Internal
<span class=
"hl opt">::
</span>StorageImpl
<span class=
"hl opt">;
</span>
365 <span class=
"hl kwd">EVAF_INFO
</span><span class=
"hl opt">(
</span><span class=
"hl str">"%s created
"</span><span class=
"hl opt">,
</span> <span class=
"hl kwd">qPrintable
</span><span class=
"hl opt">(
</span><span class=
"hl kwd">objectName
</span><span class=
"hl opt">()));
</span>
366 <span class=
"hl opt">}
</span>
368 Module
<span class=
"hl opt">::~
</span><span class=
"hl kwd">Module
</span><span class=
"hl opt">()
</span>
369 <span class=
"hl opt">{
</span>
370 <span class=
"hl kwa">delete
</span> mStorage
<span class=
"hl opt">;
</span>
372 <span class=
"hl kwd">EVAF_INFO
</span><span class=
"hl opt">(
</span><span class=
"hl str">"%s destroyed
"</span><span class=
"hl opt">,
</span> <span class=
"hl kwd">qPrintable
</span><span class=
"hl opt">(
</span><span class=
"hl kwd">objectName
</span><span class=
"hl opt">()));
</span>
373 <span class=
"hl opt">}
</span>
375 <span class=
"hl kwb">bool
</span> Module
<span class=
"hl opt">::
</span><span class=
"hl kwd">init
</span><span class=
"hl opt">(
</span>QString
<span class=
"hl kwb">const
</span> <span class=
"hl opt">&</span> args
<span class=
"hl opt">)
</span>
376 <span class=
"hl opt">{
</span>
377 <span class=
"hl kwd">Q_UNUSED
</span><span class=
"hl opt">(
</span>args
<span class=
"hl opt">);
</span>
379 <span class=
"hl kwa">if
</span> <span class=
"hl opt">(!
</span>mStorage
<span class=
"hl opt">-
></span><span class=
"hl kwd">init
</span><span class=
"hl opt">())
</span>
380 <span class=
"hl kwa">return false
</span><span class=
"hl opt">;
</span>
382 mReady
<span class=
"hl opt">=
</span> <span class=
"hl kwa">true
</span><span class=
"hl opt">;
</span>
384 <span class=
"hl kwd">EVAF_INFO
</span><span class=
"hl opt">(
</span><span class=
"hl str">"%s initialized
"</span><span class=
"hl opt">,
</span> <span class=
"hl kwd">qPrintable
</span><span class=
"hl opt">(
</span><span class=
"hl kwd">objectName
</span><span class=
"hl opt">()));
</span>
386 <span class=
"hl kwa">return true
</span><span class=
"hl opt">;
</span>
387 <span class=
"hl opt">}
</span>
389 <span class=
"hl kwb">void
</span> Module
<span class=
"hl opt">::
</span><span class=
"hl kwd">done
</span><span class=
"hl opt">()
</span>
390 <span class=
"hl opt">{
</span>
391 mReady
<span class=
"hl opt">=
</span> <span class=
"hl kwa">false
</span><span class=
"hl opt">;
</span>
393 mStorage
<span class=
"hl opt">-
></span><span class=
"hl kwd">done
</span><span class=
"hl opt">();
</span>
395 <span class=
"hl kwd">EVAF_INFO
</span><span class=
"hl opt">(
</span><span class=
"hl str">"%s finalized
"</span><span class=
"hl opt">,
</span> <span class=
"hl kwd">qPrintable
</span><span class=
"hl opt">(
</span><span class=
"hl kwd">objectName
</span><span class=
"hl opt">()));
</span>
396 <span class=
"hl opt">}
</span>
398 <span class=
"hl kwa">using namespace
</span> eVaf
<span class=
"hl opt">::
</span>PswGen
<span class=
"hl opt">::
</span>Storage
<span class=
"hl opt">::
</span>Internal
<span class=
"hl opt">;
</span>
400 <span class=
"hl kwb">char const
</span> <span class=
"hl opt">*
</span> <span class=
"hl kwb">const
</span> StorageImpl
<span class=
"hl opt">::
</span>DbConnectionName
<span class=
"hl opt">=
</span> <span class=
"hl str">"PswGenDB
"</span><span class=
"hl opt">;
</span>
402 <span class=
"hl kwb">char const
</span> <span class=
"hl opt">*
</span> <span class=
"hl kwb">const
</span> StorageImpl
<span class=
"hl opt">::
</span>DbName
<span class=
"hl opt">=
</span> <span class=
"hl str">"PswGen.sqlite
"</span><span class=
"hl opt">;
</span>
404 StorageImpl
<span class=
"hl opt">::
</span><span class=
"hl kwd">StorageImpl
</span><span class=
"hl opt">()
</span>
405 <span class=
"hl opt">:
</span> <span class=
"hl kwd">QAbstractListModel
</span><span class=
"hl opt">()
</span>
406 <span class=
"hl opt">{
</span>
407 <span class=
"hl kwd">setObjectName
</span><span class=
"hl opt">(
</span><span class=
"hl kwd">QString
</span><span class=
"hl opt">(
</span><span class=
"hl str">"%
1.iGenerator
"</span><span class=
"hl opt">).
</span><span class=
"hl kwd">arg
</span><span class=
"hl opt">(
</span>VER_MODULE_NAME_STR
<span class=
"hl opt">));
</span>
409 <span class=
"hl kwd">EVAF_INFO
</span><span class=
"hl opt">(
</span><span class=
"hl str">"%s created
"</span><span class=
"hl opt">,
</span> <span class=
"hl kwd">qPrintable
</span><span class=
"hl opt">(
</span><span class=
"hl kwd">objectName
</span><span class=
"hl opt">()));
</span>
410 <span class=
"hl opt">}
</span>
412 StorageImpl
<span class=
"hl opt">::~
</span><span class=
"hl kwd">StorageImpl
</span><span class=
"hl opt">()
</span>
413 <span class=
"hl opt">{
</span>
414 <span class=
"hl kwd">EVAF_INFO
</span><span class=
"hl opt">(
</span><span class=
"hl str">"%s destroyed
"</span><span class=
"hl opt">,
</span> <span class=
"hl kwd">qPrintable
</span><span class=
"hl opt">(
</span><span class=
"hl kwd">objectName
</span><span class=
"hl opt">()));
</span>
415 <span class=
"hl opt">}
</span>
417 <span class=
"hl kwb">bool
</span> StorageImpl
<span class=
"hl opt">::
</span><span class=
"hl kwd">init
</span><span class=
"hl opt">()
</span>
418 <span class=
"hl opt">{
</span>
419 <span class=
"hl slc">// Open the database
</span>
420 <span class=
"hl kwa">if
</span> <span class=
"hl opt">(!
</span>QSqlDatabase
<span class=
"hl opt">::
</span><span class=
"hl kwd">contains
</span><span class=
"hl opt">(
</span>DbConnectionName
<span class=
"hl opt">)) {
</span>
421 <span class=
"hl slc">// No database connection yet
</span>
422 mDb
<span class=
"hl opt">=
</span> QSqlDatabase
<span class=
"hl opt">::
</span><span class=
"hl kwd">addDatabase
</span><span class=
"hl opt">(
</span><span class=
"hl str">"QSQLITE
"</span><span class=
"hl opt">,
</span> DbConnectionName
<span class=
"hl opt">);
</span>
423 mDb
<span class=
"hl opt">.
</span><span class=
"hl kwd">setDatabaseName
</span><span class=
"hl opt">(
</span>Common
<span class=
"hl opt">::
</span>iApp
<span class=
"hl opt">::
</span><span class=
"hl kwd">instance
</span><span class=
"hl opt">()-
></span><span class=
"hl kwd">dataRootDir
</span><span class=
"hl opt">() +
</span> DbName
<span class=
"hl opt">);
</span>
424 <span class=
"hl kwa">if
</span> <span class=
"hl opt">(!
</span>mDb
<span class=
"hl opt">.
</span><span class=
"hl kwd">open
</span><span class=
"hl opt">()) {
</span>
425 QSqlError err
<span class=
"hl opt">=
</span> mDb
<span class=
"hl opt">.
</span><span class=
"hl kwd">lastError
</span><span class=
"hl opt">();
</span>
426 <span class=
"hl kwd">EVAF_ERROR
</span><span class=
"hl opt">(
</span><span class=
"hl str">"Failed to open database : %s
"</span><span class=
"hl opt">,
</span> <span class=
"hl kwd">qPrintable
</span><span class=
"hl opt">(
</span>err
<span class=
"hl opt">.
</span><span class=
"hl kwd">text
</span><span class=
"hl opt">()));
</span>
427 <span class=
"hl kwa">return false
</span><span class=
"hl opt">;
</span>
428 <span class=
"hl opt">}
</span>
429 <span class=
"hl opt">}
</span>
430 <span class=
"hl kwa">else
</span> <span class=
"hl opt">{
</span>
431 <span class=
"hl slc">// Database connection already exists
</span>
432 mDb
<span class=
"hl opt">=
</span> QSqlDatabase
<span class=
"hl opt">::
</span><span class=
"hl kwd">database
</span><span class=
"hl opt">(
</span>DbConnectionName
<span class=
"hl opt">);
</span>
433 <span class=
"hl opt">}
</span>
435 <span class=
"hl slc">// Create tables if necessary
</span>
436 <span class=
"hl kwa">if
</span> <span class=
"hl opt">(!
</span><span class=
"hl kwd">createTables
</span><span class=
"hl opt">())
</span>
437 <span class=
"hl kwa">return false
</span><span class=
"hl opt">;
</span>
439 <span class=
"hl slc">// Load data
</span>
440 <span class=
"hl kwa">if
</span> <span class=
"hl opt">(!
</span><span class=
"hl kwd">loadData
</span><span class=
"hl opt">())
</span>
441 <span class=
"hl kwa">return false
</span><span class=
"hl opt">;
</span>
443 <span class=
"hl slc">/// Register our interface
</span>
444 Common
<span class=
"hl opt">::
</span>iRegistry
<span class=
"hl opt">::
</span><span class=
"hl kwd">instance
</span><span class=
"hl opt">()-
></span><span class=
"hl kwd">registerInterface
</span><span class=
"hl opt">(
</span><span class=
"hl str">"iStorage
"</span><span class=
"hl opt">,
</span> <span class=
"hl kwa">this
</span><span class=
"hl opt">);
</span>
446 <span class=
"hl kwd">EVAF_INFO
</span><span class=
"hl opt">(
</span><span class=
"hl str">"%s initialized
"</span><span class=
"hl opt">,
</span> <span class=
"hl kwd">qPrintable
</span><span class=
"hl opt">(
</span><span class=
"hl kwd">objectName
</span><span class=
"hl opt">()));
</span>
448 <span class=
"hl kwa">return true
</span><span class=
"hl opt">;
</span>
449 <span class=
"hl opt">}
</span>
451 <span class=
"hl kwb">void
</span> StorageImpl
<span class=
"hl opt">::
</span><span class=
"hl kwd">done
</span><span class=
"hl opt">()
</span>
452 <span class=
"hl opt">{
</span>
453 mData
<span class=
"hl opt">.
</span><span class=
"hl kwd">clear
</span><span class=
"hl opt">();
</span>
454 <span class=
"hl kwd">EVAF_INFO
</span><span class=
"hl opt">(
</span><span class=
"hl str">"%s finalized
"</span><span class=
"hl opt">,
</span> <span class=
"hl kwd">qPrintable
</span><span class=
"hl opt">(
</span><span class=
"hl kwd">objectName
</span><span class=
"hl opt">()));
</span>
455 <span class=
"hl opt">}
</span>
457 <span class=
"hl kwb">bool
</span> StorageImpl
<span class=
"hl opt">::
</span><span class=
"hl kwd">save
</span><span class=
"hl opt">(
</span>QString
<span class=
"hl kwb">const
</span> <span class=
"hl opt">&</span> name
<span class=
"hl opt">,
</span> QExplicitlySharedDataPointer
<span class=
"hl opt"><</span>Storage
<span class=
"hl opt">::
</span>Data
<span class=
"hl opt">></span> data
<span class=
"hl opt">)
</span>
458 <span class=
"hl opt">{
</span>
459 <span class=
"hl kwd">EVAF_TEST_X
</span><span class=
"hl opt">(
</span>data
<span class=
"hl opt">,
</span> <span class=
"hl str">"Data cannot be null
"</span><span class=
"hl opt">);
</span>
460 <span class=
"hl kwd">EVAF_TEST_X
</span><span class=
"hl opt">(!
</span>name
<span class=
"hl opt">.
</span><span class=
"hl kwd">isEmpty
</span><span class=
"hl opt">(),
</span> <span class=
"hl str">"Name cannot be empty
"</span><span class=
"hl opt">);
</span>
462 <span class=
"hl slc">// Is it an update or a new data record?
</span>
463 <span class=
"hl kwa">if
</span> <span class=
"hl opt">(
</span>mData
<span class=
"hl opt">.
</span><span class=
"hl kwd">constFind
</span><span class=
"hl opt">(
</span>name
<span class=
"hl opt">) !=
</span> mData
<span class=
"hl opt">.
</span><span class=
"hl kwd">constEnd
</span><span class=
"hl opt">()) {
</span>
464 <span class=
"hl slc">// This is an update
</span>
465 <span class=
"hl kwa">if
</span> <span class=
"hl opt">(
</span>data
<span class=
"hl opt">-
></span><span class=
"hl kwd">modified
</span><span class=
"hl opt">()) {
</span>
466 QSqlQuery
<span class=
"hl kwd">q
</span><span class=
"hl opt">(
</span>mDb
<span class=
"hl opt">);
</span>
467 <span class=
"hl kwa">if
</span> <span class=
"hl opt">(!
</span>q
<span class=
"hl opt">.
</span><span class=
"hl kwd">exec
</span><span class=
"hl opt">(
</span><span class=
"hl kwd">QString
</span><span class=
"hl opt">(
</span><span class=
"hl str">"UPDATE data SET length =
</span> <span class=
"hl esc">\'
</span><span class=
"hl str">%
1</span><span class=
"hl esc">\'
</span><span class=
"hl str">, flags =
</span> <span class=
"hl esc">\'
</span><span class=
"hl str">%
2</span><span class=
"hl esc">\'
</span> <span class=
"hl str">WHERE name =
</span> <span class=
"hl esc">\'
</span><span class=
"hl str">%
3</span><span class=
"hl esc">\'
</span><span class=
"hl str">;
"</span><span class=
"hl opt">)
</span>
468 <span class=
"hl opt">.
</span><span class=
"hl kwd">arg
</span><span class=
"hl opt">(
</span>data
<span class=
"hl opt">-
></span><span class=
"hl kwd">length
</span><span class=
"hl opt">()).
</span><span class=
"hl kwd">arg
</span><span class=
"hl opt">(
</span>data
<span class=
"hl opt">-
></span><span class=
"hl kwd">flags
</span><span class=
"hl opt">()).
</span><span class=
"hl kwd">arg
</span><span class=
"hl opt">(
</span>name
<span class=
"hl opt">))) {
</span>
469 QSqlError err
<span class=
"hl opt">=
</span> mDb
<span class=
"hl opt">.
</span><span class=
"hl kwd">lastError
</span><span class=
"hl opt">();
</span>
470 <span class=
"hl kwd">EVAF_ERROR
</span><span class=
"hl opt">(
</span><span class=
"hl str">"Failed to update
</span> <span class=
"hl esc">\'
</span><span class=
"hl str">%s
</span><span class=
"hl esc">\'
</span> <span class=
"hl str">: %s
"</span><span class=
"hl opt">,
</span> <span class=
"hl kwd">qPrintable
</span><span class=
"hl opt">(
</span>name
<span class=
"hl opt">),
</span> <span class=
"hl kwd">qPrintable
</span><span class=
"hl opt">(
</span>err
<span class=
"hl opt">.
</span><span class=
"hl kwd">text
</span><span class=
"hl opt">()));
</span>
471 <span class=
"hl kwa">return false
</span><span class=
"hl opt">;
</span>
472 <span class=
"hl opt">}
</span>
473 <span class=
"hl opt">}
</span>
474 <span class=
"hl opt">}
</span>
475 <span class=
"hl kwa">else
</span> <span class=
"hl opt">{
</span>
476 <span class=
"hl slc">// Store to the database
</span>
477 QSqlQuery
<span class=
"hl kwd">q
</span><span class=
"hl opt">(
</span>mDb
<span class=
"hl opt">);
</span>
478 <span class=
"hl kwa">if
</span> <span class=
"hl opt">(!
</span>q
<span class=
"hl opt">.
</span><span class=
"hl kwd">exec
</span><span class=
"hl opt">(
</span><span class=
"hl kwd">QString
</span><span class=
"hl opt">(
</span><span class=
"hl str">"INSERT INTO data (name, length, flags) VALUES (
</span><span class=
"hl esc">\'
</span><span class=
"hl str">%
1</span><span class=
"hl esc">\'
</span><span class=
"hl str">, %
2, %
3);
"</span><span class=
"hl opt">)
</span>
479 <span class=
"hl opt">.
</span><span class=
"hl kwd">arg
</span><span class=
"hl opt">(
</span>name
<span class=
"hl opt">).
</span><span class=
"hl kwd">arg
</span><span class=
"hl opt">(
</span>data
<span class=
"hl opt">-
></span><span class=
"hl kwd">length
</span><span class=
"hl opt">())
</span>
480 <span class=
"hl opt">.
</span><span class=
"hl kwd">arg
</span><span class=
"hl opt">(
</span><span class=
"hl kwb">int
</span><span class=
"hl opt">(
</span>data
<span class=
"hl opt">-
></span><span class=
"hl kwd">flags
</span><span class=
"hl opt">())))) {
</span>
481 QSqlError err
<span class=
"hl opt">=
</span> mDb
<span class=
"hl opt">.
</span><span class=
"hl kwd">lastError
</span><span class=
"hl opt">();
</span>
482 <span class=
"hl kwd">EVAF_ERROR
</span><span class=
"hl opt">(
</span><span class=
"hl str">"Failed to insert
</span> <span class=
"hl esc">\'
</span><span class=
"hl str">%s
</span><span class=
"hl esc">\'
</span> <span class=
"hl str">: %s
"</span><span class=
"hl opt">,
</span> <span class=
"hl kwd">qPrintable
</span><span class=
"hl opt">(
</span>name
<span class=
"hl opt">),
</span> <span class=
"hl kwd">qPrintable
</span><span class=
"hl opt">(
</span>err
<span class=
"hl opt">.
</span><span class=
"hl kwd">text
</span><span class=
"hl opt">()));
</span>
483 <span class=
"hl kwa">return false
</span><span class=
"hl opt">;
</span>
484 <span class=
"hl opt">}
</span>
486 <span class=
"hl slc">// Store also into the local hash
</span>
487 mData
<span class=
"hl opt">.
</span><span class=
"hl kwd">insert
</span><span class=
"hl opt">(
</span>name
<span class=
"hl opt">,
</span> data
<span class=
"hl opt">);
</span>
489 <span class=
"hl slc">// Reset the model
</span>
490 <span class=
"hl kwd">reset
</span><span class=
"hl opt">();
</span>
491 <span class=
"hl opt">}
</span>
493 data
<span class=
"hl opt">-
></span><span class=
"hl kwd">reset
</span><span class=
"hl opt">();
</span>
495 <span class=
"hl kwa">return true
</span><span class=
"hl opt">;
</span>
496 <span class=
"hl opt">}
</span>
498 QExplicitlySharedDataPointer
<span class=
"hl opt"><</span>Storage
<span class=
"hl opt">::
</span>Data
<span class=
"hl opt">></span> StorageImpl
<span class=
"hl opt">::
</span><span class=
"hl kwd">query
</span><span class=
"hl opt">(
</span>QString
<span class=
"hl kwb">const
</span> <span class=
"hl opt">&</span> name
<span class=
"hl opt">)
</span> <span class=
"hl kwb">const
</span>
499 <span class=
"hl opt">{
</span>
500 QMap
<span class=
"hl opt"><</span>QString
<span class=
"hl opt">,
</span> QExplicitlySharedDataPointer
<span class=
"hl opt"><</span>Storage
<span class=
"hl opt">::
</span>Data
<span class=
"hl opt">> >::
</span>const_iterator it
<span class=
"hl opt">=
</span> mData
<span class=
"hl opt">.
</span><span class=
"hl kwd">constFind
</span><span class=
"hl opt">(
</span>name
<span class=
"hl opt">);
</span>
501 <span class=
"hl kwa">if
</span> <span class=
"hl opt">(
</span>it
<span class=
"hl opt">!=
</span> mData
<span class=
"hl opt">.
</span><span class=
"hl kwd">constEnd
</span><span class=
"hl opt">())
</span>
502 <span class=
"hl kwa">return
</span> it
<span class=
"hl opt">.
</span><span class=
"hl kwd">value
</span><span class=
"hl opt">();
</span>
503 <span class=
"hl kwa">else
</span>
504 <span class=
"hl kwa">return
</span> QExplicitlySharedDataPointer
<span class=
"hl opt"><</span>Storage
<span class=
"hl opt">::
</span>Data
<span class=
"hl opt">>();
</span>
505 <span class=
"hl opt">}
</span>
507 QVariant StorageImpl
<span class=
"hl opt">::
</span><span class=
"hl kwd">data
</span><span class=
"hl opt">(
</span>QModelIndex
<span class=
"hl kwb">const
</span> <span class=
"hl opt">&</span> index
<span class=
"hl opt">,
</span> <span class=
"hl kwb">int
</span> role
<span class=
"hl opt">)
</span> <span class=
"hl kwb">const
</span>
508 <span class=
"hl opt">{
</span>
509 <span class=
"hl kwa">if
</span> <span class=
"hl opt">(!
</span>index
<span class=
"hl opt">.
</span><span class=
"hl kwd">isValid
</span><span class=
"hl opt">() ||
</span> index
<span class=
"hl opt">.
</span><span class=
"hl kwd">row
</span><span class=
"hl opt">()
<</span> <span class=
"hl num">0</span> <span class=
"hl opt">||
</span> index
<span class=
"hl opt">.
</span><span class=
"hl kwd">row
</span><span class=
"hl opt">()
>=
</span> mData
<span class=
"hl opt">.
</span><span class=
"hl kwd">size
</span><span class=
"hl opt">() ||
</span> index
<span class=
"hl opt">.
</span><span class=
"hl kwd">column
</span><span class=
"hl opt">() !=
</span> <span class=
"hl num">0</span><span class=
"hl opt">)
</span>
510 <span class=
"hl kwa">return
</span> <span class=
"hl kwd">QVariant
</span><span class=
"hl opt">();
</span>
512 <span class=
"hl kwa">if
</span> <span class=
"hl opt">(
</span>role
<span class=
"hl opt">==
</span> Qt
<span class=
"hl opt">::
</span>EditRole
<span class=
"hl opt">||
</span> role
<span class=
"hl opt">==
</span> Qt
<span class=
"hl opt">::
</span>DisplayRole
<span class=
"hl opt">)
</span>
513 <span class=
"hl kwa">return
</span> mData
<span class=
"hl opt">.
</span><span class=
"hl kwd">keys
</span><span class=
"hl opt">().
</span><span class=
"hl kwd">at
</span><span class=
"hl opt">(
</span>index
<span class=
"hl opt">.
</span><span class=
"hl kwd">row
</span><span class=
"hl opt">());
</span>
515 <span class=
"hl kwa">return
</span> <span class=
"hl kwd">QVariant
</span><span class=
"hl opt">();
</span>
516 <span class=
"hl opt">}
</span>
518 <span class=
"hl kwb">bool
</span> StorageImpl
<span class=
"hl opt">::
</span><span class=
"hl kwd">createTables
</span><span class=
"hl opt">()
</span>
519 <span class=
"hl opt">{
</span>
520 QSqlQuery
<span class=
"hl kwd">q
</span><span class=
"hl opt">(
</span>mDb
<span class=
"hl opt">);
</span>
521 <span class=
"hl kwa">if
</span> <span class=
"hl opt">(!
</span>q
<span class=
"hl opt">.
</span><span class=
"hl kwd">exec
</span><span class=
"hl opt">(
</span><span class=
"hl str">"SELECT name FROM sqlite_master WHERE type=
</span><span class=
"hl esc">\'
</span><span class=
"hl str">table
</span><span class=
"hl esc">\'
</span> <span class=
"hl str">AND name=
</span><span class=
"hl esc">\'
</span><span class=
"hl str">data
</span><span class=
"hl esc">\'
</span><span class=
"hl str">;
"</span><span class=
"hl opt">)) {
</span>
522 QSqlError err
<span class=
"hl opt">=
</span> mDb
<span class=
"hl opt">.
</span><span class=
"hl kwd">lastError
</span><span class=
"hl opt">();
</span>
523 <span class=
"hl kwd">EVAF_ERROR
</span><span class=
"hl opt">(
</span><span class=
"hl str">"Failed to query database : %s
"</span><span class=
"hl opt">,
</span> <span class=
"hl kwd">qPrintable
</span><span class=
"hl opt">(
</span>err
<span class=
"hl opt">.
</span><span class=
"hl kwd">text
</span><span class=
"hl opt">()));
</span>
524 <span class=
"hl kwa">return false
</span><span class=
"hl opt">;
</span>
525 <span class=
"hl opt">}
</span>
527 <span class=
"hl kwa">if
</span> <span class=
"hl opt">(
</span>q
<span class=
"hl opt">.
</span><span class=
"hl kwd">isActive
</span><span class=
"hl opt">()
&&</span> q
<span class=
"hl opt">.
</span><span class=
"hl kwd">isSelect
</span><span class=
"hl opt">()
&&</span> q
<span class=
"hl opt">.
</span><span class=
"hl kwd">first
</span><span class=
"hl opt">())
</span>
528 <span class=
"hl kwa">return true
</span><span class=
"hl opt">;
</span> <span class=
"hl slc">// We already have a table called 'data'
</span>
530 <span class=
"hl slc">// Create the 'data' table
</span>
531 <span class=
"hl kwa">if
</span> <span class=
"hl opt">(!
</span>q
<span class=
"hl opt">.
</span><span class=
"hl kwd">exec
</span><span class=
"hl opt">(
</span><span class=
"hl str">"CREATE TABLE data (name text primary key not null, length integer, flags integer);
"</span><span class=
"hl opt">)) {
</span>
532 QSqlError err
<span class=
"hl opt">=
</span> mDb
<span class=
"hl opt">.
</span><span class=
"hl kwd">lastError
</span><span class=
"hl opt">();
</span>
533 <span class=
"hl kwd">EVAF_ERROR
</span><span class=
"hl opt">(
</span><span class=
"hl str">"Failed to create table
</span> <span class=
"hl esc">\'
</span><span class=
"hl str">data
</span><span class=
"hl esc">\'
</span> <span class=
"hl str">: %s
"</span><span class=
"hl opt">,
</span> <span class=
"hl kwd">qPrintable
</span><span class=
"hl opt">(
</span>err
<span class=
"hl opt">.
</span><span class=
"hl kwd">text
</span><span class=
"hl opt">()));
</span>
534 <span class=
"hl kwa">return false
</span><span class=
"hl opt">;
</span>
535 <span class=
"hl opt">}
</span>
537 <span class=
"hl kwa">return true
</span><span class=
"hl opt">;
</span>
538 <span class=
"hl opt">}
</span>
540 <span class=
"hl kwb">bool
</span> StorageImpl
<span class=
"hl opt">::
</span><span class=
"hl kwd">loadData
</span><span class=
"hl opt">()
</span>
541 <span class=
"hl opt">{
</span>
542 QSqlQuery
<span class=
"hl kwd">q
</span><span class=
"hl opt">(
</span>mDb
<span class=
"hl opt">);
</span>
543 <span class=
"hl kwa">if
</span> <span class=
"hl opt">(!
</span>q
<span class=
"hl opt">.
</span><span class=
"hl kwd">exec
</span><span class=
"hl opt">(
</span><span class=
"hl str">"SELECT name, length, flags FROM data;
"</span><span class=
"hl opt">)) {
</span>
544 QSqlError err
<span class=
"hl opt">=
</span> mDb
<span class=
"hl opt">.
</span><span class=
"hl kwd">lastError
</span><span class=
"hl opt">();
</span>
545 <span class=
"hl kwd">EVAF_ERROR
</span><span class=
"hl opt">(
</span><span class=
"hl str">"Failed to query database : %s
"</span><span class=
"hl opt">,
</span> <span class=
"hl kwd">qPrintable
</span><span class=
"hl opt">(
</span>err
<span class=
"hl opt">.
</span><span class=
"hl kwd">text
</span><span class=
"hl opt">()));
</span>
546 <span class=
"hl kwa">return false
</span><span class=
"hl opt">;
</span>
547 <span class=
"hl opt">}
</span>
549 <span class=
"hl kwa">while
</span> <span class=
"hl opt">(
</span>q
<span class=
"hl opt">.
</span><span class=
"hl kwd">next
</span><span class=
"hl opt">()) {
</span>
550 QString name
<span class=
"hl opt">=
</span> q
<span class=
"hl opt">.
</span><span class=
"hl kwd">value
</span><span class=
"hl opt">(
</span><span class=
"hl num">0</span><span class=
"hl opt">).
</span><span class=
"hl kwd">toString
</span><span class=
"hl opt">();
</span>
551 QExplicitlySharedDataPointer
<span class=
"hl opt"><</span>Storage
<span class=
"hl opt">::
</span>Data
<span class=
"hl opt">></span> <span class=
"hl kwd">data
</span><span class=
"hl opt">(
</span><span class=
"hl kwa">new
</span> Storage
<span class=
"hl opt">::
</span><span class=
"hl kwd">Data
</span><span class=
"hl opt">(
</span>name
<span class=
"hl opt">,
</span> q
<span class=
"hl opt">.
</span><span class=
"hl kwd">value
</span><span class=
"hl opt">(
</span><span class=
"hl num">1</span><span class=
"hl opt">).
</span><span class=
"hl kwd">toInt
</span><span class=
"hl opt">(),
</span> <span class=
"hl kwd">uint
</span><span class=
"hl opt">(
</span>q
<span class=
"hl opt">.
</span><span class=
"hl kwd">value
</span><span class=
"hl opt">(
</span><span class=
"hl num">2</span><span class=
"hl opt">).
</span><span class=
"hl kwd">toInt
</span><span class=
"hl opt">())));
</span>
552 mData
<span class=
"hl opt">.
</span><span class=
"hl kwd">insert
</span><span class=
"hl opt">(
</span>name
<span class=
"hl opt">,
</span> data
<span class=
"hl opt">);
</span>
553 <span class=
"hl opt">}
</span>
555 <span class=
"hl kwd">reset
</span><span class=
"hl opt">();
</span>
557 <span class=
"hl kwa">return true
</span><span class=
"hl opt">;
</span>
558 <span class=
"hl opt">}
</span></pre>
560 <p>Next --
<a href=
"pswgen08.html">Building Storage Module
</a>.
</p>