libtabula

Check-in [28f9d01b73]
Login

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

Overview
Comment:The std::type_info to FieldType mapping mechanism was purposely self-limiting itself to looking up "best guess" entries only, on the theory that since moving from MySQL C API data type enums to libtabula generic type enums we lost the uniquenss of the {FieldType::Base, FieldType::Flags} pair, that we should only look through the subset that has unique pairs. However, that logic only works when mapping from libtabula values *to* C++ data types, not the other way around, since all of the C++ type_info values in that table *are* unique.

Therefore, removed the check on the new "best guess" flag in FieldType::TypeMap::operator[] since it isn't helping us. Maybe we will use this flag later, if we add the reverse mapping; or, maybe we'll remove it on YAGNI grounds.

Timelines: family | ancestors | descendants | both | mysql-type-info
Files: files | file ages | folders
SHA1: 28f9d01b73f49fa79aae90ec8d27bd275f85aeb3
User & Date: etr 2015-08-11 11:40:13
Context
2015-08-12
02:19
Refactored the FieldType implementation details to reduce the amount of code duplication between the base type and the old TypeInfo class, greatly increasing the clarity of the code. This version is gives the same semi-broken test results as the previous checkin on this branch, so it's a good refactoring. :) check-in: c78d403f45 user: etr tags: mysql-type-info
2015-08-11
11:40
The std::type_info to FieldType mapping mechanism was purposely self-limiting itself to looking up "best guess" entries only, on the theory that since moving from MySQL C API data type enums to libtabula generic type enums we lost the uniquenss of the {FieldType::Base, FieldType::Flags} pair, that we should only look through the subset that has unique pairs. However, that logic only works when mapping from libtabula values *to* C++ data types, not the other way around, since all of the C++ type_info values in that table *are* unique.

Therefore, removed the check on the new "best guess" flag in FieldType::TypeMap::operator[] since it isn't helping us. Maybe we will use this flag later, if we add the reverse mapping; or, maybe we'll remove it on YAGNI grounds. check-in: 28f9d01b73 user: etr tags: mysql-type-info

03:32
Merged exrun OS X fixes in check-in: fb36fd8453 user: tangent tags: mysql-type-info
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/field_type.cpp.

182
183
184
185
186
187
188
189
190
191
















192
193
194
195
196
197
198

#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








<
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







182
183
184
185
186
187
188

189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213

#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) {

		map_[FieldType::types_[i].c_type_] = i;
	}
}

FieldType::TypeMap::map_type::mapped_type 
FieldType::TypeMap::operator [](const std::type_info& ti) const
{
	// Try for an exact match on the C++ std::type
	map_type::const_iterator it = map_.find(&ti);
	if (it != map_.end()) {
		return it->second;
	}
	else {
		// Can't find it.  Caller must be passing a C++ data type that
		// simply isn't represented in the types_ array.  Wah.
		std::ostringstream outs;
		outs << "Failed to find libtabula type info for " << ti.name();
		throw TypeLookupFailed(outs.str());
	}
}

#endif // !defined(DOXYGEN_IGNORE)

} // end namespace libtabula

Changes to src/field_type.h.

177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
...
232
233
234
235
236
237
238


239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
...
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
	///
	/// Our return value may simply be the Base value we got in our
	/// ctor, but it could also be a conversion from another form,
	/// either C++ type info via our std::type_info ctor or C DBMS
	/// API type info from a subclass ctor.
	///
	/// This does not encode null-ness.
	///
	/// FIXME: Is this another YAGNI case?  Who calls it, and why?
	const Base base_type() const { return base_type_; }

	/// \brief Returns true if the SQL type is of a type that needs to
	/// be quoted for syntactically correct SQL.
	bool quote_q() const
	{
		return	base_type_ == ft_blob ||
................................................................................
		sql_name_(s),
		c_type_(&t),
		base_type_(bt),
		flags_(f),
		best_guess_(bg)
		{
		}



		bool is_default() const { return flags_ == FieldType::tf_default; }
		bool is_null() const { return flags_ & FieldType::tf_null; }
		bool is_unsigned() const { return flags_ & FieldType::tf_unsigned; }

		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
................................................................................

		struct Cmp
		{
			bool operator() (const std::type_info* lhs,
					const std::type_info* rhs) const
					{ return lhs < rhs; }
		};

		typedef std::map<const std::type_info*, size_t, Cmp> map_type;

		TypeMap();

		map_type::mapped_type operator [](const std::type_info& ti) const
		{
			map_type::const_iterator it = map_.find(&ti);
			if (it != map_.end()) {
				return it->second;
			}
			else {
				std::ostringstream outs;
				outs << "Failed to find libtabula type info for " << ti.name();
				throw TypeLookupFailed(outs.str());
			}
		}

		map_type map_;
	};

	// Data structures to map {Base, Type} pairs to and from libtabula
	// C++ data types.
	static const TypeInfo types_[];







<
<







 







>
>









|







 







<



<
|
<
<
<
<
<
<
<
<
<
<
<







177
178
179
180
181
182
183


184
185
186
187
188
189
190
...
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
...
266
267
268
269
270
271
272

273
274
275

276











277
278
279
280
281
282
283
	///
	/// Our return value may simply be the Base value we got in our
	/// ctor, but it could also be a conversion from another form,
	/// either C++ type info via our std::type_info ctor or C DBMS
	/// API type info from a subclass ctor.
	///
	/// This does not encode null-ness.


	const Base base_type() const { return base_type_; }

	/// \brief Returns true if the SQL type is of a type that needs to
	/// be quoted for syntactically correct SQL.
	bool quote_q() const
	{
		return	base_type_ == ft_blob ||
................................................................................
		sql_name_(s),
		c_type_(&t),
		base_type_(bt),
		flags_(f),
		best_guess_(bg)
		{
		}

		unsigned short id() const { return (flags_ << 8) | base_type_; }

		bool is_default() const { return flags_ == FieldType::tf_default; }
		bool is_null() const { return flags_ & FieldType::tf_null; }
		bool is_unsigned() const { return flags_ & FieldType::tf_unsigned; }

		const char* sql_name_;
		const std::type_info* c_type_;
		const Base base_type_;
		const unsigned int flags_;
		const bool best_guess_;		// YAGNI?  Unused by TypeMap::operator[]
	};

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

		struct Cmp
		{
			bool operator() (const std::type_info* lhs,
					const std::type_info* rhs) const
					{ return lhs < rhs; }
		};

		typedef std::map<const std::type_info*, size_t, Cmp> map_type;

		TypeMap();

		map_type::mapped_type operator [](const std::type_info& ti) const;












		map_type map_;
	};

	// Data structures to map {Base, Type} pairs to and from libtabula
	// C++ data types.
	static const TypeInfo types_[];