2 public import static "ecere"
13 public enum OpenType { queryRows, tableRows, viewRows, processesList, databasesList, tablesList, fieldsList };
14 public enum CreateOptions { no, create, readOnly };
15 public enum AccessOptions { integral, random };
16 public enum SeekOptions { none, reset, first, last, firstEqual, lastEqual };
17 public enum MoveOptions { nil, first, last, next, previous, middle, here };
18 public enum MatchOptions { nil };
19 public enum ObjectType { table, view };
20 public enum State { none, driver, connected, opened, closed, errorDriver };
23 #define AUTO_DELETE_TABLES
25 public class OpenOptions : uint
29 CreateOptions create:2;
30 AccessOptions access:2;
33 public class DataSourceDriver
35 OldList listDB { offset = (uint)&((Database)0).prev };
36 class_data char * name;
38 class_property char * name
40 set { class_data(name) = value; }
41 get { return class_data(name); }
45 virtual String BuildLocator(DataSource ds);
46 virtual uint GetDatabasesCount();
47 virtual bool Connect(const String locator);
48 virtual void Status();
49 virtual bool RenameDatabase(const String name, const String rename);
50 virtual bool DeleteDatabase(const String name);
51 virtual Database OpenDatabase(const String name, CreateOptions create, DataSource ds);
56 while((db = listDB.first))
65 static subclass(DataSourceDriver) GetDataDriver(char * driverName)
67 subclass(DataSourceDriver) driver = null;
68 driver = FindDataDriverDerivative(class(DataSourceDriver), driverName);
72 char moduleName[MAX_LOCATION];
73 sprintf(moduleName, "EDA%s", driverName);
74 if(module = eModule_Load(__thisModule.application, moduleName, publicAccess))
75 driver = FindDataDriverDerivative(eSystem_FindClass(module /*__thisModule.application*/, "DataSourceDriver"), driverName);
80 static subclass(DataSourceDriver) FindDataDriverDerivative(Class dataSourceDriverClass, char * driverName)
83 subclass(DataSourceDriver) derivative = null;
84 for(link = dataSourceDriverClass.derivatives.first; link; link = link.next)
86 subclass(DataSourceDriver) dataDriver = link.data;
87 Class driverClass = link.data;
88 if(dataDriver.name && !strcmp(dataDriver.name, driverName))
90 derivative = dataDriver;
93 if(driverClass.derivatives.first && (derivative = FindDataDriverDerivative(driverClass, driverName)))
99 public class DataSource
119 property String driver
121 get { return ds ? ((subclass(DataSourceDriver))(ds._class)).name : null; }
122 set { delete ds; ds = value ? eInstance_New(GetDataDriver(value)) : null; }
126 set { delete host; host = CopyString(value); }
131 set { delete port; port = CopyString(value); }
136 set { delete user; user = CopyString(value); }
141 set { delete pass; pass = CopyString(value); }
144 property String locator
153 locator = CopyString(value);
155 get { return locator; }
158 property uint databasesCount { get { return ds.GetDatabasesCount(); } }
163 if(host || port || user || pass)
166 locator = ds.BuildLocator(this);
169 return ds ? ds.Connect(locator) : false;
171 void Status() { ds.Status(); }
172 bool RenameDatabase(const String name, const String rename) { return ds.RenameDatabase(name, rename); }
173 bool DeleteDatabase(const String name) { return ds.DeleteDatabase(name); }
174 Database OpenDatabase(const String name, CreateOptions create)
176 Database db = ds.OpenDatabase(name, create, this);
186 public class Database
190 OldList listTbl { offset = (uint)&((Table)0).prev };
191 public virtual String GetName();
197 ds.listDB.Remove(this);
198 while((tbl = listTbl.first))
205 public void LinkTable(Table tbl)
207 #ifdef AUTO_DELETE_TABLES
214 property String name { get { return GetName(); } }
215 property uint tablesCount { get { return ObjectsCount(table); } }
216 property uint viewsCount { get { return ObjectsCount(view); } }
218 virtual uint ObjectsCount(ObjectType type);
219 virtual bool RenameObject(ObjectType type, const String name, const String rename);
220 virtual bool DeleteObject(ObjectType type, const String name);
221 virtual Table OpenTable(const String name, OpenOptions open);
222 virtual bool Begin();
223 virtual bool Commit();
224 virtual bool CreateCustomFunction(char * name, SQLCustomFunction customFunction);
227 public enum IndexOrder { ascending, descending };
229 public struct FieldIndex
238 Mutex idRowCacheMutex { };
245 OldList listRows { offset = (uint)&((Row)0).prev };
248 virtual String GetName();
249 virtual Field GetFirstField();
250 virtual uint GetFieldsCount();
251 virtual uint GetRowsCount();
252 virtual DriverRow CreateRow();
258 // Delete cached Id row
259 idRowCacheMutex.Wait();
261 idRowCacheMutex.Release();
263 #ifdef AUTO_DELETE_TABLES
265 db.listTbl.Remove(this);
267 while((row = listRows.first))
271 property String name { get { return GetName(); } }
272 property Field firstField { get { return GetFirstField(); } }
273 property uint fieldsCount { get { return GetFieldsCount(); } }
274 property uint rowsCount { get { return GetRowsCount(); } }
276 virtual Field AddField(const String name, Class type, int length);
277 virtual Field FindField(const String name);
278 virtual bool GenerateIndex(int count, FieldIndex * fieldIndexes, bool init);
279 bool Index(int count, FieldIndex * fieldIndexes)
281 return GenerateIndex(count, fieldIndexes, true);
284 void GUIListBoxAddRowsField(ListBox list, const String fieldName)
288 fld = FindField(fieldName);
296 list.AddRow().SetData(null, s);
303 void GUIListBoxAddFields(ListBox list)
308 for(fld = firstField; fld; fld = fld.next)
322 void GUIListBoxAddRows(ListBox list)
333 Field fld = firstField;
334 for(df = list.firstField; df; df = df.next, fld = fld.next)
337 Class type = fld.type;
338 if(type.type == unitClass && !type.typeSize)
340 Class dataType = eSystem_FindClass(type.module, type.dataTypeString);
344 if(type.type == structClass)
345 data = (int64)new0 byte[type.structSize];
351 ((bool (*)())(void *)r.GetData)(r, fld, type, (type.type == structClass) ? (void *)data : &data);
352 if(type.type == systemClass || type.type == unitClass || type.type == bitClass || type.type == enumClass)
353 dr.SetData(df, (void *)&data);
355 dr.SetData(df, (void *)data);
357 // Is this missing some frees here? strings? Probably not: freeData = true?
358 // type._vTbl[__ecereVMethodID_class_OnFree](type, data);
359 if(type.type == structClass)
361 void * dataPtr = (void *)data;
364 else if(!strcmp(type.dataTypeString, "char *"))
366 // Strings are handled as a special case in ListBox -- normalClass, but copied when freeData = true
367 char * string = (char *)data;
382 virtual String GetName();
383 virtual Class GetType();
384 virtual int GetLength();
385 virtual Field GetPrev();
386 virtual Field GetNext();
387 virtual Table GetTable();
389 property String name { get { return GetName(); } }
390 property Class type { get { return GetType(); } }
391 property int length { get { return GetLength(); } }
392 property Field prev { get { return GetPrev(); } }
393 property Field next { get { return GetNext(); } }
394 property Table table { get { return GetTable(); } }
396 bool GetData(Row row, typed_object & data)
398 return row.GetData(this, data);
401 bool SetData(Row row, typed_object & data)
403 return row.SetData(this, data);
418 tbl.listRows.Remove(this);
429 row = value ? value.CreateRow() : null;
433 tbl.listRows.Remove(this);
450 tbl.listRows.Add(this);
457 property bool nil { get { return row ? row.Nil() : true; } }
459 property char * query { set { if(row) row.Query(value); } }
461 public bool Query(char * query) // Add printf format support
464 return row.Query(query);
467 bool Select(MoveOptions move) { return row ? row.Select(move) : false; }
468 bool First() { return row ? row.Select(first) : false; }
469 bool Last() { return row ? row.Select(last) : false; }
470 bool Next() { return row ? row.Select(next) : false; }
471 bool Previous() { return row ? row.Select(previous) : false; }
473 bool Find(Field field, MoveOptions move, MatchOptions match, typed_object data) { return (row && field) ? row.Find(field, move, match, data) : false; }
474 bool FindMultiple(FieldFindData * findData, MoveOptions move, int numFields) { return row ? row.FindMultiple(findData, move, numFields) : false; }
476 bool Synch(Row to) { return row && to && row._class == to.row._class ? row.Synch(to.row) : false; }
478 bool Add() { return row ? row.Add(0) : false; }
479 bool AddID(uint64 id) { return row ? row.Add(id) : false; }
480 bool GetData(Field field, typed_object & data) { return (row && field) ? row.GetData(field, data) : false; }
481 bool SetData(Field field, typed_object data) { return (row && field) ? row.SetData(field, data) : false; }
482 bool Delete() { return row ? row.Delete() : false; }
483 // TODO: Implement as a typed_object?
484 bool SetQueryParam(int paramID, int value) { return row ? row.SetQueryParam(paramID, value) : false; }
485 bool SetQueryParam64(int paramID, int64 value) { return row ? row.SetQueryParam64(paramID, value) : false; }
486 bool SetQueryParamText(int paramID, char * value) { return row ? row.SetQueryParamText(paramID, value) : false; }
487 bool SetQueryParamObject(int paramID, void * value, Class type) { return row ? row.SetQueryParamObject(paramID, value, type) : false; }
488 char * GetColumn(int paramID) { return row ? row.GetColumn(paramID) : null; }
490 bool GUIDataRowSetData(DataRow dr, DataField df, Field fld)
493 Class type = fld.type;
494 if(type.type == unitClass && !type.typeSize)
496 Class dataType = eSystem_FindClass(type.module, type.dataTypeString);
500 if(type.type == structClass)
501 data = (int64)new0 byte[type.structSize];
502 ((bool (*)())(void *)GetData)(this, fld, type, (type.type == structClass) ? (void *)data : &data);
504 if((type.type == systemClass || type.type == unitClass || type.type == bitClass || type.type == enumClass))
505 dr.SetData(df, (void *)&data);
507 dr.SetData(df, (void *)data);
508 if(type.type == structClass)
510 void * dataPtr = (void *)data;
513 else if(!strcmp(type.dataTypeString, "char *"))
515 // Strings are handled as a special case in ListBox -- normalClass, but copied when freeData = true
516 char * string = (char *)data;
521 property uint sysID { get { return row ? row.GetSysID() : 0; } set { if(row) row.GoToSysID(value); } }
524 public class DriverRow
528 virtual bool Select(MoveOptions move);
529 virtual bool Find(Field fld, MoveOptions move, MatchOptions match, typed_object data);
530 virtual bool FindMultiple(FieldFindData * findData, MoveOptions move, int numFields);
531 virtual bool Synch(DriverRow to);
532 virtual bool Add(uint64 id);
533 virtual bool Delete();
535 virtual bool GetData(Field fld, typed_object &data);
536 virtual bool SetData(Field fld, typed_object data);
537 virtual uint GetSysID();
538 virtual bool GoToSysID(uint id);
539 virtual bool Query(char * queryString);
540 virtual bool SetQueryParam(int paramID, int value);
541 virtual bool SetQueryParam64(int paramID, int64 value);
542 virtual bool SetQueryParamText(int paramID, char * value);
543 virtual bool SetQueryParamObject(int paramID, void * data, Class type);
544 virtual char * GetColumn(int paramID);
547 public class SQLCustomFunction
550 Array<char> array { minAllocSize = 1024 };
551 virtual void Process(char * text);
554 public struct FieldFindData
560 static inline void DebugLn(typed_object object, ...)
562 #if defined(_DEBUG_LINE)
565 va_start(args, object);
566 PrintStdArgsToBuffer(buffer, sizeof(buffer), object, args);