db_n_n._pike
Go to the documentation of this file.
1 /* Copyright (C) 2000-2004 Thomas Bopp, Thorsten Hampel, Ludger Merkens
2  *
3  * This program is free software; you can redistribute it and/or modify
4  * it under the terms of the GNU General Public License as published by
5  * the Free Software Foundation; either version 2 of the License, or
6  * (at your option) any later version.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * $Id: db_n_n.pike,v 1.2 2009/08/07 15:22:36 nicke Exp $
18  */
19 #include <macros.h>
20 class db_n_n {
21 public:
22 
23 
24 
25 
26 
27 int get_object_id();
28 
29 private string sDbTable;
30 private function fDb;
31 
32 string tablename()
33 {
34  return copy_value(sDbTable);
35 }
36 
37 /**
38  * connect a db_mapping with database.pike
39  * @param none
40  */
41 protected:
42  final void load_db_mapping()
43 {
44  // get database access function and tablename
45 
46  [fDb , sDbTable]= _Database->connect_db_mapping();
47 
48  // we are in secure code, so create table according to
49  // values from database.
50  if( search(fDb()->list_tables(), "mi_"+sDbTable ) == -1 )
51  {
52  fDb()->big_query("create table mi_"+sDbTable+
53  "(k char(255) not null, v text,"+
54  (fDb()->get_database() == "postgres" ?
55  "unique (v, k))":"unique(v(60),k))"));
56  //FIXME: postgres needs this as:
57  //(k char(255) not null unique, v text unique)
58  }
59 }
60 
61 public:
62 
63 /**
64  * get a list of all values associated with
65  * @param string key - the key to access
66  * @result mixed value - the datastructure set with set_value
67  * @see set_value
68  */
69 protected:
70  mixed get_value(string|int|object key)
71 {
72  mixed d = ({});
73  mixed row;
74 
75  // LOG_DEBUG("db_n_n.get_value "+sprintf("%O",key));
76  if (objectp(key) && !IS_PROXY(key))
77  throw(({"Illegal object given as key to get_value", backtrace()}));
78 
79  key = serialize(key);
80 
81  // LOG_DB("search "+sDbTable +" for "+ (string) key);
82  Sql.sql_result res =
83  fDb()->big_query("select v from mi_"+sDbTable+
84  " where k like '"+fDb()->quote_index(key)+"'");
85 
86  while (res && (row=res->fetch_row()))
87  d+= ({ unserialize(row[0])});
88  destruct(res);
89  return d;
90 }
91 
92 public:
93 
94 /**
95  * since the n_n module is symmetric, it might be interesting to retreive
96  * all keys associated to a value.
97  * @param string value - the value to access
98  * @result array keys - a list (may be empty) of the keys denoting the val
99  */
100 protected:
101  array get_key(string|int|object value)
102 {
103  mixed d = ({});
104  mixed row;
105 
106  if (objectp(value) && !IS_PROXY(value))
107  throw(({"Illeagal object given as value to get_key", backtrace()}));
108 
109  string svalue = serialize(value);
110  // LOG("search "+sDbTable +" for "+ (string) key);
111  Sql.sql_result res =
112  fDb()->big_query("select k from mi_"+sDbTable+
113  " where v like '"+ fDb()->quote(svalue) +"'");
114 
115  while (res && (row=res->fetch_row()))
116  d+= ({ unserialize(row[0])});
117  destruct(res);
118  return d;
119 }
120 
121 public:
122 
123 /**
124  * Add an entry into the list, there is no duplicate check
125  * The serialization of the given value will be stored to the database
126  * @param array key - the keys to store
127  * @param mixed value - the value to associate with the keys
128  * if you pass an array to value, all of the keys given
129  * will be registered for each of "values" members.
130  * @return 1| throw
131  */
132 protected:
133  int set_value(mixed keys, mixed values)
134 {
135  mixed key;
136  mixed val;
137 
138 
139  LOG_DEBUG("db_n_n.set_value:"+sprintf("%O",keys)+" "+sprintf("%O",values)+"\n");
140  if (zero_type(keys) || zero_type(values))
141  return 0;
142 
143  if (!arrayp(keys))
144  keys = ({ keys });
145  if (!arrayp(values))
146  values = ({ values });
147 
148  delete_value(values);
149 
150  foreach(keys, key)
151  {
152  foreach(values, val)
153  {
154  // LOG_DB("inserting "+master()->detailed_describe(value)+","+
155  // master()->detailed_describe(key));
156  if(sizeof(fDb()->query("SELECT k FROM mi_"+sDbTable+" WHERE k='"
157  +fDb()->quote(serialize(key))+"'")))
158  {
159  fDb()->big_query("UPDATE mi_"+sDbTable+
160  " SET v='"+ fDb()->quote(serialize(val))+"'"
161  " WHERE k='"+fDb()->quote(serialize(key))+"'");
162  }
163  else
164  {
165  fDb()->big_query("INSERT INTO mi_" + sDbTable +
166  " VALUES('" + fDb()->quote(serialize(key)) +
167  "', '" + fDb()->quote(serialize(val)) + "')");
168  }
169  }
170  }
171  return 1;
172 }
173 
174 public:
175 
176 /**
177  * delete all entries associated to a key, or a key value pair from the
178  * database.
179  * The NIL value below is defined in macros.h to create a zero_type
180  * If used as an argument NIL matches all values. (use like an *)
181  * @param string|int|NIL key
182  * @param string|int|void value
183  * @result int - Number of deleted entries
184  */
185 protected:
186  int delete(string|int|void|object key, string|int|void|object value)
187 {
188  string svalue;
189 
190  if (zero_type(key) && zero_type(key))
191  return 0;
192  if (objectp(key) && (!IS_PROXY(key)))
193  return 0;
194  if (objectp(value) && (!IS_PROXY(value)))
195  return 0;
196 
197  if (!zero_type(value))
198  value = serialize(value);
199  if (!zero_type(key))
200  key = serialize(key);
201 
202  string bquery = "delete from mi_"+sDbTable+" where "+
203  (!zero_type(key) ? "k = '" +fDb()->quote(key)+"'" :"") +
204  (!zero_type(value) ? (!zero_type(key) ? "and " :"")+"v='" +svalue + "'" : "");
205 
206  fDb()->big_query(bquery);
207  return 1;
208 }
209 
210 public:
211 
212 
213 /**
214  * report_delete
215  * same as delete, but also reports which elements got deleted
216  * @param string|int key
217  * @param string|int|void value
218  * @result array(string|int) keys of elements deleted
219  */
220 protected:
221  array(string|int|object)
222 report_deleted(string|int|object|void key, string|int|object|void value)
223 {
224  string svalue;
225 
226  if (zero_type(key) && zero_type(key))
227  return 0;
228 
229  if (objectp(key) && (!IS_PROXY(key)))
230  return 0;
231  if (objectp(value) && (!IS_PROXY(value)))
232  return 0;
233 
234  if (!zero_type(value))
235  value = serialize(value);
236  if (!zero_type(key))
237  key = serialize(key);
238 
239  string bquery = "mi_"+sDbTable+" where "+
240  (!zero_type(key) ? "k = '" +fDb()->quote(key)+"'" :"") +
241  (!zero_type(value) ? (!zero_type(key) ? "and " :"")+ "v='" +svalue + "'" : "");
242 
243  Sql.sql_result
244  res = fDb()->big_query("select k from "+bquery);
245 
246  array tmp = ({});
247  mixed row;
248  while (res && (row=res->fetch_row()))
249  tmp+= ({ unserialize(row[0]) });
250 
251  fDb()->big_query("delete from "+bquery);
252  return tmp;
253 }
254 
255 public:
256 
257 /**
258  * delete all entries with a matching value
259  * @param string|int|object value
260  * @result int - Number of deleted entries
261  * @see delete with first Argument NIL
262  */
263 protected:
264  int delete_value(int|string|object value)
265 {
266 
267  if (objectp(value) && !IS_PROXY(value))
268  throw(({"Illegal Object passed as value to delete_value", backtrace()}));
269 
270  string svalue = serialize(value);
271  fDb()->big_query("delete from mi_"+ sDbTable+
272  " where v = '" + svalue + "'");
273  return fDb()->master_sql->affected_rows();
274 }
275 
276 public:
277 
278 /**
279  * give a list of all indices (keys) of the database table
280  * @param none
281  * @return an array containing the keys
282  * @see maapping.indices
283  */
284 protected:
285  array index()
286 {
287  Sql.sql_result res =
288  fDb()->big_query("select k from mi_"+sDbTable);
289  int sz = res->num_rows();
290  array sIndices = allocate(sz);
291  int i;
292  for(i=0; i<sz; i++)
293  sIndices[i] = unserialize(res->fetch_row()[0]);
294  return sIndices;
295 }
296 
297 public:
298 
299 string get_table_name() { return (string)get_object_id(); }
300 
301 
302 
303 };