SDSU CS 683 Emerging Technologies: Embracing Change
Spring Semester, 2001
Integration & Some MySQL
Previous    Lecture Notes Index    Next    
© 2001, All Rights Reserved, SDSU & Roger Whitney
San Diego State University -- This page last updated 08-May-01

Contents of Doc 23, Integration & Some MySQL


References

MySQL, Paul DuBois, New Riders Publishing, 2000.
This is a very good book. A number of examples and tables in this lecture are from this text.

On-line MySQL Manual at: http://www.mysql.com/documentation/index.html


Doc 23, Integration & Some MySQL Slide # 2

Integration


Situation

XP team with N members working on a project

At the end of an iteration

We have a code base, call it Base1

We start a new iteration

All pairs check out Base1 and start to work

A pair finishes a task and integrates changes into code base

We how have a new code base, Base2

When the next pair finishes a task:






Doc 23, Integration & Some MySQL Slide # 3
In general we could have a pair that:




The larger the K the harder the integration could be


Doc 23, Integration & Some MySQL Slide # 4
Avoid Integration Hell

Use some form of source code configuration management

Integrate often


Doc 23, Integration & Some MySQL Slide # 5

MySQL

Database & tables


Database consists of a number of tables

Table is a collection of records

Each Column of data has a type

+----------------------+----------------------+------------+----------+
| firstname            | lastname             | phone      | code     |
+----------------------+----------------------+------------+----------+
| John                 | Smith                | 555-9876   | 2000     |
| Ben                  | Oker                 | 555-1212   | 9500     |
| Mary                 | Jones                | 555-3412   | 9900     |
+----------------------+----------------------+------------+----------+


Doc 23, Integration & Some MySQL Slide # 6

MySQL Names


Databases, tables columns & indexes have names

Legal Characters

Alphanumeric characters
'_'
'$'

Names can start with digits

Name length

Up to 64 characters tables, databases, columns & indexes

Name qualifiers

A table is in a database

Full name of a table is databaseName.tableName

A column is in a table

Full name of a table is databaseName.tableName.columnName

Often the full name is not needed


Doc 23, Integration & Some MySQL Slide # 7
Example of Nonqualified Names

# Set a default database

USE acm;

/* Now select some columns */

SELECT last_name , first_name FROM members;


acm is a database
members is a table in the acm database
last_name & first_name are columns in members

Case Sensitivity

SQL keywords and function names

Not case sensitive

Database & table names

Are implemented using directories and files
Case sensitivity depend on OS


Column and index names
Not case sensitive


Doc 23, Integration & Some MySQL Slide # 8

MySQL Data Types

Integer - decimal or hex
Floating-point - scientific & 12.1234
Use single or double quotes
"this is a string"
'So is this'
Sequence
Meaning
\0
NUL (ASCII 0)
\'
Single quote
\"
Double quote
\b
Backspace
\n
Newline
\r
Tab
\\
Backslash
Including a quote character in a string
Double quote the character
'Don''t do it'
"He said, ""Go home"" "
Use the other quote character
"Don't do it"
'He said, "Go home" '
Escape the quote character with a backslash


Doc 23, Integration & Some MySQL Slide # 9

MySQL Columns Types

Numeric


Type
Range
TINYINT[(M)]
Signed Values: -128 to 127
Unsigned Values: 0 to 225
SMALLINT[(M)]
Signed Values: -32,768 to 32,767
Unsigned Values: 0 to 65,535
MEDUIMINT[(M)]
Signed Values: -8,388,608 to 8,388,607
Unsigned Values: 0 to 16,777,215
INT[(M)]
Signed Values: -2,147,683,648 to 2,147,683,647
Unsigned Values: 0 to 4,294,967,259
BIGINT[(M)]
Signed Values: -9,223,372,036,854,775,808 to
9,223,372,036,854,775,807
Unsigned Values: 0 to 2 32-1
FLOAT[(M,D)], FLOAT(4)
MIN VALUES: ±1.175494351E-38
MAX VALUES: ±3.402823466+38
DOUBLE[(M,D)], FLOAT(8)
MIN VALUES: ±2.22507E-308
MAX VALUES: ±1.79769+308
DECIMAL(M,D)
Depends on M & D

Ints & Floats

M = number of digits to the left of the decimal displayed
D = number of decimal places displayed
M & D do not affect how the number is stored

DECIMAL

Stored as a string
M & D determine how many characters are stored


Doc 23, Integration & Some MySQL Slide # 10

String Column Types


Type
Max Size
CHAR(M)
M (<=225) bytes
VARCHAR(M)
M (<=225) bytes
TINYBLOB, TINYTEXT
28-1 bytes
BLOB, TEXT
216-1 bytes
MEDIUMBLOB, MEDIUMTEXT
224-1 bytes
LONGBLOB, LONGTEXT
232-1 bytes
ENUM("value1", ...)
65535 members
SET("value1", ...)
64 members

CHAR & VARCHAR are the most common string types

CHAR is fixed-width

VARCHAR, BLOBs and TEXTs are variable width

Fixed-length row
Row containing just fixed length items
Processed much faster than variable-length rows

MySQL generally converts CHARs to VARCHARS in tables with variable-length rows

BLOB (Binary Large OBject) & Text
BLOBs use case sensitive comparisons
TEXT uses case insensitive comparisons


Doc 23, Integration & Some MySQL Slide # 11

Date & Time Column Types


Type
Range
DATE
"1000-01-01" to "9999-12-31"
TIME
"-835:59:59" to "838:59:59"
DATETIME
"1000-01-01 00:00:00" to
"9999-12-31 23:59:59"
TIMESTAMP[(M)]
19700101000000 to year 2037
YEAR[(M)]
1901 to 2155


DATE is time of day

TIME is elapsed time

"12:30" represents "00:12:30"


Doc 23, Integration & Some MySQL Slide # 12

Basic SQL Commands


CREATE TABLE table_name 
(
   col_name    col_type [ NOT NULL | PRIMARY KEY]
   [, col_name col_type [ NOT NULL | PRIMARY KEY]]*
)
   
DROP TABLE table_name
   
INSERT INTO table_name [(column [, column ]*)] 
   VALUES (value [, value]*)
   
DELETE FROM table_name
   WHERE column OPERATOR value
   [ AND | OR column OPERATOR value ]*
   
SELECT [table.]column [, [table.]column]*
   FROM table [=alias][, table [= alias]]*
   [ WHERE [table.]column OPERATOR VALUE
   [ AND | OR [table.]column OPERATOR VALUE]*]
   [ ORDER BY [table.]column [DESC][, [table.]column [DESC]]

UPDATE table_name SET column=value [,column=value]*
   WHERE column OPERATOR value
   [ AND | OR column OPERATOR value]*

OPERATOR can be <,>,=,<=,>=,<>, or LIKE

VALUE can be a literal value or a column name


Doc 23, Integration & Some MySQL Slide # 13

Indexing


Column indexes make queries more efficient

MySQL before 3.23.2 did not allow indexed columns to be:


Unique & Primary Columns

Unique - index with out duplicate values
Primary key - unique column with index name Primary


Doc 23, Integration & Some MySQL Slide # 14
Creating Indexes

Can use


Doc 23, Integration & Some MySQL Slide # 15
Examples - CREATE
Format
CREATE TABLE table_name
(
   #create columns, then declare indexes
   INDEX index_name (column_list),
   UNIQUE index_name (column_list),
   PRIMARY KEY (column_list ),
   # more stuff
)
   
CREATE TABLE roger
(
   sam INT NOT NULL,
   PRIMARY KEY( SAM)
)
   
CREATE TABLE roger
(
   sam INT NOT NULL PRIMARY KEY
)
   
CREATE TABLE students
(
   name CHAR(25),
   address CHAR(60),
   INDEX (name, address)
)


Doc 23, Integration & Some MySQL Slide # 16
Alter Table

ALTER TABLE table_name ADD INDEX index_name (column_list)
ALTER TABLE table_name ADD UNIQUE index_name (column_list)
ALTER TABLE table_name ADD PRIMARY KEY  (column_list)


Create Index

CREATE UNIQUE INDEX index_name ON table_name (column_list)
CREATE INDEX index_name ON table_name (column_list)

Doc 23, Integration & Some MySQL Slide # 17

Operators


Arithmetic

+, -, *, / , %

Logical

AND, &&
OR, ||
NOT, !

Bit Operators

&
|
<<
a << b left shift of a by b bits

>> right shift


Doc 23, Integration & Some MySQL Slide # 18
Comparison Operators

Operator
Example
=

!=, <>

<

<=

>=

>

IN
a IN (x, y, z, ... )
BETWEEN
a BETWEEN b AND c
LIKE
a LIKE b
NOT LIKE

REGEXP, RLIKE
a REGEXP b
NOT REGEXP

<=>
a <=> b (equal even if NULL)
IS NULL
a IS NULL
IS NOT NULL


Binary strings
CHAR BINARY, VARCHAR BINARY, and BLOB types

Binary string comparisons are case sensitive

Non-binary string comparisons are not case sensitive


Doc 23, Integration & Some MySQL Slide # 19
BINARY operator (MySQL 3.23)

Convert a string to binary

BINARY "abc" = "Abc"

Like & Regexp

LIKE patterns match only if the entire string is matched

REGEXP patterns match if the pattern is found anywhere in the string

LIKE is not case sensitive unless at least one operand is a binary string

REGEXP starting in 3.23.4 uses LIKE's case sensitive rules

Doc 23, Integration & Some MySQL Slide # 20
Like Pattern Matching

Character
Meaning
_
matches any single character
%
matches 0 or more characters of any value
\
escapes special characters

All other characters match themselves


Doc 23, Integration & Some MySQL Slide # 21
Regexp Pattern Matching

Sequence
Meaning
^
Match the beginning of the string
$
Match the end of string
. (period)
Match any single character
[...]
Match any character between the brackets
[^...]
Match any character not between the brackets
E*
Match zero or more instance of pattern E
E+
Match one or more instance of pattern E
E?
Match zero or one instance of pattern E
E1 | E2
Match E1 or E2
E{m}
Match m instances of E
E{,n}
Match zero to n instances of E
E{m,}
Match m or more instances of E
E{m,n}
Match m to n instances of E
(...)
Group elements in to one element

All other characters match themselves

Expression
Result
"abc" REGEXP "a.c"
1
"abc" REGEXP "[a-z]"
1
"abc" REGEXP "[^a-z]"
0
"abc" REGEXP "^abc$"
1
"abcd" REGEXP "^abc$"
0
"abc" REGEXP "(abc){2}"
0
"abcabc" REGEXP "(abc){2}"
1


Doc 23, Integration & Some MySQL Slide # 22

Using MySQL In Squeak


You need the MySQL driver and a running version of MySQL

MySQL
MySQL can be downloaded at: http://www.mysql.com/documentation/index.html

If you don't want to set up your own MySQL server contact me for a database account on fargo


MySQL Squeak Driver

Part of Comanche 4.5

http://www.eli.sdsu.edu/SmalltalkCode/comanche/index.html

New versions of Comanche do not include the MySQL driver

It is available at: http://fce.cc.gatech.edu/~bolot/squeak/mysql/Mysql-Driver.28Jan2335.cs.gz

You still need the SocketStream from Comanche


Doc 23, Integration & Some MySQL Slide # 23

Using MySQL Squeak Driver


The driver supports the following SQL commands:

ALTER
CREATE
DELETE
DROP
GRANT
INSERT
LOCK
REPLACE
SELECT
SET
UNLOCK
UPDATE


Doc 23, Integration & Some MySQL Slide # 24
Sample Creation of a Table

| connection statement resultSet user |
Socket initializeNetwork.
user := JdmConnectionSpec new.
user
        database: '683Examples';
        host: (NetNameResolver addressForName: 'fargo.sdsu.edu');
        port: 5555;
        user: 'cs683';
        password: 'foobar'.
connection := JdmConnection on:  user.
statement := connection createStatement.
statement executeQuery: 
   'CREATE TABLE name 
      (first CHAR(15), 
       second CHAR(15)) '.
statement executeQuery: 
   'INSERT INTO  name 
   VALUES 
      (''Roger'' , ''Whitney''), 
      (''Eli'' , ''Whitney'')'.
resultSet := statement executeQuery: 
   'SELECT * FROM name'.
resultSet printString
Result
'''first'' ''second''
''Roger'' ''Whitney''
''Eli'' ''Whitney''
'

Doc 23, Integration & Some MySQL Slide # 25
Some Explanation

This only needs to be done once after you start an image

   Socket initializeNetwork.
The following gets to be a pain after a while

   user := JdmConnectionSpec new.
   user
          database: '683Examples';
          host: (NetNameResolver addressForName: 'fargo.sdsu.edu');
          port: 5555;
          user: 'cs683';
          password: '******'.

Doc 23, Integration & Some MySQL Slide # 26
I tend to use a subclass

JdmConnectionSpec subclass: #CS683ConnectionSpec
   instanceVariableNames: ''
   classVariableNames: ''
   poolDictionaries: ''
   category: 'Mysql-Driver'!
initialize
   database := '683Examples'.
   host := NetNameResolver addressForName: 'fargo.sdsu.edu'.
   port := 5555.
   user := 'cs683'.
   password := '******'

Class Method
new
   ^super new initialize


So we then can use:

   user := CS683ConnectionSpec new.


Doc 23, Integration & Some MySQL Slide # 27

Statements


In JDBC one uses a statement just once.

Here we can use a statement multiple times

connection := JdmConnection on:  user.
statement := connection createStatement.
statement executeQuery: 
   'CREATE TABLE name 
      (first CHAR(15), 
       second CHAR(15)) '.
statement executeQuery: 
   'INSERT INTO  name 
   VALUES 
      (''Roger'' , ''Whitney''), 
      (''Eli'' , ''Whitney'')'.
resultSet := statement executeQuery: 
   'SELECT * FROM name'.

Doc 23, Integration & Some MySQL Slide # 28
Return Types of executeQuery

A SELECT query returns a JdmResultSet

All other queries return a JdmResult

JdmResult

Contains type (always update) and number of rows changed

value returns the number of rows changed


Doc 23, Integration & Some MySQL Slide # 29
JdmResultSet

Important Methods

columns
Returns a collection of JdmColumn objects
next
Gets the next row in the result set from the database
Returns true if the row is not empty
rawValueAt: anInteger
Returns the value of the anInteger column in the row
Value is returned as a string

rawValueNamed: aString
Returns the value of the column with name aString
Value is returned as a string

valueAt: anInteger
Returns the value of the anInteger column in the row
Value is returned as correct Smalltalk type for this column

valueNamed: aString
Returns the value of the column with name aString
Value is returned as correct Smalltalk type for this column


Doc 23, Integration & Some MySQL Slide # 30
Using the ResultSet

| connection statement resultSet user |
Socket initializeNetwork.
user := CS683ConnectionSpec new.
connection := JdmConnection on:  user.
statement := connection createStatement.
resultSet := statement executeQuery: 'SELECT * FROM name'.
columnNames := resultSet columns collect: [:each | each name].
Transcript cr.
columnNames do: 
   [:each | 
   Transcript
      show: each;
      tab].
[resultSet next]
   whileTrue:
      [Transcript cr.
      columnNames do: 
         [:each |
         Transcript
            show: (resultSet valueNamed: each);
            tab.]]
Result in Transcript
first   second   
Roger   Whitney   
Eli   Whitney


Doc 23, Integration & Some MySQL Slide # 31

MySQL & Smalltalk Types


All data sent to a MySQL database must be converted to a string


Doc 23, Integration & Some MySQL Slide # 32

INT Types


valueNamed: valueAt; return an Integer object

| connection statement resultSet user anInteger |
Socket initializeNetwork.
user := CS683ConnectionSpec new.
connection := JdmConnection on:  user.
statement := connection createStatement.
statement executeQuery: 'DROP TABLE IF EXISTS typeExamples '.
statement executeQuery: 'CREATE TABLE typeExamples 
   (a INT) '.
statement executeQuery: 'INSERT INTO  typeExamples VALUES 
   ( 12  ), 
   (' , 10 printString , ')'.
resultSet := statement executeQuery: 
   'SELECT * FROM typeExamples'.
resultSet next.
anInteger := resultSet valueNamed: 'a'

Doc 23, Integration & Some MySQL Slide # 33

DOUBLE & FLOAT


valueNamed: valueAt;
return a JdmFloatHolder for FLOATs
return a JdmFloatHolder for DOUBLEs

| connection statement resultSet user aJdmFloatHolder |
Socket initializeNetwork.
user := CS683ConnectionSpec new.
connection := JdmConnection on:  user.
statement := connection createStatement.
statement executeQuery: 'DROP TABLE IF EXISTS typeExamples '.
statement executeQuery: 'CREATE TABLE typeExamples 
   (a FLOAT) '.
statement executeQuery: 'INSERT INTO  typeExamples VALUES 
   ( 12.2  ), 
   (' , 10.93 printString , ')'.
resultSet := statement executeQuery: 
   'SELECT * FROM typeExamples'.
resultSet next.
aJdmFloatHolder := resultSet valueNamed: 'a'.
aFloat := aJdmFloatHolder value.


Doc 23, Integration & Some MySQL Slide # 34

CHAR, VARCHAR, *TEXT


valueNamed: valueAt;
return a string for CHARs, VARCHARs, *TEXTs

When you send the string in SQL it must be in single quotes.

Note the two different ways to get the quotes in the SQL statement

| connection statement resultSet user inputString aString |
Socket initializeNetwork.
user := CS683ConnectionSpec new.
connection := JdmConnection on:  user.
statement := connection createStatement.
statement executeQuery: 'DROP TABLE IF EXISTS typeExamples '.
statement executeQuery: 'CREATE TABLE typeExamples 
   (a CHAR(10)) '.
inputString := 'Hi dad'.
statement executeQuery: 'INSERT INTO  typeExamples VALUES 
   ( ''Hi mom''  ),
   (' , inputString printString ,  ')'.
resultSet := statement executeQuery: 'SELECT * FROM typeExamples'.
resultSet next.
aString := resultSet valueNamed: 'a'.


Doc 23, Integration & Some MySQL Slide # 35

*BLOB


valueNamed: valueAt;
return a string for all BLOBs

| connection statement resultSet user inputString aByteArray |
Socket initializeNetwork.
user := CS683ConnectionSpec new.
connection := JdmConnection on:  user.
statement := connection createStatement.
statement executeQuery: 'DROP TABLE IF EXISTS typeExamples '.
statement executeQuery: 'CREATE TABLE typeExamples 
   (a BLOB) '.
inputString := 'Hi dad'.
statement executeQuery: 'INSERT INTO  typeExamples VALUES 
   ( ''Hi mom''  ),
   (' , inputString printString ,  ')'.
resultSet := statement executeQuery: 
   'SELECT * FROM typeExamples'.
resultSet next.
aByteArray := resultSet valueNamed: 'a'.
aByteArray


Doc 23, Integration & Some MySQL Slide # 36

DATE


valueNamed: valueAt;
return a JdmDateHolder object

| connection statement resultSet user  aJdmDateHolder aDate |
Socket initializeNetwork.
user := CS683ConnectionSpec new.
connection := JdmConnection on:  user.
statement := connection createStatement.
statement executeQuery: 'DROP TABLE IF EXISTS typeExamples '.
statement executeQuery: 'CREATE TABLE typeExamples 
   (a DATE) '.
statement executeQuery: 'INSERT INTO  typeExamples VALUES 
   ( ''2001-05-05''  ),
   (' , Date today yyyymmdd printString ,  ')'.
resultSet := statement executeQuery: 
   'SELECT * FROM typeExamples'.
resultSet next; next.
aJdmDateHolder := resultSet valueNamed: 'a'.
aDate := aJdmDateHolder value.
^aDate


Doc 23, Integration & Some MySQL Slide # 37

TIME


valueNamed: valueAt;
return a JdmTimeHolder object


| connection statement resultSet user  aJdmTimeHolder aTime |
Socket initializeNetwork.
user := CS683ConnectionSpec new.
connection := JdmConnection on:  user.
statement := connection createStatement.
statement executeQuery: 'DROP TABLE IF EXISTS typeExamples '.
statement executeQuery: 'CREATE TABLE typeExamples 
   (a TIME) '.
statement executeQuery: 'INSERT INTO  typeExamples VALUES 
   ( ''1:3:30''  ),
   (' , Time now print24 printString ,  ')',
   (' , Time now  printString printString ,  ')'
resultSet := statement executeQuery: 
   'SELECT * FROM typeExamples'.
resultSet next.
aJdmTimeHolder := resultSet valueNamed: 'a'.
aTime := aJdmTimeHolder value.
^aTime
aTime
1:03:30 am


Doc 23, Integration & Some MySQL Slide # 38

DATETIME


valueNamed: valueAt;
return a JdmDateTimeHolder object

JdmDateTimeHolder has accessor methods
date
time

| connection statement resultSet user  aJdmDateTimeHolder  |
Socket initializeNetwork.
user := CS683ConnectionSpec new.
connection := JdmConnection on:  user.
statement := connection createStatement.
statement executeQuery: 'DROP TABLE IF EXISTS typeExamples '.
statement executeQuery: 'CREATE TABLE typeExamples 
   (a DATETIME) '.
statement executeQuery: 'INSERT INTO  typeExamples VALUES 
   ( ''2001-5-5 1:3:30''  )'.
resultSet := statement executeQuery: 
   'SELECT * FROM typeExamples'.
resultSet next.
aJdmDateTimeHolder := resultSet valueNamed: 'a'.


Doc 23, Integration & Some MySQL Slide # 39

ENUM


valueNamed: valueAt;
return a string

| connection statement resultSet user  aString  |
Socket initializeNetwork.
user := CS683ConnectionSpec new.
connection := JdmConnection on:  user.
statement := connection createStatement.
statement executeQuery: 'DROP TABLE IF EXISTS typeExamples '.
statement executeQuery: 'CREATE TABLE typeExamples 
   (a ENUM( ''cat'', ''dog'', ''mouse'')) '.
statement executeQuery: 'INSERT INTO  typeExamples VALUES 
   ( ''cat'' )'.
resultSet := statement executeQuery: 
   'SELECT * FROM typeExamples'.
resultSet next.
aString := resultSet valueNamed: 'a'.
^aString.


Copyright ©, All rights reserved.
2001 SDSU & Roger Whitney, 5500 Campanile Drive, San Diego, CA 92182-7700 USA.
OpenContent license defines the copyright on this document.

Previous    visitors since 08-May-01    Next