Picking up from last night, I am still keen on exploring mapping directory structures into JSON data structures. The ultimate goal is to create a CouchDB design document (which are stored in JSON format).
For example, I would like to take a document in
couch/_design/lucene/transform.js
to result in a JSON document along the lines of:{I devised a poor man's solution last night, but would like something that will work with directories that are deeper than 1 level. I also favor tail recursion because I have been learning Erlang. It may be something of a golden hammer for me, but it's a fun golden hammer. Besides, I am prototyping to learn.
"lucene": {
"transform": <<contents of transform.js>>
}
}
First up, for each
.js
file, I build an array of the directories, basename of the file and the contents the file. For couch/_design/lucene/transform.js
, I end up with something like this:["lucene", "transform", "<<contents of transform.js>>"]I can get that with:
Dir["#{DESIGN_DOC_DIR}/**/*.js"].each do |filename|Using a tail-recursive method, I can then build the desired data structure:
path = File.dirname(filename).
split(/\//)
path << File.basename(filename, ".js")
file = File.new(filename)
path << file.read
end
def build_doc(list)Trying this out in and IRB session, I am getting my desired results:
key = list.first
if (list.length > 2)
{ key => build_doc(list[1,list.length]) }
else
{ key => list.last }
end
end
>> def build_doc(list)So I feel safe to give this a try with my existing design docs being added in the Cucumber
>> key = list.first
>> if (list.length > 2)
>> { key => build_doc(list[1,list.length]) }
>> else
?> { key => list.last }
>> end
>> end
=> nil
>> build_doc(%w{1 2 3 4 5})
=> {"1"=>{"2"=>{"3"=>{"4"=>"5"}}}}
features/support/env.rb
file. I add this to my Before
block:def build_doc(list)To make sure that everything is still working, I run one of the recipe search Cucumber scenarios (which would fail without a good lucene design document):
key = list.first
if (list.length > 2)
{ key => build_doc(list[1,list.length]) }
else
{ key => list.last }
end
end
docs = { }
DESIGN_DOC_DIR = "couch/_design"
Dir["#{DESIGN_DOC_DIR}/**/*.js"].each do |filename|
path = File.dirname(filename).
gsub(/#{DESIGN_DOC_DIR}\//, '').
split(/\//)
path << File.basename(filename, ".js")
file = File.new(filename)
path << file.read
docs.merge!(build_doc(path))
end
docs.each do |document_name, doc|
RestClient.put "#{@@db}/_design/#{document_name}",
doc.to_json,
:content_type => 'application/json'
end
cstrom@jaynestown:~/repos/eee-code$ cucumber features -n -s "Matching a word in the recipe summary"Yay!
Sinatra::Test is deprecated; use Rack::Test instead.
Feature: Search for recipes
So that I can find one recipe among many
As a web user
I want to be able search recipes
Scenario: Matching a word in the recipe summary
Given a "pancake" recipe with a "Yummy!" summary
And a "french toast" recipe with a "Delicious" summary
And a 0.5 second wait to allow the search index to be updated
When I search for "yummy"
Then I should see the "pancake" recipe in the search results
And I should not see the "french toast" recipe in the search results
1 scenario
6 passed steps
I rather like that. It is especially nice that the transform.js file is pure javascript, making is easily tested. I may very well delete my prototype and implement for real tomorrow.
No comments:
Post a Comment