Fixed encoding issues in MySql, new ExportIds utility (in Sql) creates a file of SQLID constants for given database

git-svn-id: svn://ultimatepp.org/upp/trunk@361 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
cxl 2008-08-20 10:06:42 +00:00
parent be14fe1e48
commit 2fe3327c8e
4 changed files with 69 additions and 17 deletions

View file

@ -26,9 +26,11 @@ private:
unsigned long *len;
int rows;
int lastid;
Buffer<bool> convert;
String MakeQuery() const;
void FreeResult();
String EscapeString(const String& v);
public:
MySqlConnection(MySqlSession& session, MYSQL *mysql);
@ -49,6 +51,8 @@ bool MySqlSession::Connect(const char *user, const char *password, const char *d
sEmpNull(socket), 0)) {
Sql sql(*this);
username = sql.Select("substring_index(USER(),'@',1)");
sql.Execute("SET NAMES 'utf8'");
sql.Execute("SET CHARACTER SET utf8");
return true;
}
Close();
@ -182,23 +186,29 @@ MySqlConnection::MySqlConnection(MySqlSession& session, MYSQL *mysql)
lastid = 0;
}
String MySqlConnection::EscapeString(const String& v)
{
StringBuffer b(v.GetLength() * 2 + 3);
char *q = b;
*q = '\"';
int n = mysql_real_escape_string(mysql, q + 1, v, v.GetLength());
q[1 + n] = '\"';
b.SetCount(2 + n); //TODO - check this fix
return b;
}
void MySqlConnection::SetParam(int i, const Value& r) {
String p;
if(IsNull(r))
p = "NULL";
else
switch(r.GetType()) {
case 34:
p = EscapeString(SqlRaw(r));
break;
case WSTRING_V:
case STRING_V: {
String v = r;
StringBuffer b(v.GetLength() * 2 + 3);
char *q = b;
*q = '\"';
int n = mysql_real_escape_string(mysql, q + 1, v, v.GetLength());
q[1 + n] = '\"';
b.SetCount(2 + n); //TODO - check this fix
p = b;
}
case STRING_V:
p = EscapeString(ToCharset(CHARSET_UTF8, r));
break;
case BOOL_V:
case INT_V:
@ -257,6 +267,7 @@ bool MySqlConnection::Execute() {
rows = (int)mysql_affected_rows(mysql);
int fields = mysql_num_fields(result);
info.SetCount(fields);
convert.Alloc(fields, false);
for(int i = 0; i < fields; i++) {
MYSQL_FIELD *field = mysql_fetch_field_direct(result, i);
SqlColumnInfo& f = info[i];
@ -280,8 +291,12 @@ bool MySqlConnection::Execute() {
case FIELD_TYPE_DATETIME:
f.type = TIME_V;
break;
case FIELD_TYPE_VAR_STRING:
case FIELD_TYPE_STRING:
convert[i] = true;
default:
f.type = STRING_V;
break;
}
f.width = field->length;
f.scale = f.precision = 0;
@ -361,7 +376,10 @@ void MySqlConnection::GetColumn(int i, Ref f) const {
}
break;
default:
f = Value(String(s, len[i]));
if(convert[i])
f = Value(ToCharset(CHARSET_DEFAULT, String(s, len[i]), CHARSET_UTF8));
else
f = Value(String(s, len[i]));
break;
}
}

View file

@ -47,7 +47,7 @@ String ExportSch(SqlSession& session, const String& database)
break;
}
r << '\t' << sPutId(type, id, c[i].name, 8);
if(width > 0 && width < 4000)
if(width > 0 && width < 40000)
r << ", " << width;
r << ")\r\n";
}
@ -61,4 +61,35 @@ String ExportSch(const String& database)
return ExportSch(SQL.GetSession(), database);
}
static void sId(String& r, const String& id, Index<String>& done)
{
String u = ToUpper(id);
if(done.Find(u) >= 0)
return;
done.Add(u);
if(u == id)
r << "SQLID(" << id << ")\r\n";
else
r << "SQL_ID(" << u << ", " << id << ")\r\n";
}
String ExportIds(SqlSession& session, const String& database)
{
String r;
Vector<String> tab = session.EnumTables(database);
Index<String> done;
for(int i = 0; i < tab.GetCount(); i++) {
sId(r, tab[i], done);
Vector<SqlColumnInfo> c = session.EnumColumns(database, tab[i]);
for(int i = 0; i < c.GetCount(); i++)
sId(r, c[i].name, done);
}
return r;
}
String ExportIds(const String& database)
{
return ExportIds(SQL.GetSession(), database);
}
END_UPP_NAMESPACE

View file

@ -110,3 +110,5 @@ inline void SqlSchemaClear(T *a, int n) {
String ExportSch(SqlSession& session, const String& database);
String ExportSch(const String& database);
String ExportIds(SqlSession& session, const String& database);
String ExportIds(const String& database);

View file

@ -109,13 +109,14 @@ public:
SqlId operator [] (int i) const;
SqlId operator&(const SqlId& s) const;
SqlId() {}
SqlId(const char *s) : id(s) {}
SqlId(const String& s) : id(s) {}
SqlId(Id id) : id(id) {}
SqlId() {}
SqlId(const char *s) : id(s) {}
SqlId(const String& s) : id(s) {}
SqlId(Id id) : id(id) {}
};
#define SQLID(x) const UPP::SqlId x(#x);
#define SQLID(x) const UPP::SqlId x(#x);
#define SQL_ID(n, x) const UPP::SqlId n(#x);
class SqlS : Moveable<SqlS> {
protected: