-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Initial commit with working version (barely)
- Loading branch information
1 parent
bc138eb
commit 51646bb
Showing
15 changed files
with
632 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
'srcDirectory' : 'src' | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
#format : #tonel | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
Class { | ||
#name : #BaselineOfCouchDB, | ||
#superclass : #BaselineOf, | ||
#category : #BaselineOfCouchDB | ||
} | ||
|
||
{ #category : #baselines } | ||
BaselineOfCouchDB >> baseline: spec [ | ||
<baseline> | ||
spec | ||
for: #common | ||
do: [ spec | ||
baseline: 'NeoJSON' | ||
with: [ spec repository: 'github://svenvc/NeoJSON/repository' ]. | ||
spec | ||
package: #'CouchDB-Client' | ||
with: [ spec requires: #('NeoJSON') ]. | ||
spec group: 'default' with: #(#'CouchDB-Client') ] | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Package { #name : #BaselineOfCouchDB } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
" | ||
CouchDBError is raised whenever we get an error response from the CouchDB server, eg: {error: {}} instead of {ok: true} | ||
" | ||
Class { | ||
#name : #CouchDBError, | ||
#superclass : #Error, | ||
#category : #CouchDB | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
" | ||
Database provides an interface to a database running on a CouchDB server. | ||
" | ||
Class { | ||
#name : #CouchDatabase, | ||
#superclass : #CouchObject, | ||
#category : #CouchDB | ||
} | ||
|
||
{ #category : #'api - database' } | ||
CouchDatabase >> compact [ | ||
^self class post: address, '_compact' | ||
] | ||
|
||
{ #category : #'api - documents' } | ||
CouchDatabase >> create: anObject [ | ||
| response | | ||
response := self class post: address contents: (CouchDocument with: anObject). | ||
^CouchDocument new | ||
address: address / (response at: 'id'); | ||
revision: (response at: 'rev'); | ||
object: anObject; | ||
yourself | ||
] | ||
|
||
{ #category : #'api - documents' } | ||
CouchDatabase >> createAll: aCollectionOfObjects [ | ||
|
||
| saveAll response documents | | ||
saveAll := (Dictionary new) | ||
at: 'docs' put: aCollectionOfObjects; | ||
yourself. | ||
response := self class post: address , '_bulk_docs' contents: saveAll. | ||
documents := OrderedCollection new. | ||
response with: aCollectionOfObjects | ||
do: | ||
[:dictionary :object | | ||
| document | | ||
document := (self document: (dictionary at: 'id') | ||
revision: (dictionary at: 'rev')) | ||
object: object; | ||
yourself. | ||
documents add: document]. "at: 'new_revs'" | ||
^documents | ||
] | ||
|
||
{ #category : #'api - views' } | ||
CouchDatabase >> design: designName view: viewName [ | ||
^CouchView new | ||
address: address; | ||
design: designName; | ||
name: viewName; | ||
yourself | ||
] | ||
|
||
{ #category : #'api - documents' } | ||
CouchDatabase >> document: id [ | ||
^self document: id revision: nil | ||
] | ||
|
||
{ #category : #'api - documents' } | ||
CouchDatabase >> document: id revision: revision [ | ||
^CouchDocument new | ||
address: address / id; | ||
revision: revision; | ||
yourself | ||
] | ||
|
||
{ #category : #'api - querying' } | ||
CouchDatabase >> documents [ | ||
^self searchResults: (self class get: address / '_all_docs') | ||
] | ||
|
||
{ #category : #'api - querying' } | ||
CouchDatabase >> documentsCount: count [ | ||
^self searchResults: (self class get: address, ('_all_docs?count=', count)) | ||
] | ||
|
||
{ #category : #'api - querying' } | ||
CouchDatabase >> documentsFrom: start [ | ||
^self searchResults: (self class get: address, ('_all_docs?startkey=', start)) | ||
] | ||
|
||
{ #category : #'api - querying' } | ||
CouchDatabase >> documentsFrom: start count: count [ | ||
^self searchResults: (self class get: address, ('_all_docs?startkey=', start, '&count=', count)) | ||
] | ||
|
||
{ #category : #'api - querying' } | ||
CouchDatabase >> documentsFrom: start to: end [ | ||
^self searchResults: (self class get: address, ('_all_docs?startkey=', start, '&endkey=', end)) | ||
] | ||
|
||
{ #category : #'api - database' } | ||
CouchDatabase >> name [ | ||
^self information at: 'db_name' | ||
] | ||
|
||
{ #category : #'api - querying' } | ||
CouchDatabase >> reverseDocuments [ | ||
^self searchResults: (self class get: address, '_all_docs?descending=true') | ||
] | ||
|
||
{ #category : #'api - querying' } | ||
CouchDatabase >> reverseDocumentsCount: count [ | ||
^self searchResults: (self class get: address, ('_all_docs?descending=true&count=', count)) | ||
] | ||
|
||
{ #category : #'api - querying' } | ||
CouchDatabase >> reverseDocumentsFrom: start [ | ||
^self searchResults: (self class get: address, ('_all_docs?descending=true&startkey=', start)) | ||
] | ||
|
||
{ #category : #'api - querying' } | ||
CouchDatabase >> reverseDocumentsFrom: start count: count [ | ||
^self searchResults: (self class get: address, ('_all_docs?descending=true&startkey=', start, '&count=', count)) | ||
] | ||
|
||
{ #category : #'api - querying' } | ||
CouchDatabase >> reverseDocumentsFrom: start to: end [ | ||
^self searchResults: (self class get: address, ('_all_docs?descending=true&startkey=', start, '&endkey=', end)) | ||
] | ||
|
||
{ #category : #'api - documents' } | ||
CouchDatabase >> save: aCouchDocument [ | ||
self saveAll: (Array with: aCouchDocument) | ||
] | ||
|
||
{ #category : #'api - documents' } | ||
CouchDatabase >> saveAll: aCollectionOfDocuments [ | ||
|
||
| saveAll response | | ||
saveAll := (Dictionary new) | ||
at: 'docs' put: aCollectionOfDocuments; | ||
yourself. | ||
response := self client post: address , '_bulk_docs' contents: saveAll. | ||
response with: aCollectionOfDocuments | ||
do: [:dictionary :document | document revision: (dictionary at: 'rev')]. "at: 'new_revs'" | ||
^response | ||
] | ||
|
||
{ #category : #private } | ||
CouchDatabase >> searchResults: results [ | ||
^(results at: 'rows') collect: [:row | self document: (row at: 'id') revision: ((row at: 'value') at: 'rev')] | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,169 @@ | ||
" | ||
Document provides an interface to a document in a database running on a CouchDB server. | ||
Instance Variables: | ||
object <Object> the data/object for this document | ||
revision <String> the revision id for this document | ||
" | ||
Class { | ||
#name : #CouchDocument, | ||
#superclass : #CouchObject, | ||
#instVars : [ | ||
'object', | ||
'revision' | ||
], | ||
#classVars : [ | ||
'Undefined' | ||
], | ||
#category : #CouchDB | ||
} | ||
|
||
{ #category : #'instance creation' } | ||
CouchDocument class >> neoJsonMapping: mapper [ | ||
mapper | ||
for: self | ||
do: [ :mapping | | ||
mapping mapAccessor: #id to: '_id'. | ||
mapping mapInstVar: #revision to: '_rev'. | ||
mapping | ||
mapProperty: '+class' | ||
getter: [ :receiver | receiver object class name asString ] | ||
setter: [ :receiver :value | value asSymbol asClass ]. | ||
mapping mapInstVar: #object to: 'object' ] | ||
] | ||
|
||
{ #category : #'instance creation' } | ||
CouchDocument class >> with: anObject [ | ||
^ self new | ||
object: anObject; | ||
yourself | ||
] | ||
|
||
{ #category : #'instance creation' } | ||
CouchDocument class >> writeAttachment: uri contentType: aString bytes: aByteArray [ | ||
^self request: [:client | | ||
| request | | ||
request := (client requestClass put: uri). | ||
request contentType: aString. | ||
request doNotChunk. | ||
request contentLength: aByteArray size. | ||
request byteSource: aByteArray readStream. | ||
client request: request. | ||
client executeAndGetResponse | ||
] | ||
] | ||
|
||
{ #category : #api } | ||
CouchDocument >> delete [ | ||
| response | | ||
revision ifNil: [self refresh]. | ||
response := self class delete: (address copy query: 'rev=', revision). | ||
revision := response at: 'rev'. | ||
^response | ||
] | ||
|
||
{ #category : #accessing } | ||
CouchDocument >> id [ | ||
^ self address ifNotNil: [ :obj | obj lastPathSegment ] | ||
] | ||
|
||
{ #category : #'initialize-release' } | ||
CouchDocument >> initialize [ | ||
super initialize. | ||
object := self undefined | ||
] | ||
|
||
{ #category : #converting } | ||
CouchDocument >> jsonWriteOn: aStream [ | ||
aStream nextPutAll: '{'. | ||
aStream nextPutAll: '"_id":'. | ||
self id jsonWriteOn: aStream. | ||
self revision ifNotNil: | ||
[aStream nextPutAll: ',"_rev":'. | ||
self revision jsonWriteOn: aStream]. | ||
object jsonKeysAndValuesDo: [:key :value | | ||
aStream nextPutAll: ','. | ||
key jsonWriteOn: aStream. | ||
aStream nextPutAll: ':'. | ||
value jsonWriteOn: aStream]. | ||
aStream nextPutAll: '}' | ||
] | ||
|
||
{ #category : #accessing } | ||
CouchDocument >> object [ | ||
|
||
object = #_undefined ifTrue: [ self refresh ]. | ||
^object | ||
] | ||
|
||
{ #category : #accessing } | ||
CouchDocument >> object: anObject [ | ||
object := anObject | ||
] | ||
|
||
{ #category : #printing } | ||
CouchDocument >> printOn: aStream [ | ||
super printOn: aStream. | ||
revision ifNil: [^self]. | ||
aStream space; nextPutAll: revision | ||
] | ||
|
||
{ #category : #api } | ||
CouchDocument >> refresh [ | ||
" Update this Document to the latest revision " | ||
|
||
| response | | ||
response := self information. | ||
revision := response at: '_rev'. | ||
((response includesKey: '+class') | ||
and: [ response includesKey: 'object' ]) | ||
ifTrue: [ | class | | ||
class := (response at: '+class') asSymbol asClass. | ||
({Array. Dictionary. String. Integer} includes: class) | ||
ifTrue: [ object := NeoJSONReader | ||
fromString: (NeoJSONWriter toString: response object) ] | ||
ifFalse: [ object := NeoJSONReader | ||
fromString: (NeoJSONWriter toString: response object) | ||
as: class ] ] | ||
ifFalse: [ object := response ]. | ||
^ response | ||
] | ||
|
||
{ #category : #accessing } | ||
CouchDocument >> revision [ | ||
^revision | ||
] | ||
|
||
{ #category : #accessing } | ||
CouchDocument >> revision: anObject [ | ||
revision := anObject | ||
] | ||
|
||
{ #category : #api } | ||
CouchDocument >> revisions [ | ||
^(self class get: (address copy query: 'revs_info=true')) at: '_revs_info' ifAbsent: [#()] | ||
] | ||
|
||
{ #category : #api } | ||
CouchDocument >> save [ | ||
| response | | ||
response := self class put: address contents: self. | ||
revision := response at: 'rev'. | ||
^response | ||
] | ||
|
||
{ #category : #'initialize-release' } | ||
CouchDocument >> undefined [ | ||
^ #_undefined | ||
] | ||
|
||
{ #category : #api } | ||
CouchDocument >> writeAttachment: nameString contentType: aString bytes: aByteArray [ | ||
| response | | ||
revision ifNil: [self refresh]. | ||
response := self class writeAttachment: ((address asString, '/' , nameString) asURI query: 'rev=', revision) contentType: aString bytes: aByteArray. | ||
revision := response at: 'rev'. | ||
^response | ||
] |
Oops, something went wrong.