db_mapping._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_mapping.pike,v 1.2 2009/05/06 19:23:10 astra Exp $
18  */
19 #include <macros.h>
20 //! This class simulates a mapping inside the database.
21 //! Call get_value() and set_value() functions.
22 class db_mapping {
23 public:
24 
25 
26 
27 
28 
29 
30 private string sDbTable;
31 //private mapping mData;
32 private function fDb;
33 
34 int get_object_id();
35 
36 string tablename()
37 {
38  return copy_value(sDbTable);
39 }
40 
41 /**
42  * connect a db_mapping with database.pike
43  */
44 protected:
45  final void load_db_mapping()
46 {
47  // get database access function and tablename
48  // mData = ([]);
49  [fDb , sDbTable]= _Database->connect_db_mapping();
50 
51  // we are in secure code, so create table according to
52  // values from database.
53  if( search(fDb()->list_tables(), "i_"+sDbTable ) == -1 )
54  {
55  fDb()->big_query("create table i_"+sDbTable+
56  "(k char(255) not null, v text,"+
57  (fDb()->get_database() == "postgres" ?
58  "UNIQUE(k))":"UNIQUE(k, v(60)))"));
59  }
60 }
61 
62 public:
63 
64 /**
65  * Index Operator for mapping emulation
66  * @param string key - the key to access
67  * @result mixed value - the datastructure set with `[]= if any
68  */
69 protected:
70  mixed get_value(string|int key) {
71  mixed row;
72 
73  // if (d = mData[key])
74  // return d;
75 
76  // LOG("db_mapping.get_value("+key+")");
77 
78  string query = "select v from i_"+sDbTable+
79  " where k = '"+fDb()->quote_index((string)key)+"'";
80  Sql.sql_result res =
81  fDb()->big_query(query);
82  if (!objectp(res) ) {
83  return 0;
84  }
85  else if ( !(row=res->fetch_row())) {
86  destruct(res);
87  return 0;
88  }
89  // mData[key] = unserialize(row[0]);
90  destruct(res);
91  // return mData[key];
92  return unserialize(row[0]);
93 }
94 
95 public:
96 
97 /**
98  * all keys associated to a value.
99  * @param string value - the value to access
100  * @result array keys - a list (may be empty) of the keys denoting the val
101  */
102 protected:
103  array get_key(string|int|object value)
104 {
105  mixed d = ({});
106  mixed row;
107 
108  if (objectp(value) && !IS_PROXY(value))
109  throw(({"Illeagal object given as value to get_key", backtrace()}));
110 
111  string svalue = serialize(value);
112  // LOG("search "+sDbTable +" for "+ (string) key);
113  Sql.sql_result res =
114  fDb()->big_query("select k from mi_"+sDbTable+
115  " where v like '"+ fDb()->quote_index(svalue) +"'");
116 
117  while (res && (row=res->fetch_row()))
118  d+= ({ unserialize(row[0])});
119  destruct(res);
120  return d;
121 }
122 
123 public:
124 
125 /**
126  * Write Index Operator for mapping emulation
127  * The serialization of the given value will be stored to the database
128  * @param string key - the key to access
129  * @param mixed value - the value
130  * @return value| throw
131  */
132 protected:
133  mixed set_value(string|int key, mixed value) {
134  // mData[key]=value;
135  //write("setting:"+serialize(value)+"\n");
136  if(sizeof(fDb()->query("SELECT k FROM i_"+sDbTable+
137  " WHERE k='"+fDb()->quote_index((string)key)+"'")))
138  {
139  fDb()->big_query("UPDATE i_"+sDbTable+
140  " SET v='"+ fDb()->quote(serialize(value))+ "'"
141  " WHERE k='"+ fDb()->quote_index((string)key)+"'");
142  }
143  else
144  {
145  fDb()->big_query("INSERT INTO i_" + sDbTable +
146  " VALUES('" + fDb()->quote_index((string)key) + "', '" +
147  fDb()->quote(serialize(value)) + "')");
148  }
149  return value;
150 }
151 
152 public:
153 
154 /**
155  * delete a key from the database mapping emulation.
156  * @param string|int key
157  * @result int (0|1) - Number of deleted entries
158  */
159 protected:
160  int delete(string|int key) {
161  fDb()->query("delete from i_"+ sDbTable+" where k = '"+
162  fDb()->quote_index(key)+"'");
163  return 1;
164 }
165 
166 public:
167 
168 /**
169  * select keys from the database like the given expression.
170  * @param string|int keyexpression
171  * @result array(int|string)
172  */
173 protected:
174  array report_delete(string|int key) {
175  mixed aResult = ({});
176  int i, sz;
177 
178  object handle = fDb();
179  Sql.sql_result res = handle->big_query("select k from i_"+ sDbTable +
180  " where k like '"+ fDb()->quote_index(key)+"'");
181  if (!res || !res->num_rows())
182  return ({ });
183 
184  aResult = allocate(sz=res->num_rows());
185  for (i=0;i<sz;i++)
186  aResult[i] = res->fetch_row()[0];
187 
188  fDb()->big_query("delete from i_"+ sDbTable+" where k like '"+
189  fDb()->quote_index(key)+"'");
190  // m_delete(mData, (string) key);
191 
192  return aResult;
193 }
194 
195 public:
196 
197 /**
198  * give a list of all indices (keys) of the database table
199  * @param none
200  * @return an array containing the keys
201  * @see maapping.indices
202  */
203 array index()
204 {
205  // LOG("getting index()\n");
206 
207  Sql.sql_result res = fDb()->big_query("select k from i_"+sDbTable);
208  // LOG("done...");
209 #if 1
210  int sz = res->num_rows();
211  array sIndices = allocate(sz);
212  int i;
213  for ( i = 0; i < sz; i++ )
214  {
215  string sres = copy_value(res->fetch_row()[0]);
216  sIndices[i] = sres;
217  }
218 #else
219  array sIndices = ({});
220  array mres;
221  while (mres = res->fetch_row())
222  sIndices+=mres;
223 #endif
224  destruct(res);
225  return sIndices;
226 }
227 
228 protected:
229  void clear_table()
230 {
231  fDb()->big_query("delete from i_"+sDbTable+" where 1");
232 }
233 
234 public:
235 
236 string get_table_name() { return (string)get_object_id(); }
237 
238 
239 };