2 public import static "ecere"
7 // For idRowCache connection...
16 public enum OpenType { queryRows, tableRows, viewRows, processesList, databasesList, tablesList, fieldsList };
17 public enum CreateOptions { no, create, readOnly };
18 public enum AccessOptions { integral, random };
19 public enum SeekOptions { none, reset, first, last, firstEqual, lastEqual };
20 public enum MoveOptions { nil, first, last, next, previous, middle, here };
21 public enum MatchOptions { nil };
22 public enum ObjectType { table, view };
23 public enum State { none, driver, connected, opened, closed, errorDriver };
26 #define AUTO_DELETE_TABLES
28 public class OpenOptions : uint
32 CreateOptions create:2;
33 AccessOptions access:2;
36 public class DataSourceDriver
38 OldList listDB { offset = (uint)&((Database)0).prev };
39 class_data char * name;
41 class_property char * name
43 set { class_data(name) = value; }
44 get { return class_data(name); }
48 virtual String BuildLocator(DataSource ds);
49 virtual uint GetDatabasesCount();
50 virtual bool Connect(const String locator);
51 virtual void Status();
52 virtual bool RenameDatabase(const String name, const String rename);
53 virtual bool DeleteDatabase(const String name);
54 virtual Database OpenDatabase(const String name, CreateOptions create, DataSource ds);
59 while((db = listDB.first))
68 static subclass(DataSourceDriver) GetDataDriver(char * driverName)
70 subclass(DataSourceDriver) driver = null;
71 driver = FindDataDriverDerivative(class(DataSourceDriver), driverName);
75 char moduleName[MAX_LOCATION];
76 sprintf(moduleName, "EDA%s", driverName);
77 if(module = eModule_Load(__thisModule.application, moduleName, publicAccess))
78 driver = FindDataDriverDerivative(eSystem_FindClass(module /*__thisModule.application*/, "DataSourceDriver"), driverName);
83 static subclass(DataSourceDriver) FindDataDriverDerivative(Class dataSourceDriverClass, char * driverName)
86 subclass(DataSourceDriver) derivative = null;
87 for(link = dataSourceDriverClass.derivatives.first; link; link = link.next)
89 subclass(DataSourceDriver) dataDriver = link.data;
90 Class driverClass = link.data;
91 if(dataDriver.name && !strcmp(dataDriver.name, driverName))
93 derivative = dataDriver;
96 if(driverClass.derivatives.first && (derivative = FindDataDriverDerivative(driverClass, driverName)))
102 public class DataSource
122 property String driver
124 get { return ds ? ((subclass(DataSourceDriver))(ds._class)).name : null; }
125 set { delete ds; ds = value ? eInstance_New(GetDataDriver(value)) : null; }
129 set { delete host; host = CopyString(value); }
134 set { delete port; port = CopyString(value); }
139 set { delete user; user = CopyString(value); }
144 set { delete pass; pass = CopyString(value); }
147 property String locator
156 locator = CopyString(value);
158 get { return locator; }
161 property uint databasesCount { get { return ds.GetDatabasesCount(); } }
166 if(host || port || user || pass)
169 locator = ds.BuildLocator(this);
172 return ds ? ds.Connect(locator) : false;
174 void Status() { ds.Status(); }
175 bool RenameDatabase(const String name, const String rename) { return ds.RenameDatabase(name, rename); }
176 bool DeleteDatabase(const String name) { return ds.DeleteDatabase(name); }
177 Database OpenDatabase(const String name, CreateOptions create)
179 Database db = ds.OpenDatabase(name, create, this);
189 public class Database
193 OldList listTbl { offset = (uint)&((Table)0).prev };
194 public virtual String GetName();
200 ds.listDB.Remove(this);
201 while((tbl = listTbl.first))
208 public void LinkTable(Table tbl)
210 #ifdef AUTO_DELETE_TABLES
217 property String name { get { return GetName(); } }
218 property uint tablesCount { get { return ObjectsCount(table); } }
219 property uint viewsCount { get { return ObjectsCount(view); } }
221 virtual uint ObjectsCount(ObjectType type);
222 virtual bool RenameObject(ObjectType type, const String name, const String rename);
223 virtual bool DeleteObject(ObjectType type, const String name);
224 virtual Table OpenTable(const String name, OpenOptions open);
225 virtual bool Begin();
226 virtual bool Commit();
227 virtual bool CreateCustomFunction(char * name, SQLCustomFunction customFunction);
230 public enum IndexOrder { ascending, descending };
232 public struct FieldIndex
246 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();
257 MapIterator<Table, Row> it { map = idRowCache };
259 // Remove row from Id row cache
260 idRowCache.mutex.Wait();
261 if(it.Index(this, false))
265 _refCount = 2; // Removing the Table entry will try to decref the table ('this') again
269 idRowCache.mutex.Release();
271 #ifdef AUTO_DELETE_TABLES
273 db.listTbl.Remove(this);
275 while((row = listRows.first))
279 property String name { get { return GetName(); } }
280 property Field firstField { get { return GetFirstField(); } }
281 property uint fieldsCount { get { return GetFieldsCount(); } }
282 property uint rowsCount { get { return GetRowsCount(); } }
284 virtual Field AddField(const String name, Class type, int length);
285 virtual Field FindField(const String name);
286 virtual bool GenerateIndex(int count, FieldIndex * fieldIndexes, bool init);
287 bool Index(int count, FieldIndex * fieldIndexes)
289 return GenerateIndex(count, fieldIndexes, true);
292 void GUIListBoxAddRowsField(ListBox list, const String fieldName)
296 fld = FindField(fieldName);
304 list.AddRow().SetData(null, s);
311 void GUIListBoxAddFields(ListBox list)
316 for(fld = firstField; fld; fld = fld.next)
330 void GUIListBoxAddRows(ListBox list)
341 Field fld = firstField;
342 for(df = list.firstField; df; df = df.next, fld = fld.next)
345 Class type = fld.type;
346 if(type.type == unitClass && !type.typeSize)
348 Class dataType = eSystem_FindClass(type.module, type.dataTypeString);
352 if(type.type == structClass)
353 data = (int64)new0 byte[type.structSize];
359 ((bool (*)())(void *)r.GetData)(r, fld, type, (type.type == structClass) ? (void *)data : &data);
360 if(type.type == systemClass || type.type == unitClass || type.type == bitClass || type.type == enumClass)
361 dr.SetData(df, (void *)&data);
363 dr.SetData(df, (void *)data);
365 // Is this missing some frees here? strings? Probably not: freeData = true?
366 // type._vTbl[__ecereVMethodID_class_OnFree](type, data);
367 if(type.type == structClass)
369 void * dataPtr = (void *)data;
372 else if(!strcmp(type.dataTypeString, "char *"))
374 // Strings are handled as a special case in ListBox -- normalClass, but copied when freeData = true
375 char * string = (char *)data;
390 virtual String GetName();
391 virtual Class GetType();
392 virtual int GetLength();
393 virtual Field GetPrev();
394 virtual Field GetNext();
395 virtual Table GetTable();
397 property String name { get { return GetName(); } }
398 property Class type { get { return GetType(); } }
399 property int length { get { return GetLength(); } }
400 property Field prev { get { return GetPrev(); } }
401 property Field next { get { return GetNext(); } }
402 property Table table { get { return GetTable(); } }
404 bool GetData(Row row, typed_object & data)
406 return row.GetData(this, data);
409 bool SetData(Row row, typed_object & data)
411 return row.SetData(this, data);
426 tbl.listRows.Remove(this);
437 row = value ? value.CreateRow() : null;
441 tbl.listRows.Remove(this);
458 tbl.listRows.Add(this);
465 property bool nil { get { return row ? row.Nil() : true; } }
467 property char * query { set { if(row) row.Query(value); } }
469 public bool Query(char * query) // Add printf format support
472 return row.Query(query);
475 bool Select(MoveOptions move) { return row ? row.Select(move) : false; }
476 bool First() { return row ? row.Select(first) : false; }
477 bool Last() { return row ? row.Select(last) : false; }
478 bool Next() { return row ? row.Select(next) : false; }
479 bool Previous() { return row ? row.Select(previous) : false; }
481 bool Find(Field field, MoveOptions move, MatchOptions match, typed_object data) { return (row && field) ? row.Find(field, move, match, data) : false; }
482 bool FindMultiple(FieldFindData * findData, MoveOptions move, int numFields) { return row ? row.FindMultiple(findData, move, numFields) : false; }
484 bool Synch(Row to) { return row && to && row._class == to.row._class ? row.Synch(to.row) : false; }
486 bool Add() { return row ? row.Add(0) : false; }
487 bool AddID(uint64 id) { return row ? row.Add(id) : false; }
488 bool GetData(Field field, typed_object & data) { return (row && field) ? row.GetData(field, data) : false; }
489 bool SetData(Field field, typed_object data) { return (row && field) ? row.SetData(field, data) : false; }
490 bool Delete() { return row ? row.Delete() : false; }
491 // TODO: Implement as a typed_object?
492 bool SetQueryParam(int paramID, int value) { return row ? row.SetQueryParam(paramID, value) : false; }
493 bool SetQueryParam64(int paramID, int64 value) { return row ? row.SetQueryParam64(paramID, value) : false; }
494 bool SetQueryParamText(int paramID, char * value) { return row ? row.SetQueryParamText(paramID, value) : false; }
495 bool SetQueryParamObject(int paramID, void * value, Class type) { return row ? row.SetQueryParamObject(paramID, value, type) : false; }
496 char * GetColumn(int paramID) { return row ? row.GetColumn(paramID) : null; }
498 bool GUIDataRowSetData(DataRow dr, DataField df, Field fld)
501 Class type = fld.type;
502 if(type.type == unitClass && !type.typeSize)
504 Class dataType = eSystem_FindClass(type.module, type.dataTypeString);
508 if(type.type == structClass)
509 data = (int64)new0 byte[type.structSize];
510 ((bool (*)())(void *)GetData)(this, fld, type, (type.type == structClass) ? (void *)data : &data);
512 if((type.type == systemClass || type.type == unitClass || type.type == bitClass || type.type == enumClass))
513 dr.SetData(df, (void *)&data);
515 dr.SetData(df, (void *)data);
516 if(type.type == structClass)
518 void * dataPtr = (void *)data;
521 else if(!strcmp(type.dataTypeString, "char *"))
523 // Strings are handled as a special case in ListBox -- normalClass, but copied when freeData = true
524 char * string = (char *)data;
529 property uint sysID { get { return row ? row.GetSysID() : 0; } set { if(row) row.GoToSysID(value); } }
532 public class DriverRow
536 virtual bool Select(MoveOptions move);
537 virtual bool Find(Field fld, MoveOptions move, MatchOptions match, typed_object data);
538 virtual bool FindMultiple(FieldFindData * findData, MoveOptions move, int numFields);
539 virtual bool Synch(DriverRow to);
540 virtual bool Add(uint64 id);
541 virtual bool Delete();
543 virtual bool GetData(Field fld, typed_object &data);
544 virtual bool SetData(Field fld, typed_object data);
545 virtual uint GetSysID();
546 virtual bool GoToSysID(uint id);
547 virtual bool Query(char * queryString);
548 virtual bool SetQueryParam(int paramID, int value);
549 virtual bool SetQueryParam64(int paramID, int64 value);
550 virtual bool SetQueryParamText(int paramID, char * value);
551 virtual bool SetQueryParamObject(int paramID, void * data, Class type);
552 virtual char * GetColumn(int paramID);
555 public class SQLCustomFunction
558 Array<char> array { minAllocSize = 1024 };
559 virtual void Process(char * text);
562 public struct FieldFindData
568 static inline void DebugLn(typed_object object, ...)
570 #if defined(_DEBUG_LINE)
573 va_start(args, object);
574 PrintStdArgsToBuffer(buffer, sizeof(buffer), object, args);