Source

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

Transcript show: 'CirculationStatus'; cr!
Smalltalk at: #CirculationStatus put: Dictionary new!
CirculationStatus at: #'BACKORDERED' put:  (#BACKORDERED)!
CirculationStatus at: #'ERASURED' put:  (#ERASURED)!
CirculationStatus at: #'LENDING' put:  (#LENDING)!
CirculationStatus at: #'STOCKED' put:  (#STOCKED)!

Object subclass: #Book
	instanceVariableNames: 'id title author isbn status'
	classVariableNames: ''
	poolDictionaries: 'CirculationStatus'
	category: 'TDDBC-Sap02-Library'!
!Book commentStamp: 'sumim 5/20/2011 15:19' prior: 0!
書籍オブジェクト

Instance Variables
	id:		<String>
	title:		<String>
	author:		<String>
	isbn:		<String>
	status:		<Symbol>

id
	- 書籍ID

title
	- タイトル

author
	- 著者

isbn
	- ISBN code

status
	- 状態コード!]lang[(8 116 2 13 4 12 2 31 5)5,0,5,0,5,0,5,0,5!


!Book methodsFor: 'initialization' stamp: 'sumim 5/20/2011 16:21'!
initialize
	" 書籍ID "
	id := '0'.
	" タイトル "
	title := ''.
	" 著者 "
	author := ''.
	" ISBN code "
	isbn := ''.
	" 状態コード "
	status := STOCKED!]lang[(14 2 20 4 20 2 49 5 21)0,5,0,5,0,5,0,5,0! !


!Book methodsFor: 'accessing' stamp: 'sumim 5/17/2011 17:44'!
author
	^author! !

!Book methodsFor: 'accessing' stamp: 'sumim 5/17/2011 17:44'!
author: newAuthor
	author := newAuthor! !

!Book methodsFor: 'accessing' stamp: 'sumim 5/17/2011 17:43'!
id
	^id! !

!Book methodsFor: 'accessing' stamp: 'sumim 5/17/2011 17:43'!
id: newId
	id := newId! !

!Book methodsFor: 'accessing' stamp: 'sumim 5/17/2011 17:44'!
isbn
	^isbn! !

!Book methodsFor: 'accessing' stamp: 'sumim 5/17/2011 17:44'!
isbn: newIsbn
	isbn := newIsbn! !

!Book methodsFor: 'accessing' stamp: 'sumim 5/17/2011 17:46'!
status
	^status! !

!Book methodsFor: 'accessing' stamp: 'sumim 5/17/2011 17:44'!
status: newStatus
	status := newStatus! !

!Book methodsFor: 'accessing' stamp: 'sumim 5/17/2011 17:43'!
title
	^title! !

!Book methodsFor: 'accessing' stamp: 'sumim 5/17/2011 17:44'!
title: newTitle
	title := newTitle! !


!Book methodsFor: 'comparing ' stamp: 'sumim 5/17/2011 17:48'!
= other
	self == other ifTrue: [^true].
	other isNil ifTrue: [^false].
	self class ~= other class ifTrue: [^false].
	author isNil
		ifTrue: [other author notNil ifTrue: [^false]]
		ifFalse: [author ~= other author ifTrue: [^false]].
	id isNil
		ifTrue: [other id notNil ifTrue: [^false]]
		ifFalse: [id ~= other id ifTrue: [^false]].
	isbn isNil
		ifTrue: [other isbn notNil ifTrue: [^false]]
		ifFalse: [isbn ~= other isbn ifTrue: [^false]].
	status ~= other status ifTrue: [^false].
	title isNil
		ifTrue: [other title notNil ifTrue: [^false]]
		ifFalse: [title ~= other title ifTrue: [^false]].
	^true! !

!Book methodsFor: 'comparing ' stamp: 'sumim 5/17/2011 17:46'!
hash
	| prime result |
	prime := 31.
	result := 1.
	result := prime * (result + (author ifNil: [0] ifNotNil: [author hash])).
	result := prime * (result + (id ifNil: [0] ifNotNil: [id hash])).
	result := prime * (result + (isbn ifNil: [0] ifNotNil: [isbn hash])).
	result := prime * (result + (status ifNil: [0] ifNotNil: [status hash])).
	result := prime * (result + (title ifNil: [0] ifNotNil: [title hash])).
	^result! !


!Book methodsFor: 'printing' stamp: 'sumim 5/17/2011 17:49'!
printOn: stream
	stream
		nextPutAll: 'Book[';
		nextPutAll: 'id=', id storeString;
		nextPutAll: ', title=', title storeString;
		nextPutAll: ', author=', author storeString;
		nextPutAll: ', isbn=', isbn storeString;
		nextPutAll: ', status=', status storeString;
		nextPut: $]! !


Object subclass: #Database
	instanceVariableNames: 'keyMap offset datastore'
	classVariableNames: 'DATASTORExNAME EMPTYxSTRING LENGTH LENxAUTHOR LENxID LENxISBN LENxSTATUS LENxTITLE OFFSETxAUTHOR OFFSETxID OFFSETxISBN OFFSETxSTATUS OFFSETxTITLE'
	poolDictionaries: 'CirculationStatus'
	category: 'TDDBC-Sap02-Library'!
!Database commentStamp: 'sumim 5/17/2011 17:33' prior: 0!
Bookレコードをローカルファイルへ保存するデータベースクラス。
Bookのインスタンスは、固定長フォーマットでローカルファイルへと保存される。

Instance Variables
	datastore:		<StandardFileStream>
	keyMap:		<Dictionary>
	offset:		<Integer>

datastore
	- データファイル

keyMap
	- keyとオフセットのマップ!]lang[(4 28 5 35 112 7 15 10)0,5,0,5,0,5,0,5!


!Database methodsFor: 'initialization' stamp: 'sumim 5/17/2011 17:03'!
initialize
	keyMap := Dictionary new.
	offset := 0.
	datastore := StandardFileStream fileNamed: DATASTORExNAME.
	datastore binary.
	[:exit | 
		[	| b key |
			datastore position: offset.
			b := datastore next: LENxID.
			b ifEmpty: [exit value].
			key := (b copyUpTo: 0) asString.
			keyMap at: key put: offset.
			offset := offset + LENGTH
		] repeat
	] valueWithExit.
	offset := 0! !


!Database methodsFor: 'adding' stamp: 'sumim 5/17/2011 17:23'!
add: book
	keyMap at: book id put: datastore position.
	datastore nextPutAll: (self toByte: book).! !


!Database methodsFor: 'finding' stamp: 'sumim 5/17/2011 17:56'!
find: key
	| bytes |
	(keyMap includesKey: key) not ifTrue: [^nil].
	offset := keyMap at: key.
	datastore position: offset.
	bytes := datastore next: LENGTH.
	^self toEntry: bytes! !


!Database methodsFor: 'listing' stamp: 'sumim 5/21/2011 01:02'!
list
	| result |
	result := OrderedCollection new: keyMap size.
	keyMap keys sort do: [:key |
		result add: (self find: key)
	].
	^result asArray! !


!Database methodsFor: 'converting' stamp: 'sumim 5/17/2011 17:45'!
toByte: book
	| bytes writerOffset write |
	bytes := ByteArray new: LENGTH.
	writerOffset := 1.

	write := [:str :len |
		| data |
		data := (str convertToEncoding: 'utf-8') asByteArray.
		bytes replaceFrom: writerOffset to: writerOffset + data size - 1 with: data.
		writerOffset := writerOffset + len].

	write value: book id value: LENxID.
	write value: book title value: LENxTITLE.
	write value: book author value: LENxAUTHOR.
	write value: book isbn value: LENxISBN.
	write value: book status value: LENxSTATUS.
	^bytes! !

!Database methodsFor: 'converting' stamp: 'sumim 5/20/2011 16:23'!
toEntry: bytes
	| reader readerOffset readString book |
	reader := bytes readStream.
	readerOffset := 1.

	readString := [:len |
		[
			| data |
			data := reader next: len.
			(data upTo: 0) asString convertFromEncoding: 'utf-8'
		] ensure: [
			readerOffset := readerOffset + len.
		]
	].

	book := Book new.
	book id: (readString value: LENxID).
	book title: (readString value: LENxTITLE).
	book author: (readString value: LENxAUTHOR).
	book isbn: (readString value: LENxISBN).
	book status: (CirculationStatus at: (readString value: LENxSTATUS) asSymbol).
	^book! !

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

Database class
	instanceVariableNames: ''!

!Database class methodsFor: 'class initialization' stamp: 'sumim 5/17/2011 17:39'!
initialize
	"Database initialize"

	DATASTORExNAME := 'book.bin'.
	LENxID := 8.
	LENxTITLE := 512.
	LENxAUTHOR := 128.
	LENxISBN := 16.
	LENxSTATUS := 16.
	OFFSETxID := 0.
	OFFSETxTITLE := OFFSETxID + LENxID.
	OFFSETxAUTHOR := OFFSETxTITLE + LENxTITLE.
	OFFSETxISBN := OFFSETxAUTHOR + LENxAUTHOR.
	OFFSETxSTATUS := OFFSETxISBN + LENxISBN.
	LENGTH := LENxID + LENxTITLE + LENxAUTHOR + LENxISBN + LENxSTATUS.
	EMPTYxSTRING := String new: LENGTH! !


!Database class methodsFor: 'examples' stamp: 'sumim 5/25/2011 23:01'!
example
	"Database example"
	"Smalltalk garbageCollect"

	| database book1 book2 book3 |
	database := Database new.
	book1 := Book new
		id: '001'; 
		title: '刀語 第一話 絶刀・鉋'; 
		author: '西尾 維新'; 
		isbn: '9784062836111'; 
		status: BACKORDERED;
		yourself.
	book2 := Book new
		id: '002'; 
		title: '刀語 第二話 斬刀・鈍'; 
		author: '西尾 維新'; 
		isbn: '9784062836043'; 
		yourself.
	book3 := Book new
		id: '003'; 
		title: '刀語 第三話 千刀・ツルギ'; 
		author: '西尾 維新'; 
		isbn: '9784062836043'; 
		status: LENDING;
		yourself.
	{book1. book2. book3} do: [:book | database add: book].
	(database find: '002') inspect.
	database list inspect!]lang[(159 2 1 3 1 4 15 2 1 2 108 2 1 3 1 4 15 2 1 2 85 2 1 3 1 6 15 2 1 2 173)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! !

Database initialize!
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.