diff --git a/uppsrc/Sql/S_info.cpp b/uppsrc/Sql/S_info.cpp index ea331d5d3..1243c349c 100644 --- a/uppsrc/Sql/S_info.cpp +++ b/uppsrc/Sql/S_info.cpp @@ -5,12 +5,26 @@ NAMESPACE_UPP void S_info_maker::Field(const char *name, Ref f, bool *b) { if(b) f = Ref(*b); - info.column.Add(name, MakeTuple((byte *)f.GetVoidPtr() - (byte *)s, f.GetManager())); + S_info::Column& c = info.column.Add(name); + c.offset = (byte *)f.GetVoidPtr() - (byte *)s; + c.manager = f.GetManager(); + c.width = 0; +} + +void S_info_maker::Width(int width) +{ + info.column.Top().width = width; } Ref S_info::GetRef(const void *s, int i) const { - return Ref((byte *)s + column[i].a, column[i].b); + return Ref((byte *)s + column[i].offset, column[i].manager); +} + +int S_info::GetWidth(const SqlId& id) const +{ + int q = column.Find(~id); + return q >= 0 ? GetWidth(q) : 0; } Ref S_info::GetRef(const void *s, const SqlId& id) const diff --git a/uppsrc/Sql/Sql.cpp b/uppsrc/Sql/Sql.cpp index 0c4594340..d032012d5 100644 --- a/uppsrc/Sql/Sql.cpp +++ b/uppsrc/Sql/Sql.cpp @@ -26,6 +26,9 @@ void FieldOperator::Field(const char *name, Ref f) { Field(f); } void FieldOperator::Field(const char *name, Ref f, bool *b) { Field(name, f); } +void FieldOperator::Width(int width) {} + + FieldOperator& FieldOperator::operator()(const char *name, bool& b) { String x = BoolToSql(b); Field(name, x, &b); diff --git a/uppsrc/Sql/SqlSchema.h b/uppsrc/Sql/SqlSchema.h index 86f8c82d3..d3f255fd1 100644 --- a/uppsrc/Sql/SqlSchema.h +++ b/uppsrc/Sql/SqlSchema.h @@ -132,13 +132,22 @@ String ExportIds(const String& database); #endif struct S_info { - VectorMap< String, Tuple2 > column; + struct Column : Moveable { + intptr_t offset; + RefManager *manager; + int width; + }; + VectorMap column; SqlSet set; Vector ids; - SqlId GetId(int i) const { return column.GetKey(i); } int GetCount() const { return column.GetCount(); } + SqlId GetId(int i) const { return column.GetKey(i); } + + int GetWidth(int i) const { return column[i].width; } + int GetWidth(const SqlId& id) const; + Ref GetRef(const void *s, int i) const; Ref GetRef(const void *s, const SqlId& id) const; Value Get(const void *s, const SqlId& id) const; @@ -160,7 +169,8 @@ struct S_info_maker : FieldOperator { void *s; virtual void Field(const char *name, Ref f, bool *b); - + virtual void Width(int width); + S_info_maker(S_info& f, void *s) : info(f), s(s) {} }; @@ -184,6 +194,8 @@ struct S_type { int GetCount() const; SqlId GetId(int i) const; + int GetWidth(int i) const; + int GetWidth(const SqlId& id) const; Ref GetRef(int i); Ref GetRef(const SqlId& id); Value Get(const SqlId& id) const; diff --git a/uppsrc/Sql/Sqlexp.h b/uppsrc/Sql/Sqlexp.h index 6dd361633..2554a5d0f 100644 --- a/uppsrc/Sql/Sqlexp.h +++ b/uppsrc/Sql/Sqlexp.h @@ -31,6 +31,8 @@ struct FieldOperator { FieldOperator& operator()(const char *name, bool& b); FieldOperator& operator()(const String& name, bool& b) { return (*this)(~name, b); } FieldOperator& operator()(Id id, bool& b) { return (*this)(~id, b); } + + virtual void Width(int width); // Only to be used for S_info FieldOperator(); virtual ~FieldOperator(); diff --git a/uppsrc/Sql/sch_header.h b/uppsrc/Sql/sch_header.h index 57cdd6af3..187164da4 100644 --- a/uppsrc/Sql/sch_header.h +++ b/uppsrc/Sql/sch_header.h @@ -23,6 +23,8 @@ public: \ String ToString() const { return AsString((Fields)const_cast(*this)); } \ int GetCount() const { return info->GetCount(); } \ SqlId GetId(int i) const { return info->GetId(i); } \ + int GetWidth(int i) const { return info->GetWidth(i); } \ + int GetWidth(const SqlId& id) const { return info->GetWidth(id); } \ Ref GetRef(int i) { return info->GetRef(this, i); } \ Ref GetRef(const SqlId& id) { return info->GetRef(this, id); } \ Value Get(const SqlId& id) const { return info->Get(this, id); } \ diff --git a/uppsrc/Sql/sch_source.h b/uppsrc/Sql/sch_source.h index 12501846d..d762ef573 100644 --- a/uppsrc/Sql/sch_source.h +++ b/uppsrc/Sql/sch_source.h @@ -91,11 +91,11 @@ void S_##x::FieldLayoutRaw(FieldOperator& fo, const String& prefix) {\ S_##b2::FieldLayoutRaw(fo, prefix);\ S_##b3::FieldLayoutRaw(fo, prefix); -#define COLUMN(type, ctype, name, width, prec) fo(prefix + #name, ADD_SCHEMA_PREFIX_CPP(name)); +#define COLUMN(type, ctype, name, width, prec) fo(prefix + #name, ADD_SCHEMA_PREFIX_CPP(name)), fo.Width(width); #define COLUMN_ARRAY(type, ctype, name, width, prec, items) \ { \ for(int i = 0; i < items; i++)\ - fo(Format("%s%s%d", ~prefix, #name, i), ADD_SCHEMA_PREFIX_CPP(name)[i]); \ + fo(Format("%s%s%d", ~prefix, #name, i), ADD_SCHEMA_PREFIX_CPP(name)[i]), fo.Width(width); \ } #define VAR(type, x) x.FieldLayoutRaw(fo, prefix + #x + "$"); diff --git a/uppsrc/Sql/src.tpp/S_type$en-us.tpp b/uppsrc/Sql/src.tpp/S_type$en-us.tpp index bc07b8d96..3c348fb89 100644 --- a/uppsrc/Sql/src.tpp/S_type$en-us.tpp +++ b/uppsrc/Sql/src.tpp/S_type$en-us.tpp @@ -94,6 +94,18 @@ purposes.&] onst]&] [s2; Returns a column ID for column at [%-*@3 i].&] [s3; &] +[s4;%- &] +[s5;:S`_type`:`:GetWidth`(int`)const:%- [@(0.0.255) int]_[* GetWidth]([@(0.0.255) int]_[*@3 i +])_[@(0.0.255) const]&] +[s2; Returns the width of column (usually text) as defined in the +schema. If column does not have width, returns 0.&] +[s3; &] +[s4;%- &] +[s5;:S`_type`:`:GetWidth`(const SqlId`&`)const:%- [@(0.0.255) int]_[* GetWidth]([@(0.0.255) c +onst]_[_^SqlId^ SqlId][@(0.0.255) `&]_[*@3 id])_[@(0.0.255) const]&] +[s2; Returns the width of column (usually text) as defined in the +schema.If [%-*@3 id] is not in S`_[/ type], returns 0.&] +[s3; &] [s4; &] [s5;:S`_type`:`:GetRef`(int`):%- [_^Ref^ Ref]_[* GetRef]([@(0.0.255) int]_[*@3 i])&] [s2; Returns a reference to column at [%-*@3 i].&] diff --git a/uppsrc/plugin/sqlite3/Sqlite3Schema.h b/uppsrc/plugin/sqlite3/Sqlite3Schema.h index 0a6d8f8eb..6032af63f 100644 --- a/uppsrc/plugin/sqlite3/Sqlite3Schema.h +++ b/uppsrc/plugin/sqlite3/Sqlite3Schema.h @@ -13,10 +13,10 @@ #define DOUBLE_(x) COLUMN_("real", double, x, 0, 0) #define DOUBLE_ARRAY_(x, items) COLUMN_ARRAY_("real", double, x, 0, 0, items) -#define STRING(x, n) COLUMN("text", String, x, 0, 0) -#define STRING_ARRAY(x, n, items) COLUMN_ARRAY("text", String, x, 0, 0, items) -#define STRING_(x, n) COLUMN_("text", String, x, 0, 0) -#define STRING_ARRAY_(x, n, items) COLUMN_ARRAY_("text", String, x, 0, 0, items) +#define STRING(x, n) COLUMN("text", String, x, n, 0) +#define STRING_ARRAY(x, n, items) COLUMN_ARRAY("text", String, x, n, 0, items) +#define STRING_(x, n) COLUMN_("text", String, x, n, 0) +#define STRING_ARRAY_(x, n, items) COLUMN_ARRAY_("text", String, x, n, 0, items) #define DATE(x) COLUMN("date", Date, x, 0, 0) #define DATE_ARRAY(x, items) COLUMN_ARRAY("date", Date, x, 0, 0, items)