2
* database.cpp is part of Brewtarget, and is Copyright Philip G. Lee
3
* (rocketman768@gmail.com), 2009.
5
* Brewtarget is free software: you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation, either version 3 of the License, or
8
* (at your option) any later version.
10
* Brewtarget is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program. If not, see <http://www.gnu.org/licenses/>.
24
#include <QDomDocument>
26
#include <QDomNodeList>
28
#include <QTextStream>
30
#include "equipment.h"
31
#include "fermentable.h"
44
#include "brewtarget.h"
46
// Grrr... stupid C++. Have to define these outside the class AGAIN.
47
std::list<Equipment*> Database::equipments;
48
std::list<Fermentable*> Database::fermentables;
49
std::list<Hop*> Database::hops;
50
std::list<Mash*> Database::mashs;
51
std::list<MashStep*> Database::mashSteps;
52
std::list<Misc*> Database::miscs;
53
std::list<Recipe*> Database::recipes;
54
std::list<Style*> Database::styles;
55
std::list<Water*> Database::waters;
56
std::list<Yeast*> Database::yeasts;
57
bool Database::initialized = false;
58
Database* Database::internalDBInstance = 0;
59
QFile Database::dbFile;
60
QString Database::dbFileName;
61
QFile Database::recipeFile;
62
QString Database::recipeFileName;
63
QFile Database::mashFile;
64
QString Database::mashFileName;
68
// Don't EVER use this method to get the database!!!
71
Database* Database::getDatabase()
74
return internalDBInstance;
79
bool Database::isInitialized()
84
void Database::initialize()
86
QDomDocument dbDoc, recDoc, mashDoc;
93
dbFileName = (Brewtarget::getDataDir() + "database.xml");
94
recipeFileName = (Brewtarget::getDataDir() + "recipes.xml");
95
mashFileName = (Brewtarget::getDataDir() + "mashs.xml");
97
dbFile.setFileName(dbFileName);
98
recipeFile.setFileName(recipeFileName);
99
mashFile.setFileName(mashFileName);
101
// Try to open the files.
102
if( ! dbFile.open(QIODevice::ReadOnly) )
104
Brewtarget::log(Brewtarget::ERROR, "Could not open " + dbFile.fileName().toStdString() + " for reading.");
107
if( ! recipeFile.open(QIODevice::ReadOnly) )
109
Brewtarget::log(Brewtarget::ERROR, "Could not open " + recipeFile.fileName().toStdString() + " for reading.");
112
if( ! mashFile.open(QIODevice::ReadOnly) )
114
Brewtarget::log(Brewtarget::ERROR, "Could not open " + recipeFile.fileName().toStdString() + " for reading.");
118
// Parse the xml documents.
119
if( ! dbDoc.setContent(&dbFile, false, &err, &line, &col) )
120
Brewtarget::log(Brewtarget::WARNING, QString("Bad document formatting in %1 %2:%3. %4").arg(dbFile.fileName()).arg(line).arg(col).arg(err) );
121
if( ! recDoc.setContent(&recipeFile, false, &err, &line, &col) )
122
Brewtarget::log(Brewtarget::WARNING, QString("Bad document formatting in %1 %2:%3. %4").arg(recipeFile.fileName()).arg(line).arg(col).arg(err) );
123
if( ! mashDoc.setContent(&mashFile, false, &err, &line, &col) )
124
Brewtarget::log(Brewtarget::WARNING, QString("Bad document formatting in %1 %2:%3. %4").arg(mashFile.fileName()).arg(line).arg(col).arg(err) );
126
/*** Items in dbDoc ***/
127
list = dbDoc.elementsByTagName("EQUIPMENT");
129
for( i = 0; i < size; ++i )
130
equipments.push_back(new Equipment( list.at(i) ));
131
list = dbDoc.elementsByTagName("FERMENTABLE");
133
for( i = 0; i < size; ++i )
134
fermentables.push_back( new Fermentable( list.at(i) ) );
135
list = dbDoc.elementsByTagName("HOP");
137
for( i = 0; i < size; ++i )
138
hops.push_back(new Hop( list.at(i) ));
139
list = dbDoc.elementsByTagName("MASH_STEP");
141
for( i = 0; i < size; ++i )
142
mashSteps.push_back(new MashStep( list.at(i) ));
143
list = dbDoc.elementsByTagName("MISC");
145
for( i = 0; i < size; ++i )
146
miscs.push_back(new Misc( list.at(i) ));
147
list = dbDoc.elementsByTagName("STYLE");
149
for( i = 0; i < size; ++i )
150
styles.push_back(new Style(list.at(i)));
151
list = dbDoc.elementsByTagName("WATER");
153
for( i = 0; i < size; ++i )
154
waters.push_back(new Water(list.at(i)));
155
list = dbDoc.elementsByTagName("YEAST");
157
for( i = 0; i < size; ++i )
158
yeasts.push_back(new Yeast(list.at(i)));
160
/*** Items in mashDoc ***/
161
list = mashDoc.elementsByTagName("MASH");
163
for( i = 0; i < size; ++i )
164
mashs.push_back(new Mash(list.at(i)));
166
/*** Items in recDoc ***/
167
list = recDoc.elementsByTagName("RECIPE");
169
for( i = 0; i < size; ++i )
170
recipes.push_back(new Recipe(list.at(i)));
172
// Sort everything by name.
173
equipments.sort(Equipment_ptr_cmp());
174
fermentables.sort(Fermentable_ptr_cmp());
175
hops.sort(Hop_ptr_cmp());
176
mashs.sort(Mash_ptr_cmp());
177
mashSteps.sort(MashStep_ptr_cmp());
178
miscs.sort(Misc_ptr_cmp());
179
recipes.sort(Recipe_ptr_cmp());
180
styles.sort(Style_ptr_cmp());
181
waters.sort(Water_ptr_cmp());
182
yeasts.sort(Yeast_ptr_cmp());
188
internalDBInstance = new Database();
189
Database::initialized = true;
192
dbFile.open(dbFileName.toStdString().c_str());
193
recipeFile.open(recipeFileName.toStdString().c_str()); // Why are these separate from the dbFile? To prevent duplicates.
194
mashFile.open(mashFileName.toStdString().c_str()); // Why are these separate from the dbFile? To prevent duplicates.
196
unsigned int i, size;
197
std::vector<XmlNode*> nodes;
198
XmlTree* tree = new XmlTree(dbFile);
200
size = tree->getNodesWithTag(nodes, "EQUIPMENT");
201
for( i = 0; i < size; ++i )
202
equipments.push_back(new Equipment(nodes[i]));
203
size = tree->getNodesWithTag(nodes, "FERMENTABLE");
204
for( i = 0; i < size; ++i )
205
fermentables.push_back(new Fermentable(nodes[i]));
206
size = tree->getNodesWithTag(nodes, "HOP");
207
for( i = 0; i < size; ++i )
208
hops.push_back(new Hop(nodes[i]));
209
size = tree->getNodesWithTag(nodes, "MASH_STEP");
210
for( i = 0; i < size; ++i )
211
mashSteps.push_back(new MashStep(nodes[i]));
212
size = tree->getNodesWithTag(nodes, "MISC");
213
for( i = 0; i < size; ++i )
214
miscs.push_back(new Misc(nodes[i]));
215
size = tree->getNodesWithTag(nodes, "STYLE");
216
for( i = 0; i < size; ++i )
217
styles.push_back(new Style(nodes[i]));
218
size = tree->getNodesWithTag(nodes, "WATER");
219
for( i = 0; i < size; ++i )
220
waters.push_back(new Water(nodes[i]));
221
size = tree->getNodesWithTag(nodes, "YEAST");
222
for( i = 0; i < size; ++i )
223
yeasts.push_back(new Yeast(nodes[i]));
227
tree = new XmlTree(mashFile);
229
size = tree->getNodesWithTag(nodes, "MASH");
230
for( i = 0; i < size; ++i )
231
mashs.push_back(new Mash(nodes[i]));
235
tree = new XmlTree(recipeFile);
237
size = tree->getNodesWithTag(nodes, "RECIPE");
238
for( i = 0; i < size; ++i )
239
recipes.push_back(new Recipe(nodes[i]));
246
// Sort everything by name.
247
equipments.sort(Equipment_ptr_cmp());
248
fermentables.sort(Fermentable_ptr_cmp());
249
hops.sort(Hop_ptr_cmp());
250
mashs.sort(Mash_ptr_cmp());
251
mashSteps.sort(MashStep_ptr_cmp());
252
miscs.sort(Misc_ptr_cmp());
253
recipes.sort(Recipe_ptr_cmp());
254
styles.sort(Style_ptr_cmp());
255
waters.sort(Water_ptr_cmp());
256
yeasts.sort(Yeast_ptr_cmp());
261
void Database::resortAll()
263
// Sort everything by name.
264
equipments.sort(Equipment_ptr_cmp());
265
fermentables.sort(Fermentable_ptr_cmp());
266
hops.sort(Hop_ptr_cmp());
267
mashs.sort(Mash_ptr_cmp());
268
mashSteps.sort(MashStep_ptr_cmp());
269
miscs.sort(Misc_ptr_cmp());
270
recipes.sort(Recipe_ptr_cmp());
271
styles.sort(Style_ptr_cmp());
272
waters.sort(Water_ptr_cmp());
273
yeasts.sort(Yeast_ptr_cmp());
275
hasChanged(QVariant(DBALL));
278
void Database::resortEquipments()
280
equipments.sort(Equipment_ptr_cmp());
281
hasChanged(QVariant(DBEQUIP));
284
void Database::resortFermentables()
286
fermentables.sort(Fermentable_ptr_cmp());
287
hasChanged(QVariant(DBFERM));
290
void Database::resortHops()
292
hops.sort(Hop_ptr_cmp());
293
hasChanged(QVariant(DBHOP));
296
void Database::resortMiscs()
298
miscs.sort(Misc_ptr_cmp());
299
hasChanged(QVariant(DBMISC));
302
void Database::resortStyles()
304
styles.sort(Style_ptr_cmp());
305
hasChanged(QVariant(DBSTYLE));
308
void Database::resortYeasts()
310
yeasts.sort(Yeast_ptr_cmp());
311
hasChanged(QVariant(DBYEAST));
314
void Database::savePersistent()
316
QDomDocument dbDoc, recDoc, mashDoc;
317
QDomElement dbRoot, recRoot, mashRoot;
319
if( ! dbFile.open( QIODevice::Truncate | QIODevice::WriteOnly ) )
321
Brewtarget::log(Brewtarget::ERROR, "Could not open " + dbFile.fileName().toStdString() + " for writing.");
324
if( ! recipeFile.open( QIODevice::Truncate | QIODevice::WriteOnly ) )
326
Brewtarget::log(Brewtarget::ERROR, "Could not open " + recipeFile.fileName().toStdString() + " for writing.");
329
if( ! mashFile.open( QIODevice::Truncate | QIODevice::WriteOnly ) )
331
Brewtarget::log(Brewtarget::ERROR, "Could not open " + mashFile.fileName().toStdString() + " for writing.");
335
QTextStream dbOut(&dbFile);
336
QTextStream recipeOut(&recipeFile);
337
QTextStream mashOut(&mashFile);
340
dbRoot = dbDoc.createElement("DATABASE");
342
std::list<Equipment*>::iterator eqit, eqend;
343
eqend = equipments.end();
344
for( eqit = equipments.begin(); eqit != eqend; ++eqit )
345
(*eqit)->toXml(dbDoc, dbRoot);
347
std::list<Fermentable*>::iterator fit, fend;
348
fend = fermentables.end();
349
for( fit = fermentables.begin(); fit != fend; ++fit )
350
(*fit)->toXml(dbDoc, dbRoot);
352
std::list<Hop*>::iterator hit, hend;
354
for( hit = hops.begin(); hit != hend; ++hit )
355
(*hit)->toXml(dbDoc, dbRoot);
357
std::list<MashStep*>::iterator msit, msend;
358
msend = mashSteps.end();
359
for( msit = mashSteps.begin(); msit != msend; ++msit )
360
(*msit)->toXml(dbDoc, dbRoot);
362
std::list<Misc*>::iterator miscit, miscend;
363
miscend = miscs.end();
364
for( miscit = miscs.begin(); miscit != miscend; ++miscit )
365
(*miscit)->toXml(dbDoc, dbRoot);
367
std::list<Style*>::iterator sit, send;
369
for( sit = styles.begin(); sit != send; ++sit )
370
(*sit)->toXml(dbDoc, dbRoot);
372
std::list<Water*>::iterator wit, wend;
374
for( wit = waters.begin(); wit != wend; ++wit )
375
(*wit)->toXml(dbDoc, dbRoot);
377
std::list<Yeast*>::iterator yit, yend;
379
for( yit = yeasts.begin(); yit != yend; ++yit )
380
(*yit)->toXml(dbDoc, dbRoot);
382
dbDoc.appendChild(dbRoot);
383
dbOut << dbDoc.toString();
387
recRoot = recDoc.createElement("RECIPES");
389
std::list<Recipe*>::iterator rit, rend;
390
rend = recipes.end();
391
for( rit = recipes.begin(); rit != rend; ++rit )
392
(*rit)->toXml(recDoc, recRoot);
394
recDoc.appendChild(recRoot);
395
recipeOut << recDoc.toString();
399
mashRoot = mashDoc.createElement("MASHS");
401
std::list<Mash*>::iterator mait, maend;
403
for( mait = mashs.begin(); mait != maend; ++mait )
404
(*mait)->toXml(mashDoc, mashRoot);
406
mashDoc.appendChild(mashRoot);
407
mashOut << mashDoc.toString();
408
/*** END mashDoc ***/
411
dbOut << QString("<?xml version=\"1.0\"?>\n");
412
recipeOut << QString("<?xml version=\"1.0\"?>\n");
413
mashOut << QString("<?xml version=\"1.0\"?>\n");
415
//=====================dbOut entries=============================
417
std::list<Equipment*>::iterator eqit, eqend;
418
eqend = equipments.end();
419
dbOut << QString("<EQUIPMENTS>\n");
420
for( eqit = equipments.begin(); eqit != eqend; ++eqit )
421
dbOut << QString((*eqit)->toXml().c_str());
422
dbOut << QString("</EQUIPMENTS>\n");
424
std::list<Fermentable*>::iterator fit, fend;
425
fend = fermentables.end();
426
dbOut << QString("<FERMENTABLES>\n");
427
for( fit = fermentables.begin(); fit != fend; ++fit )
428
dbOut << QString((*fit)->toXml().c_str());
429
dbOut << QString("</FERMENTABLES>\n");
431
std::list<Hop*>::iterator hit, hend;
433
dbOut << QString("<HOPS>\n");
434
for( hit = hops.begin(); hit != hend; ++hit )
435
dbOut << QString((*hit)->toXml().c_str());
436
dbOut << QString("</HOPS>\n");
438
std::list<MashStep*>::iterator msit, msend;
439
msend = mashSteps.end();
440
dbOut << QString("<MASH_STEPS>\n");
441
for( msit = mashSteps.begin(); msit != msend; ++msit )
442
dbOut << QString((*msit)->toXml().c_str());
443
dbOut << QString("</MASH_STEPS>\n");
445
std::list<Misc*>::iterator miscit, miscend;
446
miscend = miscs.end();
447
dbOut << QString("<MISCS>\n");
448
for( miscit = miscs.begin(); miscit != miscend; ++miscit )
449
dbOut << QString((*miscit)->toXml().c_str());
450
dbOut << QString("</MISCS>\n");
452
std::list<Style*>::iterator sit, send;
454
dbOut << QString("<STYLES>\n");
455
for( sit = styles.begin(); sit != send; ++sit )
456
dbOut << QString((*sit)->toXml().c_str());
457
dbOut << QString("</STYLES>\n");
459
std::list<Water*>::iterator wit, wend;
461
dbOut << QString("<WATERS>\n");
462
for( wit = waters.begin(); wit != wend; ++wit )
463
dbOut << QString((*wit)->toXml().c_str());
464
dbOut << QString("</WATERS>\n");
466
std::list<Yeast*>::iterator yit, yend;
468
dbOut << QString("<YEASTS>\n");
469
for( yit = yeasts.begin(); yit != yend; ++yit )
470
dbOut << QString((*yit)->toXml().c_str());
471
dbOut << QString("</YEASTS>\n");
473
//============================mashOut entries===============================
474
std::list<Mash*>::iterator mait, maend;
476
mashOut << QString("<MASHS>\n");
477
for( mait = mashs.begin(); mait != maend; ++mait )
478
mashOut << QString((*mait)->toXml().c_str());
479
mashOut << QString("</MASHS>\n");
481
//==========================recipeOut entries===============================
482
std::list<Recipe*>::iterator rit, rend;
483
rend = recipes.end();
484
recipeOut << QString("<RECIPES>\n");
485
for( rit = recipes.begin(); rit != rend; ++rit )
486
recipeOut << QString((*rit)->toXml().c_str());
487
recipeOut << QString("</RECIPES>\n");
496
//=========================accessor methods=====================================
498
// TODO: restructure the database to use maps so that this process is fast.
499
void Database::addEquipment(Equipment* equip)
503
equipments.push_back(equip);
504
equipments.sort(Equipment_ptr_cmp());
505
equipments.unique(Equipment_ptr_equals()); // No dups.
506
hasChanged(QVariant(DBEQUIP));
510
void Database::addFermentable(Fermentable* ferm)
514
fermentables.push_back(ferm);
515
fermentables.sort(Fermentable_ptr_cmp());
516
fermentables.unique(Fermentable_ptr_equals());
517
hasChanged(QVariant(DBFERM));
521
void Database::addHop(Hop* hop)
526
hops.sort(Hop_ptr_cmp());
527
hops.unique(Hop_ptr_equals());
528
hasChanged(QVariant(DBHOP));
532
void Database::addMash(Mash* mash)
536
mashs.push_back(mash);
537
mashs.sort(Mash_ptr_cmp());
538
mashs.unique(Mash_ptr_equals());
539
hasChanged(QVariant(DBMASH));
543
void Database::addMashStep(MashStep* mashStep)
547
mashSteps.push_back(mashStep);
548
mashSteps.sort(MashStep_ptr_cmp());
549
mashSteps.unique(MashStep_ptr_equals());
550
hasChanged(QVariant(DBMASHSTEP));
554
void Database::addMisc(Misc* misc)
558
miscs.push_back(misc);
559
miscs.sort(Misc_ptr_cmp());
560
miscs.unique(Misc_ptr_equals());
561
hasChanged(QVariant(DBMISC));
565
void Database::addRecipe(Recipe* rec, bool copySubelements)
570
recipes.push_back(rec);
571
recipes.sort(Recipe_ptr_cmp());
572
recipes.unique(Recipe_ptr_equals());
574
if( copySubelements )
576
unsigned int i, size;
577
addEquipment(rec->getEquipment());
578
addMash(rec->getMash());
579
addStyle(rec->getStyle());
581
size = rec->getNumFermentables();
582
for( i = 0; i < size; ++i )
583
addFermentable( rec->getFermentable(i) );
584
size = rec->getNumHops();
585
for( i = 0; i < size; ++i )
586
addHop( rec->getHop(i) );
587
size = rec->getNumMiscs();
588
for( i = 0; i < size; ++i )
589
addMisc( rec->getMisc(i) );
590
size = rec->getNumWaters();
591
for( i = 0; i < size; ++i )
592
addWater( rec->getWater(i) );
593
size = rec->getNumYeasts();
594
for( i = 0; i < size; ++i )
595
addYeast( rec->getYeast(i) );
598
hasChanged(DBRECIPE);
602
void Database::addStyle(Style* style)
606
styles.push_back(style);
607
styles.sort(Style_ptr_cmp());
608
styles.unique(Style_ptr_equals());
609
hasChanged(QVariant(DBSTYLE));
613
void Database::removeEquipment(Equipment* equip)
615
equipments.remove(equip);
616
hasChanged(QVariant(DBEQUIP));
619
void Database::removeFermentable(Fermentable* ferm)
621
fermentables.remove(ferm);
622
hasChanged(QVariant(DBFERM));
625
void Database::removeHop(Hop* hop)
628
hasChanged(QVariant(DBHOP));
631
void Database::removeMash(Mash* mash)
634
hasChanged(QVariant(DBMASH));
637
void Database::removeMashStep(MashStep* mashStep)
639
mashSteps.remove(mashStep);
640
hasChanged(QVariant(DBMASHSTEP));
643
void Database::removeMisc(Misc* misc)
646
hasChanged(QVariant(DBMISC));
649
void Database::removeRecipe(Recipe* rec)
652
hasChanged(QVariant(DBRECIPE));
655
void Database::removeStyle(Style* style)
657
styles.remove(style); // Wow, that was easy.
658
hasChanged(QVariant(DBSTYLE));
661
void Database::removeWater(Water* water)
663
waters.remove(water);
664
hasChanged(QVariant(DBWATER));
667
void Database::removeYeast(Yeast* yeast)
669
yeasts.remove(yeast);
670
hasChanged(QVariant(DBYEAST));
673
void Database::addWater(Water* water)
677
waters.push_back(water);
678
waters.sort(Water_ptr_cmp());
679
waters.unique(Water_ptr_equals());
680
hasChanged(QVariant(DBWATER));
684
void Database::addYeast(Yeast* yeast)
688
yeasts.push_back(yeast);
689
yeasts.sort(Yeast_ptr_cmp());
690
yeasts.unique(Yeast_ptr_equals());
691
hasChanged(QVariant(DBYEAST));
696
unsigned int Database::getNumEquipments()
698
return equipments.size();
701
unsigned int Database::getNumFermentables()
703
return fermentables.size();
706
unsigned int Database::getNumHops()
711
unsigned int Database::getNumMashs()
716
unsigned int Database::getNumMashSteps()
718
return mashSteps.size();
721
unsigned int Database::getNumMiscs()
726
unsigned int Database::getNumRecipes()
728
return recipes.size();
731
unsigned int Database::getNumStyles()
733
return styles.size();
736
unsigned int Database::getNumWaters()
738
return waters.size();
741
unsigned int Database::getNumYeasts()
743
return yeasts.size();
747
std::list<Equipment*>::iterator Database::getEquipmentBegin()
749
return equipments.begin();
752
std::list<Equipment*>::iterator Database::getEquipmentEnd()
754
return equipments.end();
757
std::list<Fermentable*>::iterator Database::getFermentableBegin()
759
return fermentables.begin();
762
std::list<Fermentable*>::iterator Database::getFermentableEnd()
764
return fermentables.end();
767
std::list<Hop*>::iterator Database::getHopBegin()
772
std::list<Hop*>::iterator Database::getHopEnd()
777
std::list<Mash*>::iterator Database::getMashBegin()
779
return mashs.begin();
782
std::list<Mash*>::iterator Database::getMashEnd()
787
std::list<MashStep*>::iterator Database::getMashStepBegin()
789
return mashSteps.begin();
792
std::list<MashStep*>::iterator Database::getMashStepEnd()
794
return mashSteps.end();
797
std::list<Misc*>::iterator Database::getMiscBegin()
799
return miscs.begin();
802
std::list<Misc*>::iterator Database::getMiscEnd()
807
std::list<Recipe*>::iterator Database::getRecipeBegin()
809
return recipes.begin();
812
std::list<Recipe*>::iterator Database::getRecipeEnd()
814
return recipes.end();
817
std::list<Style*>::iterator Database::getStyleBegin()
819
return styles.begin();
822
std::list<Style*>::iterator Database::getStyleEnd()
827
std::list<Water*>::iterator Database::getWaterBegin()
829
return waters.begin();
832
std::list<Water*>::iterator Database::getWaterEnd()
837
std::list<Yeast*>::iterator Database::getYeastBegin()
839
return yeasts.begin();
842
std::list<Yeast*>::iterator Database::getYeastEnd()
847
Equipment* Database::findEquipmentByName(std::string name)
849
std::list<Equipment*>::iterator it, end;
850
end = equipments.end();
852
for( it = equipments.begin(); it != end; it++ )
854
if( (*it)->getName() == name )
861
Fermentable* Database::findFermentableByName(std::string name)
863
std::list<Fermentable*>::iterator it, end;
864
end = fermentables.end();
866
for( it = fermentables.begin(); it != end; it++ )
868
if( (*it)->getName() == name )
875
Hop* Database::findHopByName(std::string name)
877
std::list<Hop*>::iterator it, end;
880
for( it = hops.begin(); it != end; it++ )
882
if( (*it)->getName() == name )
889
Mash* Database::findMashByName(std::string name)
891
std::list<Mash*>::iterator it, end;
894
for( it = mashs.begin(); it != end; it++ )
896
if( (*it)->getName() == name )
903
MashStep* Database::findMashStepByName(std::string name)
905
std::list<MashStep*>::iterator it, end;
906
end = mashSteps.end();
908
for( it = mashSteps.begin(); it != end; it++ )
910
if( (*it)->getName() == name )
917
Misc* Database::findMiscByName(std::string name)
919
std::list<Misc*>::iterator it, end;
922
for( it = miscs.begin(); it != end; it++ )
924
if( (*it)->getName() == name )
931
Recipe* Database::findRecipeByName(std::string name)
933
std::list<Recipe*>::iterator it, end;
936
for( it = recipes.begin(); it != end; it++ )
938
if( (*it)->getName() == name )
945
Style* Database::findStyleByName(std::string name)
947
std::list<Style*>::iterator it, end;
950
for( it = styles.begin(); it != end; it++ )
952
if( (*it)->getName() == name )
959
Water* Database::findWaterByName(std::string name)
961
std::list<Water*>::iterator it, end;
964
for( it = waters.begin(); it != end; it++ )
966
if( (*it)->getName() == name )
973
Yeast* Database::findYeastByName(std::string name)
975
std::list<Yeast*>::iterator it, end;
978
for( it = yeasts.begin(); it != end; it++ )
980
if( (*it)->getName() == name )