Hi diogenes,
I didn't find yet where to change the pragma for sqlite via glorp, I didn't
have time until now and I'm on holidays for two weeks and I won't use my pc.
however I found that when I do one transaction for each insert it is very slow,
and one transaction for all (1000) inserts it is very fast (less than 1sec).
Here you'll find my code (unfinished but it's first try).
Beware that in the changeset there is my SQLitePlatform and SQLiteSequence code
so if you have done some work on it load only the Customer and
TpccGlorDescriptor classes.
Thoses classes (SQLite) are a slightly modified version of a copy of another
platform.
It does'nt retrieve row id yet.
Cheers
Alain
"Diogenes Moreira" <[email protected]> a écrit dans le message de
news: calwf4u6p3tas-ph9ew3ok5e-5r6c7kwzkeyrvgfcunfzs7n...@mail.gmail.com...
hi alan.
i dont know if sqlite implemetation has a problem.. but in glorp some times
do unnecesary read.. by example when you making "N times" CommitAndContinue..
and because it, you see a lot time spending in InputEventPollingFetcher>>wait.
if you send to me or send to SqueakDbx list you glorp code(ST), may be, I
can send to you some advices. or may be, we can find the delay source.
Best.
pd: please check in you sqlite the pragmas.. by example synchronous
(http://www.sqlite.org/pragma.html#pragma_synchronous) that increment the
performance to much.
On Tue, Jul 5, 2011 at 6:46 PM, Alain Rastoul <[email protected]> wrote:
Hi Mariano,
I don't want to do multi threading with sqlite because I know it doesn't
work.
I was curious about the squeakdbx (or opendbx architecture) because of the
not so good performance and the time spent in waiting , I do not understand the
squeakdbx package vs opendbx package: the doc is mentioning a squeakdbx plugin
dll but I have no squeakdbx dll ?
You are saying that in that case the external call is counted on the
InputEventPollingFetcher>> wait and not in primitives (?).
I will investigate with FFI/SQlite and it should be the same (I've seen
some messages about incorrect profiling reports in primitives),
I expected much better performance with sqlite , and glorp is very good
(5% of the time), I would have expected the contrary.
Thanks
Cheers
Alain
"Mariano Martinez Peck" <[email protected]> a écrit dans le message
de
news:CAA+-=mvv3zvpcfpm3uwts11y1ugxpcji6pzxypvjpztfsdrrdq-jsoawuisxosn+bqq9rb...@public.gmane.org...
On Tue, Jul 5, 2011 at 10:50 PM, Alain Rastoul <[email protected]> wrote:
Hi,
(sorry for sending this mail again, my pc was off for a long time and
the
message was dated from 2007, people who sort their messages would not
see
it)
I've done a small program in Pharo 1.3 with glorp+opendbx that insert
1000
rows in a customer table in a sqlite db.
The 1000 insert takes 140 sec (very slow), but the Pharo profiler says
that
it spend 95%
of the time waiting for input.
(in InputEventPollingFetcher>> waitForInput)
I was wondering if the queries are executed in another thread than the
vm
thread ?
Hi Alain. No. Squeak/Pharo's thread architecture is the so called green
thread, that is, only ONE OS thread is used. Internally, the language reifies
Process, Scheduler, #fork: , etc etc etc. But from the OS point of view there
is only one thread for the VM. So.....the regular FFI blocks the VM. What does
it mean? that while the C function called by FFI is being executed, the WHOLE
VM is block. Notihgn can happen at the same time. Imagine the function that
retrieves the results and needs to wait for them.....TERRIBLE. So...if the
backend does not support async quieries, then you are screw and dbx may be slow
in Pharo. Nothing to do.
However, some backends support async queries, and opendbx let us
configure this. This is explained in:
http://www.squeakdbx.org/Architecture%20and%20desing?_s=FlIhkPQOOFSlqf8C&_k=j-3_7Kw_&_n&18
where it says "External call implementation"
You can see the list of backends that support async queries in here:
http://www.squeakdbx.org/documentation/Asynchronous%20queries?_s=FlIhkPQOOFSlqf8C&_k=j-3_7Kw_&_n&17
Notice that there is some room for improvements, but we didn't have time
so far. Hernik told us some good ideas. But since we didn't need more power so
far we couldn't find time to integrate his ideas. I am forwarding now the
emails to the mailing list. If you can take a look and provide code, it would
be awesome. Basically, it improves how and how much we wait in each side: image
and opendbx.
Finally, notice that Eliot is working in a multithreared FFI for Cog, but
it is not yet available as far as I know.
Cheers
Mariano
(I thought I've seen a document about opendbx architecture but could'nt
find
it on the site).
TIA
Alain
------------------------------------------------------------------------------
All of the data generated in your IT infrastructure is seriously
valuable.
Why? It contains a definitive record of application performance,
security
threats, fraudulent activity, and more. Splunk takes this data and makes
sense of it. IT sense. And common sense.
http://p.sf.net/sfu/splunk-d2d-c2
_______________________________________________
libopendbx-devel mailing list
libopendbx-devel-5nwgofrqmnerv+lv9mx5uipxlwaovq5f-xmd5yjdbdmrexy1tmh2...@public.gmane.org
https://lists.sourceforge.net/lists/listinfo/libopendbx-devel
http://www.linuxnetworks.de/doc/index.php/OpenDBX
--
Mariano
http://marianopeck.wordpress.com
--------------------------------------------------------------------------
------------------------------------------------------------------------------
All of the data generated in your IT infrastructure is seriously valuable.
Why? It contains a definitive record of application performance, security
threats, fraudulent activity, and more. Splunk takes this data and makes
sense of it. IT sense. And common sense.
http://p.sf.net/sfu/splunk-d2d-c2
--------------------------------------------------------------------------
------------------------------------------------------------------------------
All of the data generated in your IT infrastructure is seriously valuable.
Why? It contains a definitive record of application performance, security
threats, fraudulent activity, and more. Splunk takes this data and makes
sense of it. IT sense. And common sense.
http://p.sf.net/sfu/splunk-d2d-c2
_______________________________________________
libopendbx-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/libopendbx-devel
http://www.linuxnetworks.de/doc/index.php/OpenDBX
------------------------------------------------------------------------------
------------------------------------------------------------------------------
All of the data generated in your IT infrastructure is seriously valuable.
Why? It contains a definitive record of application performance, security
threats, fraudulent activity, and more. Splunk takes this data and makes
sense of it. IT sense. And common sense.
http://p.sf.net/sfu/splunk-d2d-c2
------------------------------------------------------------------------------
'From Pharo1.3 of 16 June 2011 [Latest update: #13269] on 8 July 2011 at
9:51:53 pm'!
Object subclass: #DBConnection
instanceVariableNames: 'connection'
classVariableNames: ''
poolDictionaries: ''
category: 'Tpcc-Model'!
Object subclass: #Customer
instanceVariableNames: 'id wareHouseId districtId firstName lastName
middle address1 address2 city state zip country phone since credit creditLim
balance ytdPayment paymentCnt deliveryCnt'
classVariableNames: ''
poolDictionaries: ''
category: 'Tpcc-Model'!
!Customer commentStamp: 'AlainRastoul 7/7/2011 16:19' prior: 0!
I am a customer in the tpcc benchmark system.
Instance Variables:
id : (C_ID) unique customer id . 96,000 unique IDs, 3,000 are
populated per district.
integer
wareHouseId : (C_W_ID) 2*W unique IDs
districtId : (C_D_ID) 20 unique IDs
firstName : (C_FIRST) variable text, size 64 (16 in tpcc benchemark)
lastName (C_LAST) variable text, size 64 (16 in tpcc
benchemark)
middle (C_MIDDLE) fixed text, size 2
address1 <ProtoObject | PseudoContext>
address2 <ProtoObject | PseudoContext>
city <ProtoObject | PseudoContext>
state <ProtoObject | PseudoContext>
zip <ProtoObject | PseudoContext>
country <ProtoObject | PseudoContext>
phone <ProtoObject | PseudoContext>
since <ProtoObject | PseudoContext>
credit <ProtoObject | PseudoContext>
creditLim <ProtoObject | PseudoContext>
balance <ProtoObject | PseudoContext>
ytdPayment <ProtoObject | PseudoContext>
paymentCnt <ProtoObject | PseudoContext>
deliveryCnt <ProtoObject | PseudoContext>
from TPCC benchmark:
Primary Key: (C_W_ID, C_D_ID, C_ID)
(C_W_ID, C_D_ID) Foreign Key, references (D_W_ID, D_ID)
!
NamedSequence subclass: #SQLiteSequence
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'Glorp-Database'!
DatabasePlatform subclass: #SQLitePlatform
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'Glorp-Database'!
Smalltalk renameClassNamed: #TpccGlorpDescriptor as: #TpccGlorpDescriptor!
DescriptorSystem subclass: #TpccGlorpDescriptor
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'Tpcc-Model'!
!DBConnection methodsFor: 'as yet unclassified' stamp: 'AlainRastoul 7/4/2011
21:59'!
connection
^connection! !
!DBConnection methodsFor: 'as yet unclassified' stamp: 'AlainRastoul 7/4/2011
21:47'!
connection: anObject
connection := anObject! !
!DBConnection class methodsFor: 'as yet unclassified' stamp: 'AlainRastoul
7/4/2011 21:54'!
sqlite: aDb
"comment stating purpose of message"
| settings dbc |
settings := DBXConnectionSettings
host: SmalltalkImage current imagePath, '/'
port: ''
database: aDb
userName: ''
userPassword: ''.
dbc := DBConnection new connection: (DBXConnection platform:
DBXSqlitePlatform new settings: settings).
^dbc
! !
!Customer methodsFor: 'accessing' stamp: 'AlainRastoul 7/7/2011 21:29'!
address1
^address1! !
!Customer methodsFor: 'accessing' stamp: 'AlainRastoul 7/7/2011 21:29'!
address1: anObject
address1 := anObject! !
!Customer methodsFor: 'accessing' stamp: 'AlainRastoul 7/7/2011 21:29'!
address2
^address2! !
!Customer methodsFor: 'accessing' stamp: 'AlainRastoul 7/7/2011 21:29'!
address2: anObject
address2 := anObject! !
!Customer methodsFor: 'accessing' stamp: 'AlainRastoul 7/7/2011 21:29'!
balance
^balance! !
!Customer methodsFor: 'accessing' stamp: 'AlainRastoul 7/7/2011 21:29'!
balance: anObject
balance := anObject! !
!Customer methodsFor: 'accessing' stamp: 'AlainRastoul 7/7/2011 21:29'!
city
^city! !
!Customer methodsFor: 'accessing' stamp: 'AlainRastoul 7/7/2011 21:29'!
city: anObject
city := anObject! !
!Customer methodsFor: 'accessing' stamp: 'AlainRastoul 7/7/2011 21:29'!
country
^country! !
!Customer methodsFor: 'accessing' stamp: 'AlainRastoul 7/7/2011 21:29'!
country: anObject
country := anObject! !
!Customer methodsFor: 'accessing' stamp: 'AlainRastoul 7/7/2011 21:29'!
credit
^credit! !
!Customer methodsFor: 'accessing' stamp: 'AlainRastoul 7/7/2011 21:29'!
credit: anObject
credit := anObject! !
!Customer methodsFor: 'accessing' stamp: 'AlainRastoul 7/7/2011 21:29'!
creditLim
^creditLim! !
!Customer methodsFor: 'accessing' stamp: 'AlainRastoul 7/7/2011 21:29'!
creditLim: anObject
creditLim := anObject! !
!Customer methodsFor: 'accessing' stamp: 'AlainRastoul 7/7/2011 21:29'!
deliveryCnt
^deliveryCnt! !
!Customer methodsFor: 'accessing' stamp: 'AlainRastoul 7/7/2011 21:29'!
deliveryCnt: anObject
deliveryCnt := anObject! !
!Customer methodsFor: 'accessing' stamp: 'AlainRastoul 7/7/2011 21:29'!
districtId
^districtId! !
!Customer methodsFor: 'accessing' stamp: 'AlainRastoul 7/7/2011 21:29'!
districtId: anObject
districtId := anObject! !
!Customer methodsFor: 'accessing' stamp: 'AlainRastoul 7/7/2011 21:29'!
firstName
^firstName! !
!Customer methodsFor: 'accessing' stamp: 'AlainRastoul 7/7/2011 21:29'!
firstName: anObject
firstName := anObject! !
!Customer methodsFor: 'accessing' stamp: 'AlainRastoul 7/7/2011 21:29'!
id
^id! !
!Customer methodsFor: 'accessing' stamp: 'AlainRastoul 7/7/2011 21:29'!
id: anObject
id := anObject! !
!Customer methodsFor: 'accessing' stamp: 'AlainRastoul 7/7/2011 21:29'!
lastName
^lastName! !
!Customer methodsFor: 'accessing' stamp: 'AlainRastoul 7/7/2011 21:29'!
lastName: anObject
lastName := anObject! !
!Customer methodsFor: 'accessing' stamp: 'AlainRastoul 7/7/2011 21:29'!
middle
^middle! !
!Customer methodsFor: 'accessing' stamp: 'AlainRastoul 7/7/2011 21:29'!
middle: anObject
middle := anObject! !
!Customer methodsFor: 'accessing' stamp: 'AlainRastoul 7/7/2011 21:29'!
paymentCnt
^paymentCnt! !
!Customer methodsFor: 'accessing' stamp: 'AlainRastoul 7/7/2011 21:29'!
paymentCnt: anObject
paymentCnt := anObject! !
!Customer methodsFor: 'accessing' stamp: 'AlainRastoul 7/7/2011 21:29'!
phone
^phone! !
!Customer methodsFor: 'accessing' stamp: 'AlainRastoul 7/7/2011 21:29'!
phone: anObject
phone := anObject! !
!Customer methodsFor: 'accessing' stamp: 'AlainRastoul 7/7/2011 21:29'!
since
^since! !
!Customer methodsFor: 'accessing' stamp: 'AlainRastoul 7/7/2011 21:29'!
since: anObject
since := anObject! !
!Customer methodsFor: 'accessing' stamp: 'AlainRastoul 7/7/2011 21:29'!
state
^state! !
!Customer methodsFor: 'accessing' stamp: 'AlainRastoul 7/7/2011 21:29'!
state: anObject
state := anObject! !
!Customer methodsFor: 'accessing' stamp: 'AlainRastoul 7/7/2011 21:29'!
wareHouseId
^wareHouseId! !
!Customer methodsFor: 'accessing' stamp: 'AlainRastoul 7/7/2011 21:29'!
wareHouseId: anObject
wareHouseId := anObject! !
!Customer methodsFor: 'accessing' stamp: 'AlainRastoul 7/7/2011 21:29'!
ytdPayment
^ytdPayment! !
!Customer methodsFor: 'accessing' stamp: 'AlainRastoul 7/7/2011 21:29'!
ytdPayment: anObject
ytdPayment := anObject! !
!Customer methodsFor: 'accessing' stamp: 'AlainRastoul 7/7/2011 21:29'!
zip
^zip! !
!Customer methodsFor: 'accessing' stamp: 'AlainRastoul 7/7/2011 21:29'!
zip: anObject
zip := anObject! !
!Customer class methodsFor: 'as yet unclassified' stamp: 'AlainRastoul 7/4/2011
20:24'!
glorpSetupDescriptor: aDescriptor forSystem: aSystem
| table |
table := aSystem tableNamed: 'Customer'.
aDescriptor table: table.! !
!Customer class methodsFor: 'benchmarks-utilities' stamp: 'AlainRastoul
7/7/2011 21:32'!
newLoginForSQLite
"get a login on a sqlite test db"
^Login new database: SQLitePlatform new;
username: '';
password: '';
host: SmalltalkImage current imagePath, '/' ;
connectString: 'testdb.dat'.
! !
!Customer class methodsFor: 'benchmarks-utilities' stamp: 'AlainRastoul
7/8/2011 20:56'!
newPopulation
" a random Customer population generator for benchmarks
self newPopulation.
"
| customers |
customers := (1 to: 1000) inject: OrderedCollection new
into: [:all :one |
|customer |
customer := Customer new
"id: one;" " let the db geenrate the id
an retrieve it "
wareHouseId: 1;
districtId: 2;
firstName: self pickAFirstName;
lastName: self pickAName.
all add: customer.
all].
^customers. ! !
!Customer class methodsFor: 'benchmarks-utilities' stamp: 'AlainRastoul
7/8/2011 20:56'!
newSessionForLogin: aLogin accessor: anAccessor
" returns a new session for the given login"
| session |
session := GlorpSession new
system: (TpccGlorpDescriptor forPlatform:
aLogin database) ;
accessor: anAccessor.
^session! !
!Customer class methodsFor: 'benchmarks-utilities' stamp: 'AlainRastoul
7/8/2011 21:16'!
pickACountryAndStoreFor: aCustomer
" pick a random country and ware house id
"
| adresses |
self flag: #todo.
adresses := #( " country towns zipcode and street names"
#('Scottland'
#("town zipcodes"
#( 'Edimburgh' 'EHXX')
#('Aberdeen' 'ABXX')
#('Inverness' 'IVXX' )
)
#( "street names")
)
#('France'
#("town zipcodes"
#( 'Paris' '75XXX')
#('Lyon' '69XXX')
#('Marseille' '13XXX' )
)
#( "street names")
)
).
! !
!Customer class methodsFor: 'benchmarks-utilities' stamp: 'AlainRastoul
7/8/2011 20:57'!
pickAFirstName
" pick a random first name from a predefined list
"
^#( 'John' 'Roger' 'Stephan' 'Mike' 'Julia' 'Elisabeth' 'Mary'
'Dave' 'Edgar' 'Gertrud' 'Elmut' 'Veronica' 'Alex' ) atRandom.
! !
!Customer class methodsFor: 'benchmarks-utilities' stamp: 'AlainRastoul
7/8/2011 20:57'!
pickAName
" random Customer names generator from the tpcc benchmark specification
nb: slightly different implementation
p64. The customer last name (C_LAST) must be generated by the concatenation of
three variable length syllables selected from the following list:
0 1 2 3 4 5 6 7 8 9
BAR OUGHT ABLE PRI PRES ESE ANTI CALLY ATION EING
Given a number between 0 and 999, each of the three syllables is determined by
the corresponding digit in the three digit representation of the number. For
example, the number 371 generates the name PRICALLYOUGHT, and the number 40
generates the name BARPRESBAR."
| syllabes aName|
syllabes := #( 'BAR' 'OUGHT' 'ABLE' 'PRI' 'PRES' 'ESE' 'ANTI' 'CALLY'
'ATION' 'EING' ).
aName := WriteStream on: String new.
3 timesRepeat: [ aName nextPutAll: syllabes atRandom ].
^aName contents.
! !
!Customer class methodsFor: 'benchmarks' stamp: 'AlainRastoul 7/7/2011 21:29'!
createTablesIn: session accessor: accessor
" create the tables "
session reset.
session inTransactionDo:
[session system allTables do:
[:each |
accessor
createTable: each
ifError: [:error |Transcript show: error
messageText]]].
! !
!Customer class methodsFor: 'benchmarks' stamp: 'AlainRastoul 7/8/2011 20:56'!
insertDataIn: aSession
| list |
aSession reset.
list := Customer newPopulation .
TimeProfileBrowser onBlock: [
aSession beginUnitOfWork.
list do:
[ :customer |
aSession register: customer ].
aSession commitUnitOfWork.
].
! !
!Customer class methodsFor: 'benchmarks' stamp: 'AlainRastoul 7/7/2011 21:31'!
newCustomersBench
"A small benchmark that creates a list of customers and insert thoses
customer in a database
self newCustomersBench
"
| login accessor session list |
DBXPlatform enableDebugMode .
login := self newLoginForSQLite.
accessor := DatabaseAccessor forLogin: login.
accessor login.
session := self newSessionForLogin: login accessor: accessor.
self createTablesIn: session accessor: accessor.
self insertDataIn: session.
session logout! !
!SQLiteSequence methodsFor: 'sequencing' stamp: 'AlainRastoul 7/4/2011 23:30'!
getSequenceValueFromDatabaseFor: aField in: aRow using: aSession! !
!SQLiteSequence methodsFor: 'sequencing' stamp: 'AlainRastoul 7/4/2011 23:30'!
postWriteAssignSequenceValueFor: aDatabaseField in: aDatabaseRow using:
anAccessor
aDatabaseRow at: aDatabaseField
put: ((anAccessor
executeSQLString: 'select last_insert_rowid()')
first atIndex: 1).! !
!SQLiteSequence methodsFor: 'sequencing' stamp: 'AlainRastoul 7/4/2011 23:30'!
reserveSequenceNumbers: anInteger in: aSession for: aTable
"No real sequences here, just identity columns, which we can't
pre-allocate"! !
!SQLiteSequence methodsFor: 'testing' stamp: 'AlainRastoul 7/4/2011 23:30'!
isIdentityColumn
^true.! !
!SQLiteSequence class methodsFor: 'LICENSE' stamp: 'AlainRastoul 7/4/2011
23:30'!
LICENSE
^'Copyright 2000-2004 Alan Knight.
This class is part of the GLORP system (see http://www.glorp.org), licensed
under the GNU Lesser General Public License, with clarifications with respect
to Smalltalk library usage (LGPL(S)). This code is distributed WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE . See the package comment, or the COPYING.TXT file that
should accompany this distribution, or the GNU Lesser General Public License.'!
!
!SQLitePlatform methodsFor: 'constants' stamp: 'AlainRastoul 7/4/2011 21:17'!
areSequencesExplicitlyCreated
^false! !
!SQLitePlatform methodsFor: 'constants' stamp: 'AlainRastoul 7/4/2011 21:17'!
asSqueakDBXAdaptor
^DBXSqlitePlatform new.! !
!SQLitePlatform methodsFor: 'constants' stamp: 'AlainRastoul 7/5/2011 20:06'!
databaseSequenceClass
^SQLiteSequence.! !
!SQLitePlatform methodsFor: 'constants' stamp: 'AlainRastoul 7/4/2011 20:00'!
initializeReservedWords
super initializeReservedWords.
reservedWords add: 'key'! !
!SQLitePlatform methodsFor: 'constants' stamp: 'AlainRastoul 7/4/2011 20:00'!
maximumLengthOfColumnName
"^<Integer> I return the max. length of a column name"
^128! !
!SQLitePlatform methodsFor: 'constants' stamp: 'AlainRastoul 7/4/2011 20:00'!
maximumLengthOfTableName
"^<Integer> I return the max. length of a table name"
^128! !
!SQLitePlatform methodsFor: 'constants' stamp: 'AlainRastoul 7/4/2011 20:00'!
supportsConstraints
^true! !
!SQLitePlatform methodsFor: 'constants' stamp: 'AlainRastoul 7/4/2011 20:00'!
supportsMillisecondsInTimes
"I'm guessing here"
^true.! !
!SQLitePlatform methodsFor: 'binding' stamp: 'AlainRastoul 7/4/2011 20:00'!
bindingsForGroupWritingFor: aCommand
"Return the bindings array for a group write. This can be in different
formats, depending on the database and perhaps the mechanism in place."
^aCommand batchStatementBindings.! !
!SQLitePlatform methodsFor: 'binding' stamp: 'AlainRastoul 7/4/2011 20:00'!
maximumSizeToGroupWriteFor: aCollectionOfDatabaseRows
"If we are going to group write, how many rows of this collection
should we do it for at once"
^aCollectionOfDatabaseRows size min: 250.! !
!SQLitePlatform methodsFor: 'types' stamp: 'AlainRastoul 7/4/2011 21:43'!
bit
^self typeNamed: #bit ifAbsentPut: [GlorpBooleanType new typeString:
'tinyint'].! !
!SQLitePlatform methodsFor: 'types' stamp: 'AlainRastoul 7/4/2011 21:41'!
blob
^self typeNamed: #blob ifAbsentPut: [GlorpBlobType new typeString:
'blob'; queryType: (self varbinary)].! !
!SQLitePlatform methodsFor: 'types' stamp: 'AlainRastoul 7/4/2011 20:00'!
boolean
^self bit.! !
!SQLitePlatform methodsFor: 'types' stamp: 'AlainRastoul 7/4/2011 20:00'!
char
^self typeNamed: #char ifAbsentPut: [GlorpCharType new].! !
!SQLitePlatform methodsFor: 'types' stamp: 'AlainRastoul 7/4/2011 20:00'!
clob
^self typeNamed: #clob ifAbsentPut: [GlorpClobType new typeString:
'text'].! !
!SQLitePlatform methodsFor: 'types' stamp: 'AlainRastoul 7/4/2011 21:39'!
date
^self typeNamed: #date ifAbsentPut: [GlorpDateType new typeString:
'date'].! !
!SQLitePlatform methodsFor: 'types' stamp: 'AlainRastoul 7/4/2011 20:00'!
decimal
^self numeric.! !
!SQLitePlatform methodsFor: 'types' stamp: 'AlainRastoul 7/4/2011 20:00'!
double
^self float.! !
!SQLitePlatform methodsFor: 'types' stamp: 'AlainRastoul 7/4/2011 20:00'!
float
^self typeNamed: #float ifAbsentPut: [GlorpMSSQLFloatType new].! !
!SQLitePlatform methodsFor: 'types' stamp: 'AlainRastoul 7/4/2011 20:00'!
float4
^self float.! !
!SQLitePlatform methodsFor: 'types' stamp: 'AlainRastoul 7/4/2011 20:00'!
float8
^self float.! !
!SQLitePlatform methodsFor: 'types' stamp: 'AlainRastoul 7/4/2011 20:00'!
int
^self integer.! !
!SQLitePlatform methodsFor: 'types' stamp: 'AlainRastoul 7/4/2011 20:00'!
int2
^self smallint.! !
!SQLitePlatform methodsFor: 'types' stamp: 'AlainRastoul 7/4/2011 20:00'!
int4
^self integer.! !
!SQLitePlatform methodsFor: 'types' stamp: 'AlainRastoul 7/4/2011 20:00'!
int8
^self numeric.! !
!SQLitePlatform methodsFor: 'types' stamp: 'AlainRastoul 7/4/2011 20:00'!
numeric
^self typeNamed: #numeric ifAbsentPut: [GlorpNumericType new].! !
!SQLitePlatform methodsFor: 'types' stamp: 'AlainRastoul 7/4/2011 20:00'!
real
^self float.! !
!SQLitePlatform methodsFor: 'types' stamp: 'AlainRastoul 7/4/2011 20:00'!
sequence
^self serial.! !
!SQLitePlatform methodsFor: 'types' stamp: 'AlainRastoul 7/4/2011 21:46'!
serial
^self typeNamed: #serial ifAbsentPut: [GlorpSerialType new typeString:
'int autoincrement '].! !
!SQLitePlatform methodsFor: 'types' stamp: 'AlainRastoul 7/4/2011 20:00'!
text
^super text queryType: self varchar.! !
!SQLitePlatform methodsFor: 'types' stamp: 'AlainRastoul 7/4/2011 20:00'!
time
^self typeNamed: #time ifAbsentPut: [GlorpTimeType new typeString:
'datetime'].! !
!SQLitePlatform methodsFor: 'types' stamp: 'AlainRastoul 7/4/2011 20:00'!
timeStampTypeString
^'datetime'.! !
!SQLitePlatform methodsFor: 'types' stamp: 'AlainRastoul 7/4/2011 20:00'!
timestamp
^self typeNamed: #timestamp ifAbsentPut: [GlorpTimeStampType new
typeString: 'datetime'].! !
!SQLitePlatform methodsFor: 'types' stamp: 'AlainRastoul 7/4/2011 20:00'!
tinyint
^self typeNamed: #tinyInt ifAbsentPut: [GlorpIntegerType new
typeString: 'tinyint'].! !
!SQLitePlatform methodsFor: 'types' stamp: 'AlainRastoul 7/4/2011 20:00'!
varbinary
^self typeNamed: #varbinary ifAbsentPut: [GlorpVarBinaryType new].! !
!SQLitePlatform methodsFor: 'types' stamp: 'AlainRastoul 7/4/2011 20:00'!
varchar
^self typeNamed: #varchar ifAbsentPut: [GlorpVarCharType new].! !
!SQLitePlatform methodsFor: 'conversion-boolean' stamp: 'AlainRastoul 7/4/2011
20:00'!
booleanToBooleanConverter
^DelegatingDatabaseConverter
named: #booleanToBoolean
hostedBy: self
fromStToDb: #convertBooleanToInteger:for:
fromDbToSt: #convertDBBooleanToBoolean:for:.! !
!SQLitePlatform methodsFor: 'conversion-strings' stamp: 'AlainRastoul 7/4/2011
20:00'!
charactersThatNeedEscaping
"There seem to be all kind of contradictory bits of information about
what sql server does/requires for escaped characters, all of which differ from
standard sql. Empirically the only thing that requires escaping appears to be
single quote"
^#($' ).! !
!SQLitePlatform methodsFor: 'conversion-strings' stamp: 'AlainRastoul 7/4/2011
20:00'!
escapeFor: aCharacter
^String with: $' with: aCharacter.
" ^'\', (aCharacter asInteger printStringRadix: 16)."! !
!SQLitePlatform methodsFor: 'conversion-strings' stamp: 'AlainRastoul 7/4/2011
20:00'!
printBlob: aByteArray on: aStream for: aType
aByteArray isNil ifTrue: [^aStream nextPutAll: 'NULL'].
aStream nextPutAll: '0x'.
aByteArray do: [:each |
each printOn: aStream paddedWith: $0 to: 2 base: 16].! !
!SQLitePlatform methodsFor: 'database-specific' stamp: 'AlainRastoul 7/4/2011
20:00'!
compoundOperationFor: aSymbol
"Return the platform specific version of a compound statement symbol"
aSymbol == #INTERSECT ifTrue: [^'WHERE EXISTS'].
aSymbol == #MINUS ifTrue: [^'WHERE NOT EXISTS'].
^aSymbol.! !
!SQLitePlatform methodsFor: 'database-specific' stamp: 'AlainRastoul 7/5/2011
21:46'!
printPostLimit: anInteger on: aCommand
aCommand
nextPutAll: ' LIMIT '.
anInteger printOn: aCommand.! !
!SQLitePlatform methodsFor: 'database-specific' stamp: 'AlainRastoul 7/4/2011
20:00'!
queryWithUnsupportedOperationsEliminatedFrom: aQuery do: aBlock
"If aQuery has operations that we don't support, rewrite it to do them
in terms of lower level operations. In particular, rewrite INTERSECT/EXCEPT
operations into EXISTS clauses in a single query. Pass the new query to aBlock."
| newQuery |
newQuery := aQuery rewriteIntersect.
newQuery := newQuery rewriteExcept.
newQuery == aQuery ifFalse: [aBlock value: newQuery].! !
!SQLitePlatform methodsFor: 'conversion-times' stamp: 'AlainRastoul 7/4/2011
20:00'!
dateConverter
"SQL server doesn't have plain dates, and doesn't accept them"
^DelegatingDatabaseConverter
named: #date
hostedBy: self
fromStToDb: #dateToTimestampConversion:for:
fromDbToSt: #readDate:for:. "#printDate:for:"! !
!SQLitePlatform methodsFor: 'conversion-times' stamp: 'AlainRastoul 7/4/2011
21:17'!
dateToTimestampConversion: aDate for: aType
aDate isNil ifTrue: [^aDate].
^aDate asTimestamp.! !
!SQLitePlatform methodsFor: 'conversion-times' stamp: 'AlainRastoul 7/4/2011
20:00'!
printDate: aDate for: aType
"Print a date (or timestamp) as yyyy-mm-dd"
| stream |
aDate isNil ifTrue: [^'NULL'].
stream := WriteStream on: String new.
stream nextPutAll: '{ d '''.
self
printDate: aDate
isoFormatOn: stream.
stream nextPutAll: ''' }'.
^stream contents.! !
!SQLitePlatform methodsFor: 'conversion-times' stamp: 'AlainRastoul 7/4/2011
20:00'!
printTime: aTime for: aType
"Print a time (or timestamp) as hh:mm:ss.fff"
| stream |
aTime isNil ifTrue: [^'NULL'].
stream := WriteStream on: String new.
stream nextPutAll: '{ t '''.
self
printTime: aTime
isoFormatOn: stream
milliseconds: self supportsMillisecondsInTimes.
stream nextPutAll: ''' }'.
^stream contents.! !
!SQLitePlatform methodsFor: 'conversion-times' stamp: 'AlainRastoul 7/4/2011
20:00'!
printTimestamp: aTimestamp on: stream for: aType
aTimestamp isNil ifTrue: [stream nextPutAll: 'NULL'. ^self].
stream nextPutAll: '{ ts '''.
self
printDate: aTimestamp
isoFormatOn: stream.
stream nextPutAll: ' '.
self
printTime: aTimestamp
isoFormatOn: stream.
stream nextPutAll: ''' }'.! !
!SQLitePlatform methodsFor: 'exdi specific' stamp: 'AlainRastoul 7/4/2011
20:00'!
exdiTypeForDates
^#Timestamp.! !
!SQLitePlatform methodsFor: 'functions' stamp: 'AlainRastoul 7/4/2011 20:00'!
initializeFunctions
super initializeFunctions.
functions
at: #, put: (InfixFunction named: '+');
at: #copyFrom:to: put: (SubstringFunction named: 'SUBSTRING')! !
!SQLitePlatform methodsFor: 'testing' stamp: 'AlainRastoul 7/4/2011 21:38'!
isODBCPlatform
^false! !
!SQLitePlatform methodsFor: 'testing' stamp: 'AlainRastoul 7/4/2011 20:00'!
supportsANSIJoins
"Do we support the JOIN <tableName> USING <criteria> syntax. Currently
hard-coded, but may also vary by database version"
^true.! !
!SQLitePlatform methodsFor: 'testing' stamp: 'AlainRastoul 7/4/2011 20:08'!
supportsBinding
"Binding works only with VW EXDI so far"
^true.! !
!SQLitePlatform methodsFor: 'testing' stamp: 'AlainRastoul 7/4/2011 20:00'!
supportsDecimalsOnAllNumerics
"Return true if a general 'numeric' type will allow numbers after the
decimal place"
^false.! !
!SQLitePlatform methodsFor: 'testing' stamp: 'AlainRastoul 7/4/2011 20:00'!
supportsGroupWritingFor: aCommand
^aCommand supportsGroupWriting.! !
!SQLitePlatform methodsFor: 'testing' stamp: 'AlainRastoul 7/4/2011 20:00'!
supportsLimit
"Do we support anything analogous to the postgresql LIMIT, returning
only the first N rows"
^true.! !
!SQLitePlatform methodsFor: 'testing' stamp: 'AlainRastoul 7/4/2011 20:00'!
supportsMultipleOpenCursors
"Can this database support multiple open cursors at once"
^false.! !
!SQLitePlatform methodsFor: 'testing' stamp: 'AlainRastoul 7/5/2011 21:48'!
supportsTableOwners
"Return true if this platform supports table owners, i.e. expects table
names of the form Bern.TW_* rather than just TW_* in its SQL."
"Access, Firebird and PostGreSQL do not, Oracle does, others I know not."
^false! !
!SQLitePlatform methodsFor: 'testing' stamp: 'AlainRastoul 7/4/2011 20:00'!
usesArrayBindingRatherThanGrouping
"Return true if we use array binding for grouped writes rather than
printing the sql multiple times. Only applies if we support grouped writes"
^false.! !
!SQLitePlatform methodsFor: 'testing' stamp: 'AlainRastoul 7/4/2011 20:00'!
usesIdentityColumns
^true.! !
!SQLitePlatform class methodsFor: 'LICENSE' stamp: 'AlainRastoul 7/4/2011
20:00'!
LICENSE
^'Copyright 2000-2004 Alan Knight.
This class is part of the GLORP system (see http://www.glorp.org), licensed
under the GNU Lesser General Public License, with clarifications with respect
to Smalltalk library usage (LGPL(S)). This code is distributed WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE . See the package comment, or the COPYING.TXT file that
should accompany this distribution, or the GNU Lesser General Public License.'!
!
!TpccGlorpDescriptor methodsFor: 'as yet unclassified' stamp: 'AlainRastoul
7/4/2011 20:16'!
allTableNames
^#( 'Customer' )! !
!TpccGlorpDescriptor methodsFor: 'as yet unclassified' stamp: 'AlainRastoul
7/4/2011 20:25'!
classModelForCustomer: aClassModel
"0 halt."
aClassModel newAttributeNamed: #id.
aClassModel newAttributeNamed: #wareHouseId.
aClassModel newAttributeNamed: #districtId.
aClassModel newAttributeNamed: #firstName.
aClassModel newAttributeNamed: #lastName.
aClassModel newAttributeNamed: #address1.
aClassModel newAttributeNamed: #address2.
aClassModel newAttributeNamed: #city.
aClassModel newAttributeNamed: #state.
aClassModel newAttributeNamed: #zip.
aClassModel newAttributeNamed: #country.
! !
!TpccGlorpDescriptor methodsFor: 'as yet unclassified' stamp: 'AlainRastoul
7/4/2011 20:25'!
constructAllClasses
"0 halt."
^(super constructAllClasses)
add: Customer;
yourself ! !
!TpccGlorpDescriptor methodsFor: 'as yet unclassified' stamp: 'AlainRastoul
7/4/2011 20:24'!
descriptorForCustomer: aDescriptor
| table |
" 0 halt."
table := self tableNamed: 'Customer'.
aDescriptor table: table.
(aDescriptor newMapping: DirectMapping) from: #id to: (table
fieldNamed: 'id').
(aDescriptor newMapping: DirectMapping) from: #wareHouseId to: (table
fieldNamed: 'wareHouseId').
(aDescriptor newMapping: DirectMapping) from: #districtId to: (table
fieldNamed: 'districtId').
(aDescriptor newMapping: DirectMapping) from: #firstName to: (table
fieldNamed: 'firstName').
(aDescriptor newMapping: DirectMapping) from: #lastName to: (table
fieldNamed: 'lastName').
(aDescriptor newMapping: DirectMapping) from: #address1 to: (table
fieldNamed: 'address1').
(aDescriptor newMapping: DirectMapping) from: #address2 to: (table
fieldNamed: 'address2').
(aDescriptor newMapping: DirectMapping) from: #city to: (table
fieldNamed: 'city').
(aDescriptor newMapping: DirectMapping) from: #state to: (table
fieldNamed: 'state').
(aDescriptor newMapping: DirectMapping) from: #zip to: (table
fieldNamed: 'zip').
(aDescriptor newMapping: DirectMapping) from: #country to: (table
fieldNamed: 'country').
! !
!TpccGlorpDescriptor methodsFor: 'as yet unclassified' stamp: 'AlainRastoul
7/5/2011 20:58'!
tableForCUSTOMER: aTable
"id wareHouseId districtId firstName lastName middle address1 address2
city state zip phone since credit creditLim balance ytdPayment paymentCnt
deliveryCnt"
"0 halt."
" (aTable createFieldNamed: 'wareHouseId' type: (platform integer))
bePrimaryKey.
(aTable createFieldNamed: 'districtId' type: (platform integer))
bePrimaryKey.
(aTable createFieldNamed: 'id' type: (platform integer) ) bePrimaryKey .
"
aTable createFieldNamed: 'wareHouseId' type: (platform integer).
aTable createFieldNamed: 'districtId' type: (platform integer).
(aTable createFieldNamed: 'id' type: (platform integer)) bePrimaryKey .
aTable createFieldNamed: 'firstName' type: (platform varChar: 64).
aTable createFieldNamed: 'lastName' type: (platform varChar: 64).
aTable createFieldNamed: 'middle' type: (platform char: 2).
aTable createFieldNamed: 'address1' type: (platform varChar: 64).
aTable createFieldNamed: 'address2' type: (platform varChar: 64).
aTable createFieldNamed: 'city' type: (platform varChar: 64).
aTable createFieldNamed: 'state' type: (platform char: 64).
aTable createFieldNamed: 'zip' type: (platform char: 16).
aTable createFieldNamed: 'country' type: (platform char: 64).
aTable createFieldNamed: 'phone' type: (platform varChar: 64).
! !
TpccGlorpDescriptor removeSelector: #descriptorForCUSTOMER:!
TpccGlorpDescriptor removeSelector: #descriptorForPerson:!
TpccGlorpDescriptor removeSelector: #tableForCustomer:!
SQLitePlatform removeSelector: #printPreLimit:on:!
SQLitePlatform removeSelector: #useMicrosoftOuterJoins!
Customer class removeSelector: #generate!
Customer class removeSelector: #pickACountryAndStore!
!Customer class reorganize!
('as yet unclassified' glorpSetupDescriptor:forSystem:)
('benchmarks-utilities' newLoginForSQLite newPopulation
newSessionForLogin:accessor: pickACountryAndStoreFor: pickAFirstName pickAName)
('benchmarks' createTablesIn:accessor: insertDataIn: newCustomersBench)
!
DBConnection removeSelector: #sqlite:!
------------------------------------------------------------------------------
All of the data generated in your IT infrastructure is seriously valuable.
Why? It contains a definitive record of application performance, security
threats, fraudulent activity, and more. Splunk takes this data and makes
sense of it. IT sense. And common sense.
http://p.sf.net/sfu/splunk-d2d-c2
_______________________________________________
libopendbx-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/libopendbx-devel
http://www.linuxnetworks.de/doc/index.php/OpenDBX