summaryrefslogtreecommitdiffstats
path: root/krecipes/src/backends/recipedb.h
blob: f987c327e9ef4ad5d410c671f1f5525771b79ead (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
/***************************************************************************
*   Copyright (C) 2003                                                    *
*   Unai Garro (ugarro@users.sourceforge.net)                             *
*   Cyril Bosselut (bosselut@b1project.com)                               *
*                                                                         *
*   Copyright (C) 2003-2006 Jason Kivlighn (jkivlighn@gmail.com)          *
*                                                                         *
*   This program is free software; you can redistribute it and/or modify  *
*   it under the terms of the GNU General Public License as published by  *
*   the Free Software Foundation; either version 2 of the License, or     *
*   (at your option) any later version.                                   *
***************************************************************************/

#ifndef RECIPEDB_H
#define RECIPEDB_H

#include <ntqobject.h>
#include <ntqstring.h>
#include <ntqvaluelist.h>

#include <dcopclient.h>

#include "krecipesdbiface.h"

#include "datablocks/recipe.h"
#include "datablocks/recipelist.h"
#include "datablocks/elementlist.h"
#include "datablocks/ingredientpropertylist.h"
#include "datablocks/unitratiolist.h"
#include "datablocks/unit.h"

#define DEFAULT_DB_NAME "Krecipes"

/**
@author Unai Garro
*/

class TDEProcess;
class TQTextStream;

class CategoryTree;
class RecipeSearchParameters;
class Weight;
class WeightList;

typedef struct
{
	TQValueList <int> recipeIdList;
	IngredientList ilist;
}
RecipeIngredientList;

class RecipeDB: public TQObject, virtual public KrecipesDBIface
{
	Q_OBJECT

public:
	RecipeDB();
	virtual ~RecipeDB();

	virtual void connect( bool create_db = true, bool create_tables = true ) = 0;

	void importSamples();

	bool backup( const TQString &file ){ return backup(file,0); }
	bool backup( const TQString &file, TQString *errMsg = 0 );
	bool restore( const TQString &file, TQString *errMsg = 0 );

	// Error handling (passive)
	bool dbOK;
	TQString dbErr;

	enum RecipeItems { 
		None = 0,
		NamesOnly = 256,
		Noatime = 1024,
		Photo = 1,
		Instructions = 2,
		Ingredients = 4,
		Authors = 8,
		Categories = 16,
		PrepTime = 32,
		Yield = 64,
		Title = 128,
		Meta = 512,
		Ratings = 2048,
		Properties = 4096,
		IngredientAmounts = 8192,
		All = 0xFFFF ^ NamesOnly ^ Noatime
	};

	enum ConversionStatus {
		Success,
		MissingUnitConversion,
		MissingIngredientWeight,
		MissingIngredient,
		InvalidTypes,
		MismatchedPrepMethod,
		MismatchedPrepMethodUsingApprox
	};

public slots:
	void cancelOperation(){ haltOperation = true; }

signals:
	void progressBegin(int,const TQString &c=TQString::null,const TQString &t=TQString::null,int rate=1);
	void progressDone();
	void progress();

	void authorCreated( const Element & );
	void authorRemoved( int id );

	void categoryCreated( const Element &, int parent_id );
	void categoryRemoved( int id );
	void categoryModified( const Element & );
	void categoryModified( int id, int parent_id );
	void categoriesMerged( int id1, int id2 );

	void ingGroupCreated( const Element & );
	void ingGroupRemoved( int id );

	void ingredientCreated( const Element & );
	void ingredientRemoved( int id );

	void prepMethodCreated( const Element & );
	void prepMethodRemoved( int id );

	void propertyCreated( const IngredientProperty & );
	void propertyRemoved( int id );

	void unitCreated( const Unit & );
	void unitRemoved( int id );

	void ratingCriteriaCreated( const Element & );

	void recipeCreated( const Element &, const ElementList &categories );
	void recipeRemoved( int id );
	void recipeRemoved( int id, int cat_id );
	void recipeModified( const Element &, const ElementList &categories );

	// Public methods
public:
	/** Returns a database object of the given type or NULL upon failure.
	  * This function should be called to create a new database, rather
	  * than directly calling the constructor of a specific backend.
	  */
	static RecipeDB* createDatabase( const TQString &dbType,
	                                 const TQString &host,
	                                 const TQString &user,
	                                 const TQString &pass,
	                                 const TQString &DBname,
	                                 int port,
	                                 const TQString &file = TQString::null );

	/** Convenience method.  Calls the above with arguments from TDEConfig. */
	static RecipeDB* createDatabase( const TQString &dbType, const TQString &file = TQString::null );

	virtual void addIngredientWeight( const Weight & ) = 0;
	virtual void addProperty( const TQString &name, const TQString &units ) = 0;
	virtual void addPropertyToIngredient( int ingredientID, int propertyID, double amount, int perUnitsID ) = 0;
	virtual void addUnitToIngredient( int ingredientID, int unitID ) = 0;

	virtual void categorizeRecipe( int recipeID, const ElementList &categoryList ) = 0;
	virtual void changePropertyAmountToIngredient( int ingredientID, int propertyID, double amount, int per_units ) = 0;

	virtual void createNewAuthor( const TQString &authorName ) = 0;
	virtual void createNewCategory( const TQString &categoryName, int parent_id = -1 ) = 0;
	virtual void createNewIngGroup( const TQString &name ) = 0;
	virtual void createNewIngredient( const TQString &ingredientName ) = 0;
	virtual void createNewPrepMethod( const TQString &prepMethodName ) = 0;
	virtual void createNewRating( const TQString &name ) = 0;
	virtual void createNewUnit( const Unit &unit ) = 0;
	virtual void createNewYieldType( const TQString &type ) = 0;

	virtual void emptyData( void ) = 0;
	virtual void empty( void ) = 0;

	virtual int findExistingAuthorByName( const TQString& name ) = 0;
	virtual int findExistingCategoryByName( const TQString& name ) = 0;
	virtual int findExistingIngredientGroupByName( const TQString& name ) = 0;
	virtual int findExistingIngredientByName( const TQString& name ) = 0;
	virtual int findExistingPrepByName( const TQString& name ) = 0;
	virtual int findExistingPropertyByName( const TQString& name ) = 0;
	virtual int findExistingRatingByName( const TQString& name ) = 0;
	virtual int findExistingRecipeByName( const TQString& name ) = 0;
	virtual int findExistingUnitByName( const TQString& name ) = 0;
	virtual int findExistingYieldTypeByName( const TQString& name ) = 0;
	virtual void findIngredientUnitDependancies( int ingredientID, int unitID, ElementList *recipes, ElementList *ingredientInfo ) = 0;
	virtual void findIngredientDependancies( int ingredientID, ElementList *recipes ) = 0;
	virtual void findPrepMethodDependancies( int prepMethodID, ElementList *recipes ) = 0;
	virtual void findUnitDependancies( int unitID, ElementList *properties, ElementList *recipes, ElementList *weights ) = 0;
	virtual void findUseOfIngGroupInRecipes( ElementList *results, int groupID ) = 0;
	virtual void findUseOfCategoryInRecipes( ElementList *results, int catID ) = 0;
	virtual void findUseOfAuthorInRecipes( ElementList *results, int authorID ) = 0;

	void getIDList( const CategoryTree *categoryTree, TQStringList &ids );
	virtual TQString getUniqueRecipeTitle( const TQString &recipe_title ) = 0;
	virtual void givePermissions( const TQString &dbName, const TQString &username, const TQString &password = TQString::null, const TQString &clientHost = "localhost" ) = 0;

	void importUSDADatabase();

	virtual bool ingredientContainsProperty( int ingredientID, int propertyID, int perUnitsID ) = 0;
	virtual bool ingredientContainsUnit( int ingredientID, int unitID ) = 0;

	void initializeData( void );

	virtual int lastInsertID() = 0;

	virtual void loadAuthors( ElementList *list, int limit = -1, int offset = 0 ) = 0;
	virtual void loadCategories( CategoryTree *list, int limit = -1, int offset = 0, int parent_id = -1, bool recurse = true ) = 0;
	void loadCachedCategories( CategoryTree **list, int limit, int offset, int parent_id, bool recurse );
	virtual void loadCategories( ElementList *list, int limit = -1, int offset = 0 ) = 0;
	virtual void loadIngredientGroups( ElementList *list ) = 0;
	virtual void loadIngredients( ElementList *list, int limit = -1, int offset = 0 ) = 0;
	virtual void loadPossibleUnits( int ingredientID, UnitList *list ) = 0;
	virtual void loadPrepMethods( ElementList *list, int limit = -1, int offset = 0 ) = 0;
	virtual void loadProperties( IngredientPropertyList *list, int ingredientID = -2 ) = 0; // Loads the list of possible properties by default, all the ingredient properties with -1, and the ingredients of given property if id>=0
	void loadRecipe( Recipe *recipe, int items, int id );

	virtual void loadRatingCriterion( ElementList *list, int limit = -1, int offset = 0 ) = 0;
	/** Load all recipes with the ids in @param ids into the @ref RecipeList @param recipes */
	virtual void loadRecipes( RecipeList *, int items = All, TQValueList<int> ids = TQValueList<int>()/*, KProgressDialog *progress_dlg = 0*/ ) = 0;
	virtual void loadRecipeList( ElementList *list, int categoryID = -1, bool recursive = false ) = 0;
	virtual void loadUncategorizedRecipes( ElementList *list ) = 0;
	virtual void loadUnits( UnitList *list, Unit::Type = Unit::All, int limit = -1, int offset = 0 ) = 0;
	virtual void loadUnitRatios( UnitRatioList *ratioList, Unit::Type ) = 0;
	virtual void loadYieldTypes( ElementList *list, int limit = -1, int offset = 0 ) = 0;

	/** Change all instances of authors with id @param id2 to @param id1 */
	virtual void mergeAuthors( int id1, int id2 ) = 0;

	/** Change all instances of categories with id @param id2 to @param id1 */
	virtual void mergeCategories( int id1, int id2 ) = 0;

	virtual void mergeIngredientGroups( int id1, int id2 ) = 0;

	/** Change all instances of ingredients with id @param id2 to @param id1 */
	virtual void mergeIngredients( int id1, int id2 ) = 0;

	/** Change all instances of units with id @param id2 to @param id1 */
	virtual void mergeUnits( int id1, int id2 ) = 0;

	/** Change all instances of prep methods with id @param id2 to @param id1 */
	virtual void mergePrepMethods( int id1, int id2 ) = 0;

	virtual void mergeProperties( int id1, int id2 ) = 0;


	virtual void modIngredientGroup( int ingredientID, const TQString &newLabel ) = 0;
	/**
	* set newLabel for ingredientID
	*/
	virtual void modIngredient( int ingredientID, const TQString &newLabel ) = 0;
	/**
	* set newLabel for unitID
	*/
	virtual void modUnit( const Unit &unit ) = 0;
	/**
	* set newLabel for categoryID
	*/
	virtual void modCategory( int categoryID, const TQString &newLabel ) = 0;
	virtual void modCategory( int categoryID, int new_parent_id ) = 0;
	/**
	* set newLabel for authorID
	*/
	virtual void modAuthor( int authorID, const TQString &newLabel ) = 0;

	virtual void modPrepMethod( int prepMethodID, const TQString &newLabel ) = 0;

	virtual void modProperty( int propertyID, const TQString &newLabel ) = 0;

	virtual TQString recipeTitle( int recipeID ) = 0;

	virtual void removeAuthor( int categoryID ) = 0;
	virtual void removeCategory( int categoryID ) = 0;
	virtual void removeIngredientGroup( int ingredientID ) = 0;
	virtual void removeIngredient( int ingredientID ) = 0;
	virtual void removeIngredientWeight( int id ) = 0;
	virtual void removePrepMethod( int prepMethodID ) = 0;
	virtual void removeProperty( int propertyID ) = 0;
	virtual void removePropertyFromIngredient( int ingredientID, int propertyID, int perUnitID ) = 0;
	virtual void removeRecipe( int id ) = 0;
	virtual void removeRecipeFromCategory( int ingredientID, int categoryID ) = 0;
	virtual void removeUnit( int unitID ) = 0;
	virtual void removeUnitFromIngredient( int ingredientID, int unitID ) = 0;
	virtual void removeUnitRatio( int unitID1, int unitID2 ) = 0;

	virtual void saveRecipe( Recipe *recipe ) = 0;
	virtual void saveUnitRatio( const UnitRatio *ratio ) = 0;
	virtual void search( RecipeList *list, int items, const RecipeSearchParameters &parameters ) = 0;

	/** @returns true on success, false otherwise */
	ConversionStatus convertIngredientUnits( const Ingredient &from, const Unit &to, Ingredient &result );
	virtual double unitRatio( int unitID1, int unitID2 ) = 0;

	/** @returns the number of grams in the given amount of the ingredient, or -1 on failure */
	virtual double ingredientWeight( const Ingredient &ing, bool *wasApproximated = 0 ) = 0;
	virtual WeightList ingredientWeightUnits( int ingID ) = 0;

	virtual TQString escapeAndEncode( const TQString &s ) const = 0;
	virtual TQString unescapeAndDecode( const TQCString &s ) const = 0;

	virtual TQString categoryName( int ID ) = 0;
	virtual TQString ingredientName( int ID ) = 0;
	virtual TQString prepMethodName( int ID ) = 0;
	virtual IngredientProperty propertyName( int ID ) = 0;
	virtual Unit unitName( int ID ) = 0;

	virtual int categoryTopLevelCount() = 0;
	virtual int getCount( const TQString &table_name ) = 0;
	int authorCount();
	int ingredientCount();
	int prepMethodCount();
	int unitCount();
	int categoryCount();

	virtual bool checkIntegrity( void ) = 0;

	virtual void createTable( const TQString &tableName ) = 0;
	virtual void splitCommands( TQString& s, TQStringList& sl ) = 0;

	virtual float databaseVersion( void ) = 0;

	int maxAuthorNameLength() const
	{
		return 50;
	}
	int maxCategoryNameLength() const
	{
		return 40;
	}
	int maxIngredientNameLength() const
	{
		return 50;
	}
	int maxIngGroupNameLength() const
	{
		return 50;
	}
	int maxRecipeTitleLength() const
	{
		return 200;
	}
	int maxUnitNameLength() const
	{
		return 20;
	}
	int maxPrepMethodNameLength() const
	{
		return 20;
	}
	int maxPropertyNameLength() const
	{
		return 20;
	}
	int maxYieldTypeLength() const
	{
		return 20;
	}

	virtual bool ok()
	{
		return ( dbOK );
	}
	virtual TQString err()
	{
		return ( dbErr );
	}

	void updateCategoryCache( int limit );
	void clearCategoryCache();

protected:
	virtual void portOldDatabases( float version ) = 0;
	virtual TQStringList backupCommand() const = 0;
	virtual TQStringList restoreCommand() const = 0;

	//Use these with caution: SQL for one backend might not work on another!
	void execSQL( TQTextStream &stream );
	virtual void execSQL( const TQString & ) = 0;

	TQString buildSearchQuery( const RecipeSearchParameters &parameters ) const;

	double latestDBVersion() const;
	TQString krecipes_version() const;

	CategoryTree *m_categoryCache;

private:
	TQTextStream *dumpStream;
	bool haltOperation;

private slots:
	void processDumpOutput( TDEProcess *, char *buffer, int buflen );
};

#endif