* harbour/src/vm/set.c
! fixed small typos in returned values (FALSE instead of NULL and 0)
* harbour/src/vm/estack.c
* make calling hb_stackTotalItems() safe in MT mode when stack is not
initialized - now this function can be used to check if HVM stack
exists and is initialized in ST and MT mode
* harbour/src/rtl/errintlo.c
! fixed at least 4 GPF traps exploited when hb_errInternal() was called
and HVM stack was not initialized
* harbour/include/Makefile
+ harbour/include/hbcdpreg.h
* harbour/include/hbapicdp.h
* harbour/src/rtl/cdpapi.c
+ added new CDP API which fixes many errors and limitations in old
implementation.
Warning !!! some very serious bugs in national sorting have been
fixed. It may cause that old indexes using some national
sorting will not be compatible. Please rebuild existing
indexes.
* harbour/src/vm/itemapi.c
* harbour/src/rdd/hsx/hsx.c
* harbour/src/rdd/dbfntx/dbfntx1.c
* harbour/src/rdd/dbfnsx/dbfnsx1.c
* harbour/src/rdd/dbfcdx/dbfcdx1.c
* harbour/contrib/hbbmcdx/bmdbfcdx.c
* harbour/contrib/rddads/adsx.c
* harbour/contrib/rddsql/sqlmix.c
* updated to work with new CDP API
TOFIX: update adsx.c and sqlmix.c to use hb_cdpcmp() which resepcts
sorting with accented and mulitybyts characters.
Mindaugas, can you update above code?
* harbour/src/codepage/cpbg866.c
* harbour/src/codepage/cpbgiso.c
* harbour/src/codepage/cpbgmik.c
* harbour/src/codepage/cpbgwin.c
* harbour/src/codepage/cpcs852.c
* harbour/src/codepage/cpcsiso.c
* harbour/src/codepage/cpcskam.c
* harbour/src/codepage/cpcswin.c
* harbour/src/codepage/cpde850.c
* harbour/src/codepage/cpdeiso.c
* harbour/src/codepage/cpdewin.c
* harbour/src/codepage/cpel737.c
* harbour/src/codepage/cpeliso.c
* harbour/src/codepage/cpelwin.c
* harbour/src/codepage/cpes850.c
* harbour/src/codepage/cpes850c.c
* harbour/src/codepage/cpesiso.c
* harbour/src/codepage/cpesisoc.c
* harbour/src/codepage/cpeswin.c
* harbour/src/codepage/cpeswinc.c
* harbour/src/codepage/cpeswinm.c
* harbour/src/codepage/cpfr850.c
* harbour/src/codepage/cpfriso.c
* harbour/src/codepage/cpfrwin.c
* harbour/src/codepage/cphr437.c
* harbour/src/codepage/cphr852.c
* harbour/src/codepage/cphrwin.c
* harbour/src/codepage/cphu852.c
* harbour/src/codepage/cphu852s.c
* harbour/src/codepage/cphuiso.c
* harbour/src/codepage/cphuisos.c
* harbour/src/codepage/cphuwin.c
* harbour/src/codepage/cphuwins.c
* harbour/src/codepage/cpit437.c
* harbour/src/codepage/cpit850.c
* harbour/src/codepage/cpitisb.c
* harbour/src/codepage/cpitiso.c
* harbour/src/codepage/cpitwin.c
* harbour/src/codepage/cpltwin.c
* harbour/src/codepage/cppl852.c
* harbour/src/codepage/cppliso.c
* harbour/src/codepage/cpplmaz.c
* harbour/src/codepage/cpplwin.c
* harbour/src/codepage/cppt850.c
* harbour/src/codepage/cpptiso.c
* harbour/src/codepage/cpro852.c
* harbour/src/codepage/cproiso.c
* harbour/src/codepage/cprowin.c
* harbour/src/codepage/cpru866.c
* harbour/src/codepage/cpruiso.c
* harbour/src/codepage/cprukoi.c
* harbour/src/codepage/cpruwin.c
* harbour/src/codepage/cpsk852.c
* harbour/src/codepage/cpskiso.c
* harbour/src/codepage/cpskkam.c
* harbour/src/codepage/cpskwin.c
* harbour/src/codepage/cpsl437.c
* harbour/src/codepage/cpsl852.c
* harbour/src/codepage/cpsliso.c
* harbour/src/codepage/cpslwin.c
* harbour/src/codepage/cpsrwin.c
* harbour/src/codepage/cpsv850.c
* harbour/src/codepage/cpsvclip.c
* harbour/src/codepage/cpsviso.c
* harbour/src/codepage/cpsvwin.c
* harbour/src/codepage/cptr857.c
* harbour/src/codepage/cptriso.c
* harbour/src/codepage/cptrwin.c
* harbour/src/codepage/cpua1125.c
* harbour/src/codepage/cpua866.c
* harbour/src/codepage/cpuakoi.c
* harbour/src/codepage/cpuawin.c
* harbour/src/codepage/uc037.c
* harbour/src/codepage/uc1006.c
* harbour/src/codepage/uc1026.c
* harbour/src/codepage/uc1125.c
* harbour/src/codepage/uc1250.c
* harbour/src/codepage/uc1251.c
* harbour/src/codepage/uc1252.c
* harbour/src/codepage/uc1253.c
* harbour/src/codepage/uc1254.c
* harbour/src/codepage/uc1255.c
* harbour/src/codepage/uc1256.c
* harbour/src/codepage/uc1257.c
* harbour/src/codepage/uc1258.c
* harbour/src/codepage/uc424.c
* harbour/src/codepage/uc500.c
* harbour/src/codepage/uc737.c
* harbour/src/codepage/uc775.c
* harbour/src/codepage/uc850.c
* harbour/src/codepage/uc852.c
* harbour/src/codepage/uc855.c
* harbour/src/codepage/uc856.c
* harbour/src/codepage/uc857.c
* harbour/src/codepage/uc860.c
* harbour/src/codepage/uc861.c
* harbour/src/codepage/uc862.c
* harbour/src/codepage/uc863.c
* harbour/src/codepage/uc864.c
* harbour/src/codepage/uc865.c
* harbour/src/codepage/uc866.c
* harbour/src/codepage/uc869.c
* harbour/src/codepage/uc874.c
* harbour/src/codepage/uc875.c
* harbour/src/codepage/uc885910.c
* harbour/src/codepage/uc885911.c
* harbour/src/codepage/uc885913.c
* harbour/src/codepage/uc885914.c
* harbour/src/codepage/uc885915.c
* harbour/src/codepage/uc885916.c
* harbour/src/codepage/uc88591b.c
* harbour/src/codepage/uc8859_1.c
* harbour/src/codepage/uc8859_2.c
* harbour/src/codepage/uc8859_3.c
* harbour/src/codepage/uc8859_4.c
* harbour/src/codepage/uc8859_5.c
* harbour/src/codepage/uc8859_6.c
* harbour/src/codepage/uc8859_7.c
* harbour/src/codepage/uc8859_8.c
* harbour/src/codepage/uc8859_9.c
* harbour/src/codepage/ucascii.c
* harbour/src/codepage/ucatari.c
* harbour/src/codepage/uckam.c
* harbour/src/codepage/uckoi8.c
* harbour/src/codepage/uckoi8u.c
* harbour/src/codepage/ucmacce.c
* harbour/src/codepage/ucmaccyr.c
* harbour/src/codepage/ucmacgrk.c
* harbour/src/codepage/ucmacice.c
* harbour/src/codepage/ucmacrom.c
* harbour/src/codepage/ucmactrk.c
* harbour/src/codepage/ucmaz.c
* harbour/src/codepage/ucmik.c
* harbour/src/codepage/ucnext.c
* updated for new CP API
Warning: please test all national CPs. I'm not able to test unknown for
me national character conditions so it's possible that I made
something wrong. Additionally current CP API does not have
some limitations which existed in the old one so now some hacks
or workarounds can be cleaned. I.e. now all translations are
done using Unicode tables so it's not necessary to use the
same number of characters to make them working.
Updating CP files I've found the following potential problems
in definitions which I haven't fixed or fixed only partially:
cpes850c.c - update for new format removing hacks for old CP
implementation
cpesisoc.c > remove, it's not longer necessary
cpeswinc.c /
cpeswinm.c - it is the same as cpesiso.c so it should be removed
cphu852.c \
cphu852s.c \
cphuiso.c > update for new format removing hacks for old CP
cphuwin.c / implementation
cphuisos.c > remove, it's not longer necessary
cphuwins.c /
cphr437.c > does it really use CP-437? and ^]\[@~}|{` instead of
cpsl437.c / nationalletters or it uses different then 437 CP for
7-bit Croatian characters encoding. It's important
because without valid unicode table translations will
not work.
cpit437.c - update for new version if necessary (upper characters)
cpsv850.c \
cpsviso.c > they had ACCENTED_INTERLEAVED but without ACCENTED_EQUAL
cpsvwin.c / so this setting was ignored. Now it's not ignored.
cpsvclip.c - update for new format to be fully not only
"almost compatible with Clipper's NTXSWE.OBJ"
For sure these are not all problems inherited from old CP
implementation so please verify all existing CPs.
* harbour/src/codepage/cp_tpl.c
+ added new example for CP definition. Working on new CPs please read
this description:
If accented characters need special sorting ( HB_CDP_ACSORT_EQUAL or
HB_CDP_ACSORT_INTERLEAVE ) then you need to mark the accented
characters with the symbol '~' before each of them, for example:
a~_
If there is two-character sequence, which is considered as one, it
should be marked with '.' before and after it, for example:
... h.ch.i ...
if such multibyte character has its own Unicode representation then
this Unicode value can be set using '=' symbol, for example:
....h.ch=2A7C.i
and it will be used in translations.
The Upper case string and the Lower case string should use the
same letters. If some characters does not have corresponding upper
or lower letter then space ' ' can be used as dummy character, for
example in German CPs there is no upper case 'scharfes S' letter
so space is used as dummy character.
HB_CP_LATIN should be 1 if the national alphabet is based on Latin
otherwise 0
Please note that now you can use two versions of CP definition.
The 1-st one which uses human readable form similar to the old CP
definition and 2-nd which uses directly final CP tables so it
allows to replicate any conditions which existed in Clipper or
any other compatible language which uses static tables.
tests/cpinfo.prg can generate automatically .c files with new CP
definition in the 2-nd version. Now if user wants to create new
Harbour CP which is fully Clipper compatible he only has to
compile and link cpinfo.prg with given national sorting module
and then execute it with new Harbour CP name as 1-st parameter.
cp<cpname>.c file is generated which can be added to Harbour
repository. Optional 2-nd parameter is CP description and 3-rd
is Harbour Unicode table ID (if not given 437 is used and should
be updated by user in .c file). This method should definitely
resolve any problems with creating Clipper compatible CP definition.
It also allows to easy verify if CP definitions are compatible. It's
enough to compare generated .c files.
* harbour/src/codepage/uckam.c
! fixed Kamenicky Unicode table definition - it was Mazovia CP :)
* harbour/src/codepage/cpde850.c
* harbour/src/codepage/cpdeiso.c
* harbour/src/codepage/cpdewin.c
! fixed CP wrongly encoded CP due to limitations in old CP definition.
Now it's possible to define different number of upper an lower
characters (space " " can be used as dummy character) and I used
it to eliminate hack for 'scharfes S' which does not exists as upper
case.
Please clean other CPs which contain similar hacks.
* harbour/src/codepage/cphu852.c
* harbour/src/codepage/cphuiso.c
* harbour/src/codepage/cphuwin.c
* harbour/src/codepage/cpua866.c
* removed dummy letters introduced for old translation code
* harbour/src/rtl/natmsg.c
* harbour/src/rtl/cdpapi.c
* harbour/include/hbextern.ch
+ added HB_CDPINFO() function
* redirected _NATSORTVER() function to HB_CDPINFO()
To All,
Please check your national sorting in current version and make
any updates if necessary or inform me about found problems.
I've checked that Polish CPs are working fine and all existing
CPs passes my test program which verified some technical aspects
of CP implementation. But I cannot verify if this definitions
satisfy users in different countries.
/*
* $Id$
*/
Simple SQL Interface for Harbour
1. Introduction
Simple SQL interface implements accessing SQL query result via RDD
interface. It is not intended to be replacement for "transparent" move of
DBFCDX application to SQL world.
I want to discuss this in more detail. Many current RDDs for SQL servers
(ex. SQLRDD from xHarbour.com) tries to make a feeling you are working with
DBF file, but not with SQL database. SQL server does not support many
features, ex. RECNO(), deleted flag, file locks, record locks. These RDDs
are emulating these features to make feeling of DBF. DELETED() function is
emulated by creating additional table columns to store delete flag. Some
"hidden system" tables are used to register locking operations and emulate
record and file locks in DBF style. The idea of SQL query is also lost. If
you do a simple loop
DBUSEAREA(, "select * from my_table")
DO WHILE ! EOF()
somefunc( FIELD->some_sql_field )
DBSKIP()
ENDDO
RDD usualy will read SQL rows in portions, let's say 100 records per query.
So, hidden queries are generated. If you are using indexes these queries
are really complicated. Let's have index on FIELD1 + STR(FIELD2). A seek to
value cValue1 + STR(nValue2) will generate a query like:
SELECT * FROM my_table
WHERE (FIELD1 == cValue1 and FIELD2 >= nValue2) or FIELD1 > cValue1
ORDER BY FIELD1, FIELD2, _RECNO
LIMIT 100
After evaluation of first 100 cached records, next query will be generated:
SELECT * FROM my_table
WHERE (FIELD1 == cLastField1 and FIELD2 == nLastValue2 and _RECNO > nLastRecno) or
(FIELD1 == cLastField1 and FIELD2 > nLastValue2) or
FIELD1 > cLastValue1
ORDER BY FIELD1, FIELD2, _RECNO
LIMIT 100
To optimize these queries the SQL index expresion should be
"FIELD1,FIELD2,_RECNO", but not "FIELD1,FIELD2" as written in INDEX ON
command.
"Simple SQL interface" is too long to repeat every time I want to
address this library. I'll also use acronym "SSI" to address it.
The idea of SSI is different. It does not make hidden queries. All
queries should be made explicitly by programmer. SSI gives access to query
result via RDD interface, it does not tries to emulate DBF and be
"plug-and-play" solution for DBF to SQL migration. If you do
DBUSEAREA(, "select * from my_table")
all query (it could contain millions of records!) will be cached.
The features of SSI approach are:
- It's possible to access SQL database of other applications. Other
applications usualy does not follow agreement of "plug-and-play" SQL drivers
about additional DELETED column, _RECNO in the end of index expression, etc.
Access of SQL database of other applications is sometimes not possible.
- It's query oriented. That means a simple DO WHILE ! EOF() loop will iterate
each records once and only once. This is not true for "plug-and-play" SQL
drivers, if indexing is used. Just like in the case of loop over DBF file.
It is not guaranteed that all records are included! Yes! If key value of the
first record in index is changed to be the last record in index during the
phase of record processing, DO WHILE ! EOF() loop will iterate only this
single records even if the database contains millions of records. Your sould
do FLOCK() on DBF to guarantee the records are not changed. Do you use FLOCK()
before readonly DO WHILE ! EOF() loops? :)
2. Architecture
+-------------+
| |
| SQLMIX RDD |
| |
+-------------+
| ^
V |
+-------------+ +---------+
| |--->| |
| SQLBASE RDD | | SDD |
| |<---| |
+-------------+ +---------+
SQLBASE RDD implements basic functionality for accessing SQL query result
via RDD interface. This RDD could be used, if indexing of query result is not
necessary or all indexing is done by SQL server (by using ORDER BY clause).
SQLMIX RDD implements indexing of query result. This indexing is not
related to SQL server ORDER BY clause. SQLMIX do indexing of the query on the
client side.
SDD is acronym for Sql Database Driver. RDD is used to implement access
of different database formats like DBF, SDF, etc. SDD is used to implement
access of different SQL databases. Every SQL server (MySQL, PostgreSQL, etc.)
has a corresponding SDD. SDD driver implements a specific part of data
exchange interface between SQLBASE and SQL server.
A few additional functions are also implemented, ex. HB_SQLCONNECT().
Usualy these functions are just a shorter version of corresponding RDDINFO()
call.
3. Modifying database
SSI presents a query result via RDD interface and generates no hidden
SQL queries. So, how database can be changed? Does DBAPPEND() and FIELDPUT()
works, or is it readonly SQL interface?
DBAPPEND(), FIELDPUT() and other similiar functions work on cached query
result, i.e. query can be appended by new rows and field values can be
changed, but SQL database is not changed. DBCREATE() function can also be
used to create an "empty query result" but no table is created on SQL server.
So, SSI can also be used as implementation of "array RDD".
The programmer must call SQL command explicitly to modify SQL tables.
SSI provides a method to detect which cached rows was changed or appended.