Month month;
int day;
+ int OnCompare(Date b)
+ {
+ if(year > b.year) return 1;
+ if(year < b.year) return -1;
+ if(month > b.month) return 1;
+ if(month < b.month) return -1;
+ if(day > b.day) return 1;
+ if(day < b.day) return -1;
+ return 0;
+ }
+
const char * OnGetString(char * stringOutput, void * fieldData, bool * needClass)
{
if(stringOutput)
void SkipEmpty()
{
- while(!f.Eof() && (!ch || ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t'))
+ while(!f.Eof() && (!ch || ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t' || ch == '/'))
{
f.Getc(&ch);
}
extern int __ecereVMethodID_class_OnFree;
private:
+static SerialBuffer collationBuffer1 { };
+static SerialBuffer collationBuffer2 { };
+static char storage1[512];
+static char storage2[512];
+
int CollationCompare(Class type, int count1, const void * data1, int count2, const void * data2)
{
if(type.type == normalClass || type.type == noHeadClass)
{
void * inst1, * inst2;
int result;
- SerialBuffer buffer1 { size = count1, count = count1, buffer = (byte *)data1 };
- SerialBuffer buffer2 { size = count2, count = count2, buffer = (byte *)data2 };
-
- inst1 = new0 byte[type.structSize];
- inst2 = new0 byte[type.structSize];
+ //SerialBuffer buffer1 { size = count1, count = count1, buffer = (byte *)data1 };
+ //SerialBuffer buffer2 { size = count2, count = count2, buffer = (byte *)data2 };
+
+ SerialBuffer buffer1 = collationBuffer1;
+ SerialBuffer buffer2 = collationBuffer2;
+ buffer1.buffer = (byte*)data1;
+ buffer1.size = count1;
+ buffer1.count = count1;
+ buffer1.pos = 0;
+ buffer2.buffer = (byte*)data2;
+ buffer2.size = count2;
+ buffer2.count = count2;
+ buffer2.pos = 0;
+
+ if(type.structSize > 512)
+ {
+ inst1 = new0 byte[type.structSize];
+ inst2 = new0 byte[type.structSize];
+ }
+ else
+ {
+ inst1 = storage1;
+ inst2 = storage2;
+ }
((void (*)(void *, void *, void *))(void *)type._vTbl[__ecereVMethodID_class_OnUnserialize])(type, inst1, buffer1);
((void (*)(void *, void *, void *))(void *)type._vTbl[__ecereVMethodID_class_OnUnserialize])(type, inst2, buffer2);
buffer1.buffer = null;
buffer2.buffer = null;
- delete buffer1;
- delete buffer2;
- delete inst1;
- delete inst2;
+ //delete buffer1;
+ //delete buffer2;
+ if(type.structSize > 512)
+ {
+ delete inst1;
+ delete inst2;
+ }
return result;
}
else
result = sqlite3_create_collation_v2(db.db, type.fullName, SQLITE_UTF8, type, CollationCompare, null);
}
}
- if(sqliteType != SQLITE_BLOB && eClass_IsDerived(type, class(eda::Id)))
+ if(sqliteType != SQLITE_BLOB && eClass_IsDerived(type, class(eda::Id)) && type != class(eda::Id))
{
Table * table = (Table *)(intptr)eClass_GetProperty(type, "table");
if(table) refTable = *table;
if(updateStatement)
sqlite3_finalize(updateStatement);
sprintf(command, "UPDATE `%s` SET `%s` = ? WHERE ROWID = ?;", tbl.name, sqlFld.name);
+ // TODO: Shouldn't we cache those update statements per field?
result = sqlite3_prepare_v2(tbl.db.db, command, -1, &updateStatement, null);
sqlite3_bind_int64(updateStatement, 2, (sqlite3_int64)rowID);
BindData(updateStatement, 1, (SQLiteField)fld, data, null);
if(type.type == structClass)
data = (int64)(intptr)new0 byte[type.structSize];
((bool (*)())(void *)r.GetData)(r, nameField, type, (type.type == structClass) ? (void *)(intptr)data : &data);
- s = CopyString(((char *(*)(void *, void *, char *, void *, bool *))(void *)type._vTbl[__ecereVMethodID_class_OnGetString])(type, (void *)(intptr)data, tempString, null, null));
+ if(type.type == systemClass || type.type == enumClass || type.type == bitClass)
+ s = CopyString(((char *(*)(void *, void *, char *, void *, bool *))(void *)type._vTbl[__ecereVMethodID_class_OnGetString])(type, &data, tempString, null, null));
+ else
+ s = CopyString(((char *(*)(void *, void *, char *, void *, bool *))(void *)type._vTbl[__ecereVMethodID_class_OnGetString])(type, (void *)(intptr)data, tempString, null, null));
((void (*)(void *, void *))(void *)type._vTbl[__ecereVMethodID_class_OnFree])(type, (void *)(intptr)data);
if(type.type == structClass)
{
anchor = { left = 110, right = shadowS + sgs * 2 };
borderStyle = deep;
+ // TOCHECK: Testing this for GenericEditor performance issue?
+ keepEditor = true;
+
public:
property Row row
{
{
if(listSection.fldId && listSection.fldName)
{
- bool stringName = !strcmp(listSection.fldName.type.dataTypeString, "char *");
+ Class type = listSection.fldName.type;
+ bool stringName = !strcmp(type.dataTypeString, "char *");
while(r.Next())
{
Id id = 0;
if(stringName)
r.GetData(listSection.fldName, s);
else
- s = PrintString("Entry ", id);
+ {
+ s = GetNameString(r, listSection.fldName);
+ // s = PrintString("Entry ", id);
+ }
listSection.list.AddString(s).tag = id;
delete s;
}
public import "ecere"
+public int UnescapeString(char * d, char * s, int len)
+{
+ int j = 0, k = 0;
+ char ch;
+ while(j < len && (ch = s[j]))
+ {
+ switch(ch)
+ {
+ case '\\':
+ switch((ch = s[++j]))
+ {
+ case 'n': d[k] = '\n'; break;
+ case 't': d[k] = '\t'; break;
+ case 'a': d[k] = '\a'; break;
+ case 'b': d[k] = '\b'; break;
+ case 'f': d[k] = '\f'; break;
+ case 'r': d[k] = '\r'; break;
+ case 'v': d[k] = '\v'; break;
+ case '\\': d[k] = '\\'; break;
+ case '\"': d[k] = '\"'; break;
+ case '\'': d[k] = '\''; break;
+ default: d[k] = '\\'; d[k] = ch;
+ }
+ break;
+ default:
+ d[k] = ch;
+ }
+ j++, k++;
+ }
+ d[k] = '\0';
+ return k;
+}
+
// to be moved in ecere?
public class FileHandler
{
char valueQuotes;
int expectedFieldCount;
bool tolerateNewLineInValues;
+ bool escaped;
+ bool lastFieldEndsWithNewLine;
//bool checkNulls;
//bool checkCurlies;
};
virtual void Process()
{
bool quoted = false, status = true;
+ bool escaped = false;
Array<String> values { };
bool started = false;
int start = 0, end = 0;
int readCount = 0;
Array<char> buffer { minAllocSize = 4096 };
- //info.charNum = 0;
+ info.charNum = 0;
info.lineNum = 0;
info.rowNum = 0;
info.fieldNum = 0;
char ch = buffer[c];
if(quoted)
{
- if(ch == options.valueQuotes)
+ // For Git import...
+ bool inTextQuote = false;
+
+ if(options.lastFieldEndsWithNewLine && info.fieldNum == options.expectedFieldCount - 1 && ch == '\"' && info.charNum > 0)
+ inTextQuote = true;
+
+ if(!inTextQuote && !escaped && ch == options.valueQuotes)
{
quoted = false;
end = c;
}
+ if(options.escaped && ch == '\\')
+ escaped = true;
+ else
+ escaped = false;
}
else
{
{
int len = started ? (end-start) : 0;
String value = new char[len+1];
- memcpy(value, &buffer[start], len);
- value[len] = 0;
+ if(options.escaped)
+ UnescapeString(value, &buffer[start], len);
+ else
+ {
+ memcpy(value, &buffer[start], len);
+ value[len] = 0;
+ }
values.Add(value);
}
start = end = 0;
info.rowNum++;
status = OnRowStrings(values);
values.Free();
- //info.charNum = 0;
info.fieldNum = 0;
}
}
end = c+1;
}
}
- //info.charNum++;
+ if(ch == '\r' || ch == '\n')
+ info.charNum = 0;
+ else
+ info.charNum++;
}
}
if(end > start)
{
int len = end-start;
+
String value = new char[len+1];
- memcpy(value, &buffer[start], len);
- value[len] = 0;
+ if(options.escaped)
+ UnescapeString(value, &buffer[start], len);
+ else
+ {
+ memcpy(value, &buffer[start], len);
+ value[len] = 0;
+ }
values.Add(value);
}
if(values.count && status)
text = " ";
tabCycle = true;
size = { 800, 600 };
+ fullRender = true;
Array<FieldDataBox> dataBoxes { };
Array<Label> labels { };
{
if(strcmpi(f.name, "ID"))
{
- FieldDataBox box { editor = editor, field = f, text = f.name, size = { 200, 20 }, position = { 20, y + 16} };
+ int h = 20;
+ FieldDataBox box { editor = editor, field = f, text = f.name, size = { h = h }, anchor = { left = 20, top = y + 16, right = 20 } };
Label label { editor.editArea, position = { 20, y }, labeledWindow = box };
+ if(eClass_IsDerived(f.type, class(DataList)) || eClass_IsDerived(f.type, class(IdList)) || eClass_IsDerived(f.type, class(MultiLineString)))
+ {
+ h = 70;
+ box.size.h = h;
+ }
incref box;
incref label;
dataBoxes.Add(box);
labels.Add(label);
- y += 40;
+ y += 20 + h;
}
}
}