List:MySQL++« Previous MessageNext Message »
From:Warren Young Date:April 5 2005 5:13pm
Subject:RFC: Row::operator[] change
View as plain text  
I'm thinking I might have made a design mistake in the name of 
expediency back in v1.7.10 when I fixed the operator[] overloading 
problem.

For those who don't remember the "what and why" of it, the problem was 
that Row::operator[] was overloaded for several types of integer, for 
const char*, and I think even std::string.  Since 0 can be converted to 
any of those types implicitly, GCC 3 rightly refused to compile any code 
saying something like this:

	Row r;
	cout << r[0] << ....

GCC also gave ambiguous overload errors for code like this:

	cout << r["fred"] ...

since "fred" is a pointer, and thus is convertible to an integer.

So, I removed all but operator[](size_type), added 
Row::lookup_by_name(const char*) to handle the string cases, and called 
it good.

But recently, it came to me that the integer overloads were probably the 
least useful of the bunch in real-world code.  Intelligent database 
design doesn't make the client code dependent on the number or order of 
database columns.  So, I wonder if it would have been better to keep 
operator[](const char*) instead.

Obviously I can't change it back until v1.8 or v2.0.  Keeping that in 
mind, my question is, who would it bother if I changed these semantics? 
  Who uses integer indexes into a Row object in real-world code?

I sure don't, but then, I use the SSQLS mechanism, and it hides the Row 
access within its internals.  Several of the examples use 
Row::operator[](int), but they probably shouldn't, for the intelligent 
design reason I gave above.

I've attached a diff of the change you'd need to make to get the library 
itself and the examples to compile.  Notice that class Row can no longer 
derive from the template const_subscript_container, since that demands 
that the subclass implement operator[](size_type).  That's no doubt why 
I chose to keep the overload that I did.  It's not a very good reason, 
but there it is.

I'd appreciate it if some of you would try this patch, and see how it 
affects your code.  That will help me to decide if this item even makes 
it onto the Wishlist.  Also, it would be nice to know what other items 
from template const_subscript_container we need to hoist up in to class 
Row in order to make real-world code continue to compile.  I just 
hack-and-slashed it for this proof of concept.

Index: examples/complic1.cpp
===================================================================
RCS file: /usr/local/cvs/mysql++/examples/complic1.cpp,v
retrieving revision 1.2
diff -u -r1.2 complic1.cpp
--- examples/complic1.cpp	1 Mar 2005 03:48:40 -0000	1.2
+++ examples/complic1.cpp	5 Apr 2005 17:04:12 -0000
@@ -43,13 +43,13 @@
 			// there is a problem in the conversion it will throw an
 			// exception (caught below).  To test it, try changing the
 			// row[2] to row[0] below.
-			cout << setw(17) << row.lookup_by_name("ITEM") <<
-					setw(4) << row[1] <<
-					setw(7) << double(row[2]) <<
-					setw(7) << double(row[3]);
+			cout << setw(17) << row["ITEM"] <<
+					setw(4) << row.col_num(1) <<
+					setw(7) << double(row.col_num(2)) <<
+					setw(7) << double(row.col_num(3));
 
 			// The ColData is implicitly converted to a date here.
-			Date date = row.lookup_by_name("SDATE");
+			Date date = row["SDATE"];
 			cout.setf(ios::right);
 			cout.fill('0');
 			cout << setw(2) << date.month << "-" << setw(2) <<
Index: examples/dbinfo.cpp
===================================================================
RCS file: /usr/local/cvs/mysql++/examples/dbinfo.cpp,v
retrieving revision 1.2
diff -u -r1.2 dbinfo.cpp
--- examples/dbinfo.cpp	1 Mar 2005 03:48:40 -0000	1.2
+++ examples/dbinfo.cpp	5 Apr 2005 17:04:12 -0000
@@ -106,7 +106,7 @@
 				for (counter = 0; counter < columns; counter++) {
 					if (widths[counter]) {
 						cout << ' ' << setw(widths[counter]) <<
-								row[counter] << ' ';
+								row.col_num(counter) << ' ';
 					}
 				}
 				cout << endl;
@@ -130,7 +130,7 @@
 		for (i = res.begin(); i != res.end(); ++i) {
 			row = *i;
 			for (int counter = 0; counter < columns; counter++) {
-				cout << row[counter] << "  ";
+				cout << row.col_num(counter) << "  ";
 			}
 			cout << endl;
 		}
Index: examples/util.cpp
===================================================================
RCS file: /usr/local/cvs/mysql++/examples/util.cpp,v
retrieving revision 1.4
diff -u -r1.4 util.cpp
--- examples/util.cpp	11 Mar 2005 06:08:27 -0000	1.4
+++ examples/util.cpp	5 Apr 2005 17:04:12 -0000
@@ -42,11 +42,11 @@
 
 		// Note that you can use either the column index or name to
 		// retrieve the data.
-		cout << setw(20) << row[0].c_str() << ' ' <<
-				setw(9) << row[1].c_str() << ' ' <<
-				setw(9) << row.lookup_by_name("weight").c_str() << ' ' <<
-				setw(9) << row[3].c_str() << ' ' <<
-				row[4] << endl;
+		cout << setw(20) << row.col_num(0).c_str() << ' ' <<
+				setw(9) << row.col_num(1).c_str() << ' ' <<
+				setw(9) << row["weight"].c_str() << ' ' <<
+				setw(9) << row.col_num(3).c_str() << ' ' <<
+				row.col_num(4) << endl;
 	}
 }
 
Index: lib/custom.pl
===================================================================
RCS file: /usr/local/cvs/mysql++/lib/custom.pl,v
retrieving revision 1.14
diff -u -r1.14 custom.pl
--- lib/custom.pl	14 Feb 2005 17:36:32 -0000	1.14
+++ lib/custom.pl	5 Apr 2005 17:04:12 -0000
@@ -221,7 +221,7 @@
 	$parm_simple2c_b .= ", " unless $j == $i;
 	$defs  .= "    T$j I$j;";
 	$defs  .= "\n" unless $j == $i;
-	$popul .= "    s->I$j = static_cast<T$j>(row[ O$j ]);";
+	$popul .= "    s->I$j = static_cast<T$j>(row.col_num( O$j ));";
 	$popul .= "\n" unless $j == $i;
         $names .= "    N$j ";
 	$names .= ",\n" unless $j == $i;
Index: lib/row.cpp
===================================================================
RCS file: /usr/local/cvs/mysql++/lib/row.cpp,v
retrieving revision 1.4
diff -u -r1.4 row.cpp
--- lib/row.cpp	1 Mar 2005 03:29:50 -0000	1.4
+++ lib/row.cpp	5 Apr 2005 17:04:12 -0000
@@ -9,7 +9,7 @@
 	return res->num_fields();
 }
 
-const ColData Row::operator[] (size_type i) const
+const ColData Row::col_num(size_type i) const
 {
 	if (!initialized) {
 		if (throw_exceptions)
@@ -21,11 +21,11 @@
 	return ColData(data.at(i).c_str(), res->types(i), is_nulls[i]);
 }
 
-const ColData Row::lookup_by_name(const char* i) const
+const ColData Row::operator[](const char* i) const
 {
 	int si = res->field_num(std::string(i));
 	if (si < res->num_fields()) {
-		return (*this)[si];
+		return col_num(si);
 	}
 	else {
 		throw BadFieldName(i);
Index: lib/row.h
===================================================================
RCS file: /usr/local/cvs/mysql++/lib/row.h,v
retrieving revision 1.9
diff -u -r1.9 row.h
--- lib/row.h	14 Feb 2005 17:29:54 -0000	1.9
+++ lib/row.h	5 Apr 2005 17:04:12 -0000
@@ -231,8 +231,7 @@
 };
 
 //: This class handles the actual rows in an intelligent manner.
-class Row : public const_subscript_container<Row,ColData,const ColData>,
-	    public RowTemplate<Row, ResUse>
+class Row : public RowTemplate<Row, ResUse>
 {
 private:
   std::vector <std::string> data;
@@ -241,6 +240,8 @@
   bool         throw_exceptions, initialized;
 
 public:
+  typedef unsigned int size_type;
+
   Row() {}
   Row(MYSQL_ROW d, const ResUse *r, unsigned long *jj, bool te = false) 
     : res(r), throw_exceptions(te), initialized(false)
@@ -262,12 +263,12 @@
   Row& self() {return *this;}
 
   const ResUse&  parent() const {return *res;}
-  size_type     size() const;
-  //: Returns the number of columns.
-  const ColData   operator [] (size_type i) const;
-  //: Returns the value of the field with the index of i.
+  // Returns the number of columns.
+  size_type     size() const; 
+  // Returns the value of the column named 'col'.
+  const ColData   operator [] (const char* col) const; 
 
-  const ColData lookup_by_name(const char*) const;
+  const ColData col_num(size_type i) const;
 
   const char *raw_data(int i) const {return data[i].data();}
 

Thread
RFC: Row::operator[] changeWarren Young5 Apr
  • Re: RFC: Row::operator[] changeEarl Miles5 Apr
    • Re: RFC: Row::operator[] changeWarren Young5 Apr
  • Re: RFC: Row::operator[] changeChris Frey5 Apr
    • Re: RFC: Row::operator[] changeWarren Young22 Jun
  • Re: RFC: Row::operator[] changeWarren Young22 Jun
    • Re: RFC: Row::operator[] changeWarren Young25 Jun
Re: RFC: Row::operator[] changeBruce Keats11 Apr