Source

tddbc-sap02-legacy / TDDBC-Sap02-Library2.st

Object subclass: #Database2
	instanceVariableNames: 'indexDict offset'
	classVariableNames: ''
	poolDictionaries: ''
	category: 'TDDBC-Sap02-Library2'!

!Database2 methodsFor: 'initialization' stamp: 'sumim 6/2/2011 21:44'!
initialize
	indexDict := Dictionary new.
	offset := 0.
	FileStream fileNamed: self datastoreName do: [:file |
		| length position bytes record |
		file binary.
		[file atEnd] whileFalse: [
			position := offset := file position.
			record := self recordClass readFrom: file.
			indexDict at: record firstField put: position]].! !


!Database2 methodsFor: 'accessing' stamp: 'sumim 6/2/2011 13:33'!
datastoreName
	^self recordClass datastoreName! !

!Database2 methodsFor: 'accessing' stamp: 'sumim 6/1/2011 01:59'!
list
	FileStream fileNamed: self datastoreName do: [:file |
		file binary.
		^indexDict keys sort collect: [:idStr |
			file position: (indexDict at: idStr).
			self recordClass readFrom: file]]! !

!Database2 methodsFor: 'accessing' stamp: 'sumim 6/1/2011 01:58'!
recordClass
	^Book2! !


!Database2 methodsFor: 'adding' stamp: 'sumim 6/2/2011 21:43'!
add: aRecord
	| position |
	FileStream fileNamed: self datastoreName do: [:file |
		file binary.
		position := indexDict at: aRecord firstField ifAbsent: [offset].
		file position: position.
		file nextPutAll: aRecord asByteArray.
		offset := file position max: offset].
	indexDict at: aRecord firstField put: position.
	^aRecord! !


!Database2 methodsFor: 'finding' stamp: 'sumim 6/1/2011 01:58'!
find: idStr
	| position |
	position := indexDict at: idStr ifAbsent: [^nil].
	FileStream fileNamed: self datastoreName do: [:file |
		file binary; position: position.
		^self recordClass readFrom: file]! !

"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!

Database2 class
	instanceVariableNames: ''!

!Database2 class methodsFor: 'examples' stamp: 'sumim 5/31/2011 22:43'!
example
	"Database2 example"

	| database book1 book2 book3 |
	database := Database2 new.
	book1 := Book2 
		id: '001'
		title: '刀語 第一話 絶刀・鉋'
		author: '西尾 維新'
		isbn: '9784062836111'
		status: #BACKORDERED.
	book2 := Book2
		id: '002'
		title: '刀語 第二話 斬刀・鈍'
		author: '西尾 維新'
		isbn: '9784062836043'
		status: #STOCKED.
	book3 := Book2
		id: '003'
		title: '刀語 第三話 千刀・ツルギ'
		author: '西尾 維新'
		isbn: '9784062836043'
		status: #LENDING.
	{book1. book2. book3} do: [:book | database add: book].
	(database find: '002') inspect.
	database list inspect!]lang[(129 2 1 3 1 4 13 2 1 2 88 2 1 3 1 4 13 2 1 2 84 2 1 3 1 6 13 2 1 2 158)0,5,0,5,0,5,0,5,0,5,0,5,0,5,0,5,0,5,0,5,0,5,0,5,0,5,0,5,0,5,0! !


Database2 subclass: #DvdDatabase
	instanceVariableNames: ''
	classVariableNames: ''
	poolDictionaries: ''
	category: 'TDDBC-Sap02-Library2'!

!DvdDatabase methodsFor: 'accessing' stamp: 'sumim 6/2/2011 22:36'!
recordClass
	^DVD! !

"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!

DvdDatabase class
	instanceVariableNames: ''!

!DvdDatabase class methodsFor: 'examples' stamp: 'sumim 6/2/2011 22:36'!
example
	"DvdDatabase2 example"

	| database dvd1 dvd2 dvd3 |
	database := DvdDatabase new.
	dvd1 := DVD 
		id: '001'
		title: '刀語 第一巻 絶刀・鉋【完全生産限定版】'
		seller: 'アニプレックス'
		asin: 'B002WYJRRY'
		status: #BACKORDERED.
	dvd2 := DVD
		id: '002'
		title: '刀語 第二巻 / 斬刀・鈍【完全生産限定版】'
		seller: 'アニプレックス'
		asin: 'B0037FDUNY'
		status: #STOCKED.
	dvd3 := DVD
		id: '003'
		title: '刀語 第三巻 / 千刀・ツルギ 【完全生産限定版】'
		seller: 'アニプレックス'
		asin: 'B003BCWQ2O'
		status: #LENDING.
	{dvd1. dvd2. dvd3} do: [:dvd | database add: dvd].
	(database find: '002') inspect.
	database list inspect!]lang[(128 20 13 7 82 2 1 3 3 13 13 7 78 2 1 3 3 6 1 9 13 7 150)0,5,0,5,0,5,0,5,0,5,0,5,0,5,0,5,0,5,0,5,0,5,0! !


Object subclass: #Record
	instanceVariableNames: ''
	classVariableNames: ''
	poolDictionaries: ''
	category: 'TDDBC-Sap02-Library2'!

!Record methodsFor: 'compairing' stamp: 'sumim 6/3/2011 17:43'!
= other
	self == other ifTrue: [^true].
	self class ~= other class ifTrue: [^false].
 	^(self fieldsSpec reject: #isInteger) allSatisfy: [:field |
		(self perform: field) = (other perform: field)]! !

!Record methodsFor: 'compairing' stamp: 'sumim 6/9/2011 00:35'!
hash
	| prime |
	prime := 31.
	^self class instVarNames inject: 1 into: [:result :field |
		prime * result + (self perform: field) hash]! !


!Record methodsFor: 'initialization' stamp: 'sumim 6/3/2011 17:44'!
initialize
	self fieldsSpec pairsDo: [:field :size | self instVarNamed: field put: ''].
! !


!Record methodsFor: 'accessing' stamp: 'sumim 6/3/2011 17:43'!
access: message
	| fieldName sizeSuffix |
	fieldName := message selector.
	sizeSuffix := 'Size'.
	(fieldName endsWith: sizeSuffix) ifTrue: [
		fieldName := fieldName allButLast: sizeSuffix size.
		^self fieldsSpec after: fieldName].
	fieldName endsWithAColon ifTrue: [
		fieldName := fieldName allButLast.
		^self instVarNamed: fieldName put: message arguments first].
	^self instVarNamed: fieldName! !

!Record methodsFor: 'accessing' stamp: 'sumim 6/2/2011 13:34'!
datastoreName
	self subclassResponsibility! !

!Record methodsFor: 'accessing' stamp: 'sumim 6/3/2011 17:44'!
doesNotUnderstand: message
	| fields |
	fields := self fieldsSpec reject: [:each | each isInteger].
	^(message selector beginsWithAnyOf: fields)
		ifTrue: [self access: message]
		ifFalse: [super doesNotUnderstand: message]! !

!Record methodsFor: 'accessing' stamp: 'sumim 6/3/2011 17:43'!
fieldsSpec
	self subclassResponsibility! !

!Record methodsFor: 'accessing' stamp: 'sumim 6/3/2011 17:44'!
firstField
	^self perform: self fieldsSpec first! !


!Record methodsFor: 'converting' stamp: 'sumim 6/3/2011 17:43'!
asByteArray
	^ByteArray streamContents: [:ss |
		self fieldsSpec pairsDo: [:sel :size |
			| bytes |
			bytes := ((self perform: sel) asString convertToEncoding: 'utf-8') asByteArray.
			ss nextPutAll: (bytes forceTo: size paddingWith: 0)]]! !


!Record methodsFor: 'private' stamp: 'sumim 6/3/2011 17:43'!
data: byteArray
	| stream |
	stream := byteArray readStream.
	self fieldsSpec pairsDo: [:sel :len |
		| str |
		str := ((stream next: len) copyUpTo: 0) asString convertFromEncoding: 'utf-8'. 
		self perform: sel, ':' with: str].
	self status: self status asSymbol! !

!Record methodsFor: 'private' stamp: 'sumim 6/3/2011 17:44'!
readFrom: byteStream
	self fieldsSpec pairsDo: [:sel :len |
		| str |
		str := ((byteStream next: len) copyUpTo: 0) asString convertFromEncoding: 'utf-8'. 
		self perform: sel, ':' with: str]! !


!Record methodsFor: 'printing' stamp: 'sumim 6/3/2011 17:44'!
printOn: stream
	stream nextPutAll: self class name.
	(self fieldsSpec reject: #isInteger) do: [:field |
		stream space; nextPutAll: field, ': ', (self perform: field) storeString]! !

"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!

Record class
	instanceVariableNames: ''!

!Record class methodsFor: 'instance creation' stamp: 'sumim 5/31/2011 22:29'!
newFrom: byteArray
	^self readFrom: byteArray readStream! !

!Record class methodsFor: 'instance creation' stamp: 'sumim 5/31/2011 22:28'!
readFrom: byteStream
	^self new readFrom: byteStream! !


!Record class methodsFor: 'accessing' stamp: 'sumim 6/2/2011 13:33'!
datastoreName
	^self new datastoreName! !


Trait named: #TRecordStatusAccess
	uses: #()
	category: 'TDDBC-Sap02-Library2'!

!TRecordStatusAccess methodsFor: 'initialization' stamp: 'sumim 6/2/2011 14:01'!
initializeStatus
	self status: #STOCKED! !

!TRecordStatusAccess methodsFor: 'initialization' stamp: 'sumim 6/2/2011 14:02'!
readFrom: byteStream
	super readFrom: byteStream.
	self status: self status asSymbol.
	^self! !


!TRecordStatusAccess methodsFor: 'accessing' stamp: 'sumim 6/2/2011 14:03'!
status: statusSym
	(self statusSyms includes: statusSym) ifFalse: [^self error: 'unknown status'].
	super status: statusSym! !

!TRecordStatusAccess methodsFor: 'accessing' stamp: 'sumim 6/2/2011 14:03'!
statusSyms
	^#(
		"入荷待ち"
		BACKORDERED
		"在庫有"
		STOCKED
		"貸出中"
		LENDING
		"抹消"
		ERASURED
	)
!]lang[(19 4 19 3 15 3 15 2 16)0,5,0,5,0,5,0,5,0! !


Record subclass: #Book2
	uses: TRecordStatusAccess
	instanceVariableNames: 'id title author isbn status'
	classVariableNames: ''
	poolDictionaries: ''
	category: 'TDDBC-Sap02-Library2'!

!Book2 methodsFor: 'accessing' stamp: 'sumim 6/2/2011 13:32'!
datastoreName
	^'book.bin'! !

!Book2 methodsFor: 'accessing' stamp: 'sumim 6/3/2011 17:43'!
fieldsSpec
	^#(id 8 title 512 author 128 isbn 16 status 16)! !



!Book2 methodsFor: 'initializing' stamp: 'sumim 6/2/2011 14:01'!
initialize
	super initialize.
	id := '0'.
	self initializeStatus! !

"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!

Book2 class
	uses: TRecordStatusAccess classTrait
	instanceVariableNames: ''!

!Book2 class methodsFor: 'instance creation' stamp: 'sumim 5/31/2011 22:40'!
id: id title: title author: author isbn: isbn status: status
	^self new
		id: id;
		title: title;
		author: author;
		isbn: isbn;
		status: status;
		yourself! !


Record subclass: #DVD
	uses: TRecordStatusAccess
	instanceVariableNames: 'id title seller asin status'
	classVariableNames: ''
	poolDictionaries: ''
	category: 'TDDBC-Sap02-Library2'!

!DVD methodsFor: 'accessing' stamp: 'sumim 6/2/2011 13:34'!
datastoreName
	^'dvd.bin'! !

!DVD methodsFor: 'accessing' stamp: 'sumim 6/3/2011 17:43'!
fieldsSpec
	^#(id 8 title 512 seller  256 asin 16 status 16)! !


!DVD methodsFor: 'initialization' stamp: 'sumim 6/2/2011 14:02'!
initialize
	super initialize.
	id := '0'.
	self initializeStatus! !

"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!

DVD class
	uses: TRecordStatusAccess classTrait
	instanceVariableNames: ''!

!DVD class methodsFor: 'instance creation' stamp: 'sumim 6/2/2011 13:52'!
id: id title: title seller: seller asin: asin status: status
	^self new id: id; title: title; seller: seller; asin: asin; status: status; yourself! !
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.