grabbing value of a variabe by its name?

Richard A. O'Keefe ok at cs.otago.ac.nz
Tue Jul 30 00:25:43 UTC 2002


	> This is doing things an OBJECT-ORIENTED way.  You want to insert something
	> into a table.  What do you want to insert?  Variables?  No: you want to
	> insert an OBJECT.  So let there *BE* an object.
	
	Right.  However I'm using the postgres bindings which as far as I can see they
	aren't as "objectified" as they could be (or I could be wrong), and I admit
	I feel quite some reluctance to start messing with them and spreading
	changes all over the place and ripping its guts apart.
	
What I'm really suggesting is layering your own stuff *on top*.

	> For example, suppose the column 'zip' in your data base is renamed from
	> the US-centric 'zip' to a more globally intelligible 'postcode'.  ALL of
	> your versions break, but the Table1 class can just add two methods
	
	You don't go around renaming columns just because one is more intelligible to
	you than what you "inherited", unless you are very bored.
	
I'm not suggesting that your Squeak code use a new name; I'm pointing out
that the SQL code might use a new name and your Squeak code might need to
adapt to that.  Just because you've "inherited" it doesn't mean the
underlying data base won't change; real data bases very often do.  (The
BIG problem is when the semantics of the data in the real world change but
for reasons of inertia the data base schema is not changed.

	>  * It simply isn't *POSSIBLE* to use the same names in your Smalltalk code
	>    as in your data base.
	
	It is, as long as you design your database and you dont have to
	access third party ones, and thats the only reason I'm
	comfortable with pulling tricks and "rules" out of my hat.

If you are in a situation where you have full control over the names in the
SQL database schemas then fine, but in that case you aren't talking about a
data base you've "inherited".

Even then, an SQL column name may reasonably have the form
    SchemaName . TableName . ColumnName
and while you could easily represent that in Squeak as
#(SchemaName TableName ColumnName) the result would not be a Squeak variable.

	The rest of my reply revolves around this, so if you agree
	you'll probabily agree with the rest.. and if you don't you'll
	never agree with anything.
	
	> ->     Home_Team            character(14),
	
	All the columns have no underscores in them, on purpose, just to avoid this
	inconvenience.
	
If we rule out quoted identifiers and identifiers in exotic national language
character sets and just stick with basic identifiers, then underscores are not
an inconvenience.  SQL defines names to be equal if they differ only in case.

sql-to-squeak(name) = letter after underscore => capital
                      other letter or digit => no change
                      underscore => delete

squeak-to-sql(name) = capital letter => underscore, capital letter
                      lower case letter => capital letter
                      digit => no change

so  Home_Team -> homeTeam -> HOME_TEAM.
and HOME_TEAM is in fact the SQL normal form of the name Home_Team.

In fact, some such rule (and the presence of an underscore in the sql name)
would be the only justification for having a capital letter in the squeak name.

Rather more exotic rules of this type _can_ handle quoted identifiers and
accented letters, but the results tend not to be readable.  If you have full
and total control of the SQL names, this is not a problem.

	>  * The trick does not particularly encourage consistency.  SQL names are
	>    not case sensitive.  So homeTeam, homeTEAM would both represent the
	>    same SQL name.  How exactly does the trick encourage people to consistently
	>    pick one of them, in a way that gentle exhortation would not?
	
	Doesnt matter as the column names get lowercased when the postgres bindings
	return them.  Or maybe its seaside.. they get lowercased somewhere.
	
So you are NOT in full control of the names on the Squeak side?
Any interface which simply lowercases SQL names is broken; are you sure it
does not do something special with underscores?

In any case, it's not the trick that encourages people to use consistent
capitalisation; it's some other interface you are building on that forces
this.

	>  * Sometimes in SQL you have to use qualified names.  The example data base
	>    that my example comes from includes also
	>     create table Teams (Team ...)
	>     create table League (Team ...)
	>    You have not yet explained how your pun can accomodate SQL names like
	>    Teams.Team or League.Team.
	
	select team.team as teamteam
	
That is no answer.  It says how you can avoid the problem in some cases;
it does not say how the problem can be solved.

	>  * Some names which are perfectly usable as SQL names are reserved words
	>    in Smalltalk, such as "self", "super", "nil".
	
	That hardly counts as a valid objection.
	
Why the **** not?  Some names which are usable as SQL names are NOT usable
in Smalltalk.  PERIOD.  This means that a simplistic identity/case mapping
WILL NOT WORK IN ALL CASES.  It's about as valid as an objection can get.

If you are in full and total control of the SQL names, then yes, you
can avoid all the Smalltalk special names as well as the dozens of SQL
special names.  However, you did not previously inform us that you were in
full and total control of the SQL names, and the objection remains an
extremely serious objection to a simplistic identity/case name mapping
IN THE GENERAL CASE where people want to connect to a data base that they
are NOT in full control of.

The general case might reserve a prefix, such as "sQ", and map
    self to sQself
    super to sQsuper
    s_qfoo to sQsQfoo ...
A wide range of name mapping rules can be used, but not simplistic
identity mapping.

	>  * You have not yet explained how your pun can accomodate SQL delimited
	>    identifiers.  For people who never looked at SQL 92, "foo!" (with the
	>    double quotes) is a perfectly good SQL 92 'delimited identifier'.
	>    Delimited identifiers may be used pretty much anywhere that simple
	>    identifiers may be.
	
	Who wants the shotgun?
	
I have no idea what shotgun you are talking about.
Anyone who wants to talk to an SQL 92 data base that they are NOT in
full control of had better be ready to cope with any legal SQL 92.

Now that you inform us you ARE in the very very special case of building
a Smalltalk binding to an SQL data base whose names you have full control
of, that tells us that this isn't a problem *for you* and *right now*.

For other people, the fact that SQL 1992 allows some rather surprising
identifiers means that crude name identity hacks will not *in general* work.

	>  * According to the SQL 1992 standard, an identifier may contain non-Latin
	>    letters if such exist according to the <module character set specification>
	>    or the <character set specification>; how are those to be handled by this
	>    pun?
	
	And the shells?
	
Again, I have no idea what you mean by "shells".  However, accented letters
are very much a part of SQL 1992 for very good reason.  Only people who have
full control of the SQL names do not need to worry about this.

	> In this case, the two rows happen to need the same value for their
	> 'team' columns.  But what if they needed DIFFERENT values for their
	> team columns?
	> 
	>     winners := 'Hawkeyes'.
	>     losers := 'Windies'.
	>     w := Wins new.
	>     w team: winners; against: losers.
	>     w insert.
	>     l := Losses new.
	>     l team: losers; against: winners.
	>     l insert.
	> 
	> I cannot for the life of me regard any approach which would force
	> the entry into Wins and the entry into Losses to use the *same* local
	> variables for opposite purposes as 'safe'.
	
	Ah, you saved the real one for the end :) It's a poor example
	tho (SQL wise), but nobody is forcing you:

In what way is it a poor example?  All it is *supposed* to be an example
of is inserting two rows that have some column names in common, and it's
a simple clear example of that.

	If you want (or need) to write the insert statement, do. 

Hang on a minute, it's *you* who are writing explicit INSERT statements.
Part of the point of my example is that I'm *not* writing INSERT statements;
I'm constructing row objects and telling them to insert themselves.  In
the approach I am suggesting, no SQL syntax appears in the Smalltalk code
at all. (Except in the underlying classes.)

	Of course the statement was more "exposed" and therefore looked
	more natural (or less ugly) in my example than it would if it
	was next to your example.

I cannot understand this.  You example DID have "exposed" SQL syntax,
and that made it MORE ugly, not less.  In fact, it's precisely the
exposed SQL syntax that makes it so tricky to get right.  Part of my
point is that because you are interfacing to SQL code, SQL syntax has
to appear *somewhere*, but it should be hidden away as deeply as possible
and the great bulk of your code should look like Smalltalk.

Elementary statements:
    INSERT INTO table (name,...) VALUES (atom,...);
=>  newRow := Table new.
    newRow name: atom. ...
    newRow insert.

    UPDATE table WHERE cond SET name = value ...
=>  Table updateWhere: [:aRow | cond]
        set: [:aRow | aRow name: value. ...]
    Table atName: atom updateWhere: [:aRow | cond] set: [...]
    "replace Name by any suitable column name"

    DELETE FROM table WHERE cond
=>  Table deleteWhere: [:aRow | cond]
    Table atName: atom deleteWhere: [:aRow | cond]
    "replace Name by any suitable column name".

SELECT gets a bit more complicated; I'd be inclined to make each SELECT
be its own method, and it might make sense for it to be a method of the
*result* table.

Perhaps any further discussion should be in terms of actual SELECTs from
your application.




More information about the Squeak-dev mailing list