summaryrefslogtreecommitdiff
path: root/mg_order.h
blob: 8bbaaa5b39a00b93358c497d7d0c66d468fc464c (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
#ifndef _MG_SQL_H
#define _MG_SQL_H
#include <stdlib.h>
#include <typeinfo>
#include <string>
#include <list>
#include <vector>
#include <sstream>
#include "mg_valmap.h"
#include "mg_mysql.h"

using namespace std;

typedef list<string> strlist;

strlist& operator+=(strlist&a, strlist b);

//! \brief adds string n to string s, using string sep to separate them
string& addsep (string & s, string sep, string n);

enum mgKeyTypes {
	keyGenre1=1, // the genre types must have exactly this order!
	keyGenre2,
	keyGenre3,
	keyGenres,
	keyDecade,
	keyYear,
	keyArtist,
	keyAlbum,
	keyTitle,
	keyTrack,
	keyLanguage,
	keyRating,
	keyFolder1,
	keyFolder2,
	keyFolder3,
	keyFolder4,
	keyCreated,
	keyModified,
	keyArtistABC,
	keyTitleABC,
	keyCollection,
	keyCollectionItem,
};
const mgKeyTypes mgKeyTypesLow = keyGenre1;
const mgKeyTypes mgKeyTypesHigh = keyCollectionItem;
const unsigned int mgKeyTypesNr = keyCollectionItem;

bool iskeyGenre(mgKeyTypes kt);

class mgParts;

class mgReference {
	public:
		mgReference(string t1,string f1,string t2,string f2);
                string t1() const { return m_t1; }
                string t2() const { return m_t2; }
                string f1() const { return m_f1; }
                string f2() const { return m_f2; }
	private:
		string m_t1;
		string m_t2;
		string m_f1;
		string m_f2;
};

class mgReferences : public vector<mgReference> {
public:
	// \todo memory leak for vector ref?
	mgReferences();
	mgParts Connect(string c1, string c2) const;
private:
	bool Equal(unsigned int i,string table1, string table2) const;
	mgParts FindConnectionBetween(string table1, string table2) const;
	mgParts ConnectToTracks(string table) const;
};

class mgSelItem
{
	public:
		mgSelItem();
		mgSelItem(string v,string i,unsigned int c=0);
		void set(string v,string i,unsigned int c=0);
		void operator=(const mgSelItem& from);
		void operator=(const mgSelItem* from);
		bool operator==(const mgSelItem& other) const;
		string value() const { return m_value; } 
		string id() const { return m_id; } 
		unsigned int count() const { return m_count; } 
		bool valid() const { return m_valid; }
	private:
		bool m_valid;
		string m_value;
		string m_id;
		unsigned int m_count;
};

class mgKey {
	public:
		virtual ~mgKey() {};
		virtual mgParts Parts(mgmySql &db,bool orderby=false) const = 0;
		virtual string id() const = 0;
		virtual bool valid() const = 0;
		virtual string value () const = 0;
		//!\brief translate field into user friendly string
		virtual void set(mgSelItem& item) = 0;
		virtual mgSelItem& get() = 0;
		virtual mgKeyTypes Type() const = 0;
		virtual string map_idfield() const { return ""; }
		virtual string map_valuefield() const { return ""; }
		virtual string map_valuetable() const { return ""; }
		virtual bool Enabled(mgmySql &db) { return true; }
};


mgKey*
ktGenerate(const mgKeyTypes kt);

const char * const ktName(const mgKeyTypes kt);
mgKeyTypes ktValue(const char * name);
vector < const char*> ktNames();
 
typedef vector<mgKey*> keyvector;

class mgParts {
public:
	mgParts();
	~mgParts();
	strlist fields;
	strlist tables;
	strlist clauses;
	strlist groupby;
	strlist orders;
	mgParts& operator+=(mgParts a);
	void Prepare();
	string sql_count();
	string sql_select(bool distinct=true);
	string sql_delete_from_collection(string pid);
	string sql_update(strlist new_values);
	bool empty() const { return tables.size()==0;}
	string m_sql_select;
	bool orderByCount;
private:
	bool UsesTracks();
	mgReferences ref;
};

//! \brief converts long to string
string itos (int i);

//! \brief convert long to string
string ltos (long l);


const unsigned int MaxKeys = 20;

class mgOrder {
public:
	mgOrder();
	mgOrder(const mgOrder &from);
	mgOrder(mgValmap& nv, char *prefix);
	mgOrder(vector<mgKeyTypes> kt);
	~mgOrder();
	void InitFrom(const mgOrder &from);
        void DumpState(mgValmap& nv, char *prefix) const;
	mgParts Parts(mgmySql &db,const unsigned int level,bool orderby=true) const;
	const mgOrder& operator=(const mgOrder& from);
	mgKey*& operator[](unsigned int idx);
	unsigned int size() const { return Keys.size(); }
	void truncate(unsigned int i);
	bool empty() const { return Keys.empty(); }
	void clear();
	mgKey* Key(unsigned int idx) const;
	mgKeyTypes getKeyType(unsigned int idx) const;
	mgSelItem& getKeyItem(unsigned int idx) const;
	void setKeys(vector<mgKeyTypes> kt);
	string Name();
	void setOrderByCount(bool orderbycount) { m_orderByCount = orderbycount;}
	bool getOrderByCount() { return m_orderByCount; }
private:
	bool m_orderByCount;
	bool isCollectionOrder() const;
	keyvector Keys;
	void setKey ( const mgKeyTypes kt);
	void clean();
};

bool operator==(const mgOrder& a,const mgOrder&b); //! \brief compares only the order, not the current key values

extern mgSelItem zeroitem;

#endif               // _MG_SQL_H