libtabula

Check-in [3ea24ed240]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Fixed several problems in the new FieldType mechanism, found now that we're actually trying to build it. :)
Timelines: family | ancestors | descendants | both | mysql-type-info
Files: files | file ages | folders
SHA1: 3ea24ed24022f3533dd3e04c2466e344468c8d1f
User & Date: tangent 2015-08-08 07:26:04
Context
2015-08-08
07:30
Fixed some more mysql_type_info stuff check-in: 4d92d34d84 user: tangent tags: mysql-type-info
07:26
Fixed several problems in the new FieldType mechanism, found now that we're actually trying to build it. :) check-in: 3ea24ed240 user: tangent tags: mysql-type-info
06:35
Added missing field_type.cpp check-in: d2ae8f5377 user: etr tags: mysql-type-info
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/field_type.cpp.

58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
// where there may be multiple sizes.  We use the largest "native" size.
// 
// This table does not necessarily honor fine type distinctions made at
// the DBMS layer.  For example, we paper over the UNSIGNED FLOAT mess.
//
// This table is inverted for reverse lookup as the static type_map_
// object.
typedef FieldType::MapEntry FTME;
const FTME FieldType::types_[] = {
	// Basic non-nullable type set
	FTME("TINYINT NOT NULL", typeid(sql_tinyint),
			FieldType::ft_integer, FieldType::tf_default, false),
	FTME("TINYINT UNSIGNED NOT NULL", typeid(sql_tinyint_unsigned),
			FieldType::ft_integer, FieldType::tf_unsigned, false),
	FTME("SMALLINT NOT NULL", typeid(sql_smallint),
			FieldType::ft_integer, FieldType::tf_default, false),
	FTME("SMALLINT UNSIGNED NOT NULL", typeid(sql_smallint_unsigned),
			FieldType::ft_integer, FieldType::tf_unsigned, false),
	FTME("MEDIUMINT NOT NULL", typeid(sql_mediumint),
			FieldType::ft_integer, FieldType::tf_unsigned, false),
	FTME("MEDIUMINT UNSIGNED NOT NULL", typeid(sql_mediumint_unsigned),
			FieldType::ft_integer, FieldType::tf_unsigned, false),
	FTME("INT NOT NULL", typeid(sql_int), FieldType::ft_integer),
	FTME("INT UNSIGNED NOT NULL", typeid(sql_int_unsigned),
			FieldType::ft_integer, FieldType::tf_unsigned),
	FTME("BIGINT NOT NULL", typeid(sql_bigint), 
			FieldType::ft_integer, FieldType::tf_default, false),
	FTME("BIGINT UNSIGNED NOT NULL", typeid(sql_bigint_unsigned),
			FieldType::ft_integer, FieldType::tf_unsigned, false),
	FTME("FLOAT NOT NULL", typeid(sql_float), 
			FieldType::ft_real, FieldType::tf_default, false),
	FTME("FLOAT UNSIGNED NOT NULL", typeid(sql_float),
			FieldType::ft_real, FieldType::tf_unsigned, false),
	FTME("DOUBLE NOT NULL", typeid(sql_double), FieldType::ft_real),
	FTME("DOUBLE UNSIGNED NOT NULL", typeid(sql_double),
			FieldType::ft_real, FieldType::tf_unsigned),
	FTME("DECIMAL NOT NULL", typeid(sql_decimal), FieldType::ft_decimal),
	FTME("TIMESTAMP NOT NULL", typeid(sql_timestamp), FieldType::ft_timestamp),
	FTME("DATE NOT NULL", typeid(sql_date), FieldType::ft_date),
	FTME("TIME NOT NULL", typeid(sql_time), FieldType::ft_time),
	FTME("DATETIME NOT NULL", typeid(sql_datetime), FieldType::ft_datetime),
	FTME("ENUM NOT NULL", typeid(sql_enum), FieldType::ft_enum),
	FTME("SET NOT NULL", typeid(sql_set), FieldType::ft_set),
	FTME("TINYBLOB NOT NULL", typeid(sql_tinyblob),
			FieldType::ft_blob, FieldType::tf_default, false),
	FTME("MEDIUMBLOB NOT NULL", typeid(sql_mediumblob), 
			FieldType::ft_blob, FieldType::tf_default, false),
	FTME("LONGBLOB NOT NULL", typeid(sql_longblob),
			FieldType::ft_blob, FieldType::tf_default, false),
	FTME("BLOB NOT NULL", typeid(sql_blob), FieldType::ft_blob),
	FTME("VARCHAR NOT NULL", typeid(sql_varchar), FieldType::ft_string),
	FTME("CHAR NOT NULL", typeid(sql_char), 
			FieldType::ft_string, FieldType::tf_default, false),

	// Nullable versions of above
	FTME("TINYINT NULL", typeid(Null<sql_tinyint>),
			FieldType::ft_integer, FieldType::tf_null, false),
	FTME("TINYINT UNSIGNED NULL", typeid(Null<sql_tinyint_unsigned>),
			FieldType::ft_integer,
			FieldType::tf_null | FieldType::tf_unsigned, false),
	FTME("SMALLINT NULL", typeid(Null<sql_smallint>),
			FieldType::ft_integer, FieldType::tf_null, false),
	FTME("SMALLINT UNSIGNED NULL", typeid(Null<sql_smallint_unsigned>),
			FieldType::ft_integer,
			FieldType::tf_null | FieldType::tf_unsigned, false),
	FTME("MEDIUMINT NULL", typeid(Null<sql_mediumint>),
			FieldType::ft_integer, FieldType::tf_null, false),
	FTME("MEDIUMINT UNSIGNED NULL", typeid(Null<sql_mediumint_unsigned>), 
			FieldType::ft_integer,
			FieldType::tf_null | FieldType::tf_unsigned, false),
	FTME("INT NULL", typeid(Null<sql_int>),
			FieldType::ft_integer, FieldType::tf_null),
	FTME("INT UNSIGNED NULL", typeid(Null<sql_int_unsigned>),
			FieldType::ft_integer, FieldType::tf_null | FieldType::tf_unsigned),
	FTME("BIGINT NULL", typeid(Null<sql_bigint>),
			FieldType::ft_integer, FieldType::tf_null, false),
	FTME("BIGINT UNSIGNED NULL", typeid(Null<sql_bigint_unsigned>),
			FieldType::ft_integer,
			FieldType::tf_null | FieldType::tf_unsigned, false),
	FTME("FLOAT NULL", typeid(Null<sql_float>),
			FieldType::ft_real, FieldType::tf_null, false),
	FTME("FLOAT UNSIGNED NULL", typeid(Null<sql_float>),
			FieldType::ft_real,
			FieldType::tf_null | FieldType::tf_unsigned, false),
	FTME("DOUBLE NULL", typeid(Null<sql_double>),
			FieldType::ft_real, FieldType::tf_null),
	FTME("DOUBLE UNSIGNED NULL", typeid(Null<sql_double>),
			FieldType::ft_real, FieldType::tf_null | FieldType::tf_unsigned),
	FTME("DECIMAL NULL", typeid(Null<sql_decimal>),
			FieldType::ft_decimal, FieldType::tf_null),
	FTME("TIMESTAMP NULL", typeid(Null<sql_timestamp>),
			FieldType::ft_timestamp),
	FTME("DATE NULL", typeid(Null<sql_date>),
			FieldType::ft_date, FieldType::tf_null),
	FTME("TIME NULL", typeid(Null<sql_time>),
			FieldType::ft_time, FieldType::tf_null),
	FTME("DATETIME NULL", typeid(Null<sql_datetime>),
			FieldType::ft_datetime, FieldType::tf_null),
	FTME("ENUM NULL", typeid(Null<sql_enum>),
			FieldType::ft_enum, FieldType::tf_null),
	FTME("SET NULL", typeid(Null<sql_set>),
			FieldType::ft_set, FieldType::tf_null),
	FTME("TINYBLOB NULL", typeid(Null<sql_tinyblob>),
			FieldType::ft_blob, FieldType::tf_null, false),
	FTME("MEDIUMBLOB NULL", typeid(Null<sql_mediumblob>),
			FieldType::ft_blob, FieldType::tf_null, false),
	FTME("LONGBLOB NULL", typeid(Null<sql_longblob>),
			FieldType::ft_blob, FieldType::tf_null, false),
	FTME("BLOB NULL", typeid(Null<sql_blob>),
			FieldType::ft_blob, FieldType::tf_null),
	FTME("VARCHAR NULL", typeid(Null<sql_varchar>),
			FieldType::ft_string, FieldType::tf_null),
	FTME("CHAR NULL", typeid(Null<sql_char>),
			FieldType::ft_string, FieldType::tf_null, false)
};

const int FieldType::num_types_ =
		sizeof(FieldType::types) / sizeof(FieldType::types[0]);

const FieldType::TypeMap FieldType::type_map_;

#if !defined(DOXYGEN_IGNORE)
// Doxygen will not generate documentation for this section.

TypeMap::TypeMap()
{
	for (map_type::mapped_type i = 0; i < num_types_; ++i) {
		if (FieldType::types[i].best_guess_) {
			map_[FieldType::types[i].c_type_] = i;
		}
	}
}

#endif // !defined(DOXYGEN_IGNORE)

} // end namespace libtabula








|
|

|

|

|

|

|

|

|
|

|

|

|

|

|
|

|
|
|
|
|
|
|
|

|

|

|
|
|
|


|

|


|

|


|

|


|

|

|

|


|

|


|

|

|

|

|

|

|

|

|

|

|

|

|

|
|
|
|



|






|


|
|








58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
// where there may be multiple sizes.  We use the largest "native" size.
// 
// This table does not necessarily honor fine type distinctions made at
// the DBMS layer.  For example, we paper over the UNSIGNED FLOAT mess.
//
// This table is inverted for reverse lookup as the static type_map_
// object.
typedef FieldType::TypeInfo FTTI;
const FTTI FieldType::types_[] = {
	// Basic non-nullable type set
	FTTI("TINYINT NOT NULL", typeid(sql_tinyint),
			FieldType::ft_integer, FieldType::tf_default, false),
	FTTI("TINYINT UNSIGNED NOT NULL", typeid(sql_tinyint_unsigned),
			FieldType::ft_integer, FieldType::tf_unsigned, false),
	FTTI("SMALLINT NOT NULL", typeid(sql_smallint),
			FieldType::ft_integer, FieldType::tf_default, false),
	FTTI("SMALLINT UNSIGNED NOT NULL", typeid(sql_smallint_unsigned),
			FieldType::ft_integer, FieldType::tf_unsigned, false),
	FTTI("MEDIUMINT NOT NULL", typeid(sql_mediumint),
			FieldType::ft_integer, FieldType::tf_unsigned, false),
	FTTI("MEDIUMINT UNSIGNED NOT NULL", typeid(sql_mediumint_unsigned),
			FieldType::ft_integer, FieldType::tf_unsigned, false),
	FTTI("INT NOT NULL", typeid(sql_int), FieldType::ft_integer),
	FTTI("INT UNSIGNED NOT NULL", typeid(sql_int_unsigned),
			FieldType::ft_integer, FieldType::tf_unsigned),
	FTTI("BIGINT NOT NULL", typeid(sql_bigint), 
			FieldType::ft_integer, FieldType::tf_default, false),
	FTTI("BIGINT UNSIGNED NOT NULL", typeid(sql_bigint_unsigned),
			FieldType::ft_integer, FieldType::tf_unsigned, false),
	FTTI("FLOAT NOT NULL", typeid(sql_float), 
			FieldType::ft_real, FieldType::tf_default, false),
	FTTI("FLOAT UNSIGNED NOT NULL", typeid(sql_float),
			FieldType::ft_real, FieldType::tf_unsigned, false),
	FTTI("DOUBLE NOT NULL", typeid(sql_double), FieldType::ft_real),
	FTTI("DOUBLE UNSIGNED NOT NULL", typeid(sql_double),
			FieldType::ft_real, FieldType::tf_unsigned),
	FTTI("DECIMAL NOT NULL", typeid(sql_decimal), FieldType::ft_decimal),
	FTTI("TIMESTAMP NOT NULL", typeid(sql_timestamp), FieldType::ft_timestamp),
	FTTI("DATE NOT NULL", typeid(sql_date), FieldType::ft_date),
	FTTI("TIME NOT NULL", typeid(sql_time), FieldType::ft_time),
	FTTI("DATETIME NOT NULL", typeid(sql_datetime), FieldType::ft_datetime),
	FTTI("ENUM NOT NULL", typeid(sql_enum), FieldType::ft_enum),
	FTTI("SET NOT NULL", typeid(sql_set), FieldType::ft_set),
	FTTI("TINYBLOB NOT NULL", typeid(sql_tinyblob),
			FieldType::ft_blob, FieldType::tf_default, false),
	FTTI("MEDIUMBLOB NOT NULL", typeid(sql_mediumblob), 
			FieldType::ft_blob, FieldType::tf_default, false),
	FTTI("LONGBLOB NOT NULL", typeid(sql_longblob),
			FieldType::ft_blob, FieldType::tf_default, false),
	FTTI("BLOB NOT NULL", typeid(sql_blob), FieldType::ft_blob),
	FTTI("VARCHAR NOT NULL", typeid(sql_varchar), FieldType::ft_text),
	FTTI("CHAR NOT NULL", typeid(sql_char), 
			FieldType::ft_text, FieldType::tf_default, false),

	// Nullable versions of above
	FTTI("TINYINT NULL", typeid(Null<sql_tinyint>),
			FieldType::ft_integer, FieldType::tf_null, false),
	FTTI("TINYINT UNSIGNED NULL", typeid(Null<sql_tinyint_unsigned>),
			FieldType::ft_integer,
			FieldType::tf_null | FieldType::tf_unsigned, false),
	FTTI("SMALLINT NULL", typeid(Null<sql_smallint>),
			FieldType::ft_integer, FieldType::tf_null, false),
	FTTI("SMALLINT UNSIGNED NULL", typeid(Null<sql_smallint_unsigned>),
			FieldType::ft_integer,
			FieldType::tf_null | FieldType::tf_unsigned, false),
	FTTI("MEDIUMINT NULL", typeid(Null<sql_mediumint>),
			FieldType::ft_integer, FieldType::tf_null, false),
	FTTI("MEDIUMINT UNSIGNED NULL", typeid(Null<sql_mediumint_unsigned>), 
			FieldType::ft_integer,
			FieldType::tf_null | FieldType::tf_unsigned, false),
	FTTI("INT NULL", typeid(Null<sql_int>),
			FieldType::ft_integer, FieldType::tf_null),
	FTTI("INT UNSIGNED NULL", typeid(Null<sql_int_unsigned>),
			FieldType::ft_integer, FieldType::tf_null | FieldType::tf_unsigned),
	FTTI("BIGINT NULL", typeid(Null<sql_bigint>),
			FieldType::ft_integer, FieldType::tf_null, false),
	FTTI("BIGINT UNSIGNED NULL", typeid(Null<sql_bigint_unsigned>),
			FieldType::ft_integer,
			FieldType::tf_null | FieldType::tf_unsigned, false),
	FTTI("FLOAT NULL", typeid(Null<sql_float>),
			FieldType::ft_real, FieldType::tf_null, false),
	FTTI("FLOAT UNSIGNED NULL", typeid(Null<sql_float>),
			FieldType::ft_real,
			FieldType::tf_null | FieldType::tf_unsigned, false),
	FTTI("DOUBLE NULL", typeid(Null<sql_double>),
			FieldType::ft_real, FieldType::tf_null),
	FTTI("DOUBLE UNSIGNED NULL", typeid(Null<sql_double>),
			FieldType::ft_real, FieldType::tf_null | FieldType::tf_unsigned),
	FTTI("DECIMAL NULL", typeid(Null<sql_decimal>),
			FieldType::ft_decimal, FieldType::tf_null),
	FTTI("TIMESTAMP NULL", typeid(Null<sql_timestamp>),
			FieldType::ft_timestamp),
	FTTI("DATE NULL", typeid(Null<sql_date>),
			FieldType::ft_date, FieldType::tf_null),
	FTTI("TIME NULL", typeid(Null<sql_time>),
			FieldType::ft_time, FieldType::tf_null),
	FTTI("DATETIME NULL", typeid(Null<sql_datetime>),
			FieldType::ft_datetime, FieldType::tf_null),
	FTTI("ENUM NULL", typeid(Null<sql_enum>),
			FieldType::ft_enum, FieldType::tf_null),
	FTTI("SET NULL", typeid(Null<sql_set>),
			FieldType::ft_set, FieldType::tf_null),
	FTTI("TINYBLOB NULL", typeid(Null<sql_tinyblob>),
			FieldType::ft_blob, FieldType::tf_null, false),
	FTTI("MEDIUMBLOB NULL", typeid(Null<sql_mediumblob>),
			FieldType::ft_blob, FieldType::tf_null, false),
	FTTI("LONGBLOB NULL", typeid(Null<sql_longblob>),
			FieldType::ft_blob, FieldType::tf_null, false),
	FTTI("BLOB NULL", typeid(Null<sql_blob>),
			FieldType::ft_blob, FieldType::tf_null),
	FTTI("VARCHAR NULL", typeid(Null<sql_varchar>),
			FieldType::ft_text, FieldType::tf_null),
	FTTI("CHAR NULL", typeid(Null<sql_char>),
			FieldType::ft_text, FieldType::tf_null, false)
};

const int FieldType::num_types_ =
		sizeof(FieldType::types_) / sizeof(FieldType::types_[0]);

const FieldType::TypeMap FieldType::type_map_;

#if !defined(DOXYGEN_IGNORE)
// Doxygen will not generate documentation for this section.

FieldType::TypeMap::TypeMap()
{
	for (map_type::mapped_type i = 0; i < num_types_; ++i) {
		if (FieldType::types_[i].best_guess_) {
			map_[FieldType::types_[i].c_type_] = i;
		}
	}
}

#endif // !defined(DOXYGEN_IGNORE)

} // end namespace libtabula

Changes to src/field_type.h.

212
213
214
215
216
217
218
219
220
221
222
223
224




225
226
227
228
229
230
231
232
233
234
235
236
237
238
...
245
246
247
248
249
250
251


252
253
254
255
256
257
258
	/// \brief Return an opaque composite value that uniquely identifies
	/// this field type.
	///
	/// Though the implementation is right here to be examined, do not
	/// depend on the format of the value.  It could change.
	unsigned short id() const { return (flags_ << 8) | base_type_; }

protected:
	//// Subclass interface
	// Used in the global static data structures that map libtabula data
	// types and from {Base, Flag} enum pairs.  That in turn is how
	// you can construct a FieldType object and call c_type() and such
	// on it, yielding a value you did not explicitly pass to the ctor.




	class TypeInfo
	{
	public:
		TypeInfo& operator=(const TypeInfo& other);
		
		TypeInfo(const char* s = 0, const std::type_info& t = typeid(void),
				Base bt = ft_unsupported, Flag f = tf_default,
				bool bg = true) :
		sql_name_(s),
		c_type_(&t),
		base_type_(bt),
		flags_(f),
		best_guess_(bg)
		{
................................................................................
		const char* sql_name_;
		const std::type_info* c_type_;
		const Base base_type_;
		const unsigned int flags_;
		const bool best_guess_;
	};



	/// \brief Look up the TypeInfo object corresponding to our
	/// {Base, Flag} pair.
	const TypeInfo& type_info() const
	{
		return types_[base_type_];
	}








<
<




>
>
>
>






|







 







>
>







212
213
214
215
216
217
218


219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
...
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
	/// \brief Return an opaque composite value that uniquely identifies
	/// this field type.
	///
	/// Though the implementation is right here to be examined, do not
	/// depend on the format of the value.  It could change.
	unsigned short id() const { return (flags_ << 8) | base_type_; }



	// Used in the global static data structures that map libtabula data
	// types and from {Base, Flag} enum pairs.  That in turn is how
	// you can construct a FieldType object and call c_type() and such
	// on it, yielding a value you did not explicitly pass to the ctor.
	//
	// \internal This is public only because the cpp file instantiates
	// \c types_, a static array of these.  Library end-user code
	// shouldn't use this directly.
	class TypeInfo
	{
	public:
		TypeInfo& operator=(const TypeInfo& other);
		
		TypeInfo(const char* s = 0, const std::type_info& t = typeid(void),
				Base bt = ft_unsupported, unsigned int f = tf_default,
				bool bg = true) :
		sql_name_(s),
		c_type_(&t),
		base_type_(bt),
		flags_(f),
		best_guess_(bg)
		{
................................................................................
		const char* sql_name_;
		const std::type_info* c_type_;
		const Base base_type_;
		const unsigned int flags_;
		const bool best_guess_;
	};

protected:
	//// Subclass interface
	/// \brief Look up the TypeInfo object corresponding to our
	/// {Base, Flag} pair.
	const TypeInfo& type_info() const
	{
		return types_[base_type_];
	}