bud 0.9.0 → 0.9.1

Sign up to get free protection for your applications and to get access to all the features.
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bud
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.0
4
+ version: 0.9.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -13,11 +13,11 @@ authors:
13
13
  autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
- date: 2012-03-22 00:00:00.000000000 Z
16
+ date: 2012-04-10 00:00:00.000000000 Z
17
17
  dependencies:
18
18
  - !ruby/object:Gem::Dependency
19
19
  name: eventmachine
20
- requirement: &70208102945340 !ruby/object:Gem::Requirement
20
+ requirement: &70136220748940 !ruby/object:Gem::Requirement
21
21
  none: false
22
22
  requirements:
23
23
  - - ! '>='
@@ -25,10 +25,10 @@ dependencies:
25
25
  version: '0'
26
26
  type: :runtime
27
27
  prerelease: false
28
- version_requirements: *70208102945340
28
+ version_requirements: *70136220748940
29
29
  - !ruby/object:Gem::Dependency
30
30
  name: fastercsv
31
- requirement: &70208102944840 !ruby/object:Gem::Requirement
31
+ requirement: &70136220747220 !ruby/object:Gem::Requirement
32
32
  none: false
33
33
  requirements:
34
34
  - - ! '>='
@@ -36,10 +36,10 @@ dependencies:
36
36
  version: '0'
37
37
  type: :runtime
38
38
  prerelease: false
39
- version_requirements: *70208102944840
39
+ version_requirements: *70136220747220
40
40
  - !ruby/object:Gem::Dependency
41
41
  name: gchart
42
- requirement: &70208102944420 !ruby/object:Gem::Requirement
42
+ requirement: &70136220763100 !ruby/object:Gem::Requirement
43
43
  none: false
44
44
  requirements:
45
45
  - - ! '>='
@@ -47,10 +47,10 @@ dependencies:
47
47
  version: '0'
48
48
  type: :runtime
49
49
  prerelease: false
50
- version_requirements: *70208102944420
50
+ version_requirements: *70136220763100
51
51
  - !ruby/object:Gem::Dependency
52
52
  name: getopt
53
- requirement: &70208102944000 !ruby/object:Gem::Requirement
53
+ requirement: &70136220762540 !ruby/object:Gem::Requirement
54
54
  none: false
55
55
  requirements:
56
56
  - - ! '>='
@@ -58,43 +58,10 @@ dependencies:
58
58
  version: '0'
59
59
  type: :runtime
60
60
  prerelease: false
61
- version_requirements: *70208102944000
62
- - !ruby/object:Gem::Dependency
63
- name: i18n
64
- requirement: &70208102943580 !ruby/object:Gem::Requirement
65
- none: false
66
- requirements:
67
- - - ! '>='
68
- - !ruby/object:Gem::Version
69
- version: '0'
70
- type: :runtime
71
- prerelease: false
72
- version_requirements: *70208102943580
73
- - !ruby/object:Gem::Dependency
74
- name: json
75
- requirement: &70208102943100 !ruby/object:Gem::Requirement
76
- none: false
77
- requirements:
78
- - - ! '>='
79
- - !ruby/object:Gem::Version
80
- version: '0'
81
- type: :runtime
82
- prerelease: false
83
- version_requirements: *70208102943100
61
+ version_requirements: *70136220762540
84
62
  - !ruby/object:Gem::Dependency
85
63
  name: msgpack
86
- requirement: &70208102942640 !ruby/object:Gem::Requirement
87
- none: false
88
- requirements:
89
- - - ! '>='
90
- - !ruby/object:Gem::Version
91
- version: '0'
92
- type: :runtime
93
- prerelease: false
94
- version_requirements: *70208102942640
95
- - !ruby/object:Gem::Dependency
96
- name: nestful
97
- requirement: &70208102942180 !ruby/object:Gem::Requirement
64
+ requirement: &70136220761500 !ruby/object:Gem::Requirement
98
65
  none: false
99
66
  requirements:
100
67
  - - ! '>='
@@ -102,10 +69,10 @@ dependencies:
102
69
  version: '0'
103
70
  type: :runtime
104
71
  prerelease: false
105
- version_requirements: *70208102942180
72
+ version_requirements: *70136220761500
106
73
  - !ruby/object:Gem::Dependency
107
74
  name: ruby-graphviz
108
- requirement: &70208102941740 !ruby/object:Gem::Requirement
75
+ requirement: &70136220760140 !ruby/object:Gem::Requirement
109
76
  none: false
110
77
  requirements:
111
78
  - - ! '>='
@@ -113,10 +80,10 @@ dependencies:
113
80
  version: '0'
114
81
  type: :runtime
115
82
  prerelease: false
116
- version_requirements: *70208102941740
83
+ version_requirements: *70136220760140
117
84
  - !ruby/object:Gem::Dependency
118
85
  name: ruby2ruby
119
- requirement: &70208102941180 !ruby/object:Gem::Requirement
86
+ requirement: &70136220759200 !ruby/object:Gem::Requirement
120
87
  none: false
121
88
  requirements:
122
89
  - - <
@@ -124,10 +91,10 @@ dependencies:
124
91
  version: 1.3.1
125
92
  type: :runtime
126
93
  prerelease: false
127
- version_requirements: *70208102941180
94
+ version_requirements: *70136220759200
128
95
  - !ruby/object:Gem::Dependency
129
96
  name: ruby_parser
130
- requirement: &70208102940620 !ruby/object:Gem::Requirement
97
+ requirement: &70136220758700 !ruby/object:Gem::Requirement
131
98
  none: false
132
99
  requirements:
133
100
  - - ! '>='
@@ -135,10 +102,10 @@ dependencies:
135
102
  version: '0'
136
103
  type: :runtime
137
104
  prerelease: false
138
- version_requirements: *70208102940620
105
+ version_requirements: *70136220758700
139
106
  - !ruby/object:Gem::Dependency
140
107
  name: superators19
141
- requirement: &70208102939800 !ruby/object:Gem::Requirement
108
+ requirement: &70136220758040 !ruby/object:Gem::Requirement
142
109
  none: false
143
110
  requirements:
144
111
  - - ! '>='
@@ -146,10 +113,10 @@ dependencies:
146
113
  version: '0'
147
114
  type: :runtime
148
115
  prerelease: false
149
- version_requirements: *70208102939800
116
+ version_requirements: *70136220758040
150
117
  - !ruby/object:Gem::Dependency
151
118
  name: syntax
152
- requirement: &70208102938500 !ruby/object:Gem::Requirement
119
+ requirement: &70136220757320 !ruby/object:Gem::Requirement
153
120
  none: false
154
121
  requirements:
155
122
  - - ! '>='
@@ -157,10 +124,10 @@ dependencies:
157
124
  version: '0'
158
125
  type: :runtime
159
126
  prerelease: false
160
- version_requirements: *70208102938500
127
+ version_requirements: *70136220757320
161
128
  - !ruby/object:Gem::Dependency
162
129
  name: uuid
163
- requirement: &70208102937500 !ruby/object:Gem::Requirement
130
+ requirement: &70136220756700 !ruby/object:Gem::Requirement
164
131
  none: false
165
132
  requirements:
166
133
  - - ! '>='
@@ -168,10 +135,10 @@ dependencies:
168
135
  version: '0'
169
136
  type: :runtime
170
137
  prerelease: false
171
- version_requirements: *70208102937500
138
+ version_requirements: *70136220756700
172
139
  - !ruby/object:Gem::Dependency
173
140
  name: minitest
174
- requirement: &70208102937020 !ruby/object:Gem::Requirement
141
+ requirement: &70136220756180 !ruby/object:Gem::Requirement
175
142
  none: false
176
143
  requirements:
177
144
  - - ! '>='
@@ -179,7 +146,7 @@ dependencies:
179
146
  version: '0'
180
147
  type: :development
181
148
  prerelease: false
182
- version_requirements: *70208102937020
149
+ version_requirements: *70136220756180
183
150
  description: A prototype of the Bloom distributed programming language as a Ruby DSL.
184
151
  email:
185
152
  - bloomdevs@gmail.com
@@ -193,9 +160,6 @@ extra_rdoc_files: []
193
160
  files:
194
161
  - lib/bud/aggs.rb
195
162
  - lib/bud/bud_meta.rb
196
- - lib/bud/bust/bust.rb
197
- - lib/bud/bust/client/idempotence.rb
198
- - lib/bud/bust/client/restclient.rb
199
163
  - lib/bud/collections.rb
200
164
  - lib/bud/depanalysis.rb
201
165
  - lib/bud/errors.rb
@@ -224,7 +188,6 @@ files:
224
188
  - docs/bfs.md
225
189
  - docs/bfs_arch.png
226
190
  - docs/bloom-loop.png
227
- - docs/bust.md
228
191
  - docs/cheat.md
229
192
  - docs/getstarted.md
230
193
  - docs/intro.md
@@ -236,15 +199,11 @@ files:
236
199
  - docs/visualizations.md
237
200
  - examples/basics/hello.rb
238
201
  - examples/basics/paths.rb
239
- - examples/bust/bustclient-example.rb
240
- - examples/bust/bustinspector.html
241
- - examples/bust/bustserver-example.rb
242
- - examples/bust/README.md
243
202
  - examples/chat/chat.rb
244
203
  - examples/chat/chat_protocol.rb
245
204
  - examples/chat/chat_server.rb
246
205
  - examples/chat/README.md
247
- - examples/README
206
+ - examples/README.md
248
207
  - README.md
249
208
  - LICENSE
250
209
  - History.txt
data/docs/bust.md DELETED
@@ -1,83 +0,0 @@
1
- BUST stands for BUd State Transfer and it is a REST interface to Bud. BUST consists of a Bud implementation of a client and server. The client implements bindings to a subset of the Ruby Nestful library, and the server is a lightweight HTTP server written in Ruby. Note that the BUST server currently sets the "Access-Control-Allow-Origin: *" HTTP header to override web browsers' same-origin policy.
2
-
3
- Right now BUST supports "GET" and "POST" requests, and may support "DELETE" and "PUT" requests in the future.
4
-
5
- # BUST Server
6
-
7
- For the BUST server, a "GET" request corresponds to retrieving a subset of rows of a table, and a "POST" request corresponds to inserting a row into a table. For example, the following "GET" request (assuming BUST is running on port 8080):
8
-
9
- GET localhost:8080/foo?bar=hello&baz=world
10
-
11
- would retrieve all rows in table "foo" where named schema attribute "bar" is equal to the string "hello", and named schema attribute "baz" is equal to the string "world". Right now, one limitation of BUST is that only strings are supported.
12
-
13
- To use BUST in your program, ensure you have the json gem installed. Add the "require" line for BUST:
14
-
15
- require "bud/bust/bust"
16
-
17
- In your class, make sure to:
18
-
19
- include Bust
20
-
21
- That's it! Now a BUST server will be started up when your class is instantiated. This server will listen on an open port; it will print out "Bust server listening on port xxxxx" to let you know which port it has selected. But you can select a specific port by passing a port via the "bust_port" option when you instantiate your class.
22
-
23
- You can test out the BUST server using Ruby's "net/http" library if you want, and you can also check out "BUST Inspector", a sample AJAX application that allows you to view the state of a bud instance.
24
-
25
- ## net/http Example
26
-
27
- Try running "bustserver-example.rb" in the "examples/bust" directory:
28
-
29
- ruby bustserver-example.rb
30
-
31
- Now, let's interact with our example using "net/http" from within IRB. Start up an IRB instance:
32
-
33
- irb
34
- irb(main):001:0> require 'net/http'
35
- => true
36
-
37
- bustexample.rb defines a single relation called "foo":
38
-
39
- table :foo, [:bar, :baz, :qux]
40
-
41
- Let's fire off some requests. First, let's put a new foo fact in:
42
-
43
- irb(main):002:0> res = Net::HTTP.post_form(URI.parse('http://localhost:8080/foo'), {:bar => "a", :baz => "b", :qux => "c"})
44
- => #<Net::HTTPOK 200 /OK readbody=true>
45
-
46
- Now, let's retrieve all foo facts where the "qux" attribute is "c", and the "baz" attribute is "b":
47
-
48
- irb(main):003:0> res = Net::HTTP.get(URI.parse('http://localhost:8080/foo?qux=c&baz=b'))
49
- => "[[\"a\",\"b\",\"c\"]]"
50
-
51
- Note that the response is a JSON array.
52
-
53
-
54
- ## BUST Inspector
55
-
56
- BUST Inspector -- an example app that uses XMLHttpRequests to inspect state in a Bud program using BUST is included -- (bust/bustinspector.html). Right now, it assumes that the Bud instance you're trying to inspect is listening on "localhost" at port "8080". BUST Inspector is tested to work in Firefox, and may or may not work in other browsers. BUST Inspector will query your Bud instance every second for metadata describing the tables and their schema. It will display a list of the tables in a pane on the left of the screen, with a checkbox next to each table. Selecting a checkbox renders the current table contents in the right pane (these are also updated every second while the box is checked).
57
-
58
-
59
- # BUST Client
60
-
61
- The BUST client (located in the "bust/client" folder) allows Bud applications to access REST services (including a Bud client hosting a BUST instance). The REST client is basically a wrapper for the Ruby nestful library. You'll need to ensure you have the "nestful" gem installed before you can use the REST client. To use it in your application, you need to put the require line:
62
-
63
- require 'bud/bust/client/restclient'
64
-
65
- and the include line:
66
-
67
- include RestClient
68
-
69
- To make requests, insert into the rest_req interface, whose definition is reproduced below:
70
-
71
- interface input, :rest_req, [:rid, :verb, :form, :url, :params]
72
-
73
- "rid" is a unique ID for the request, "verb" is one of ":get" or ":post", "form" is the format of the request, for example, you might use ":json", or if you're doing a form post, you'd use "form". If set to nil, "form" defaults to ":form" for ":post", and is omitted from a ":get". For ":get" requests, the "form" parameter seems to be appended onto the end of "url". For example, if you do a ":get" for "http://example.com/ex" with "form" set to ":json", the library sends an HTTP GET to "http://example.com/ex.json". "params" is a hash, which comprises the query string for a ":get", and the contents of the body in a ":post" with "form" set to ":form".
74
-
75
- The output interface is:
76
-
77
- interface output, :rest_response, [:rid, :resp, :exception]
78
-
79
- "rid" is the unique ID supplied when the request was made, "resp" is the parsed response from the server. For example, if you do a ":json" ":get", then "resp" will contain whatever JSON object was returned converted into a Ruby object, e.g., array, hash, etc. If there is an exception, then "resp" will contain a string describing the exception, and "exception" will be set to true; otherwise, "exception" will be set to false.
80
-
81
- A simple example is included (bustclient-example.rb) that does an HTTP GET on Twitter's public timeline, returning the most recent statuses, and prints them to stdout. The example is in "examples/bust/client".
82
-
83
- The BUST client does not yet support OAuth. Also unsupported so far is HTTP DELETE and PUT.
@@ -1,9 +0,0 @@
1
- To run the bust twitter example client, do the following:
2
-
3
- # ruby bustclient-example.rb
4
-
5
- To test out bust inspector, do the following:
6
-
7
- # ruby bustserver-example.rb
8
-
9
- Then, launch bustinspector.html in a web browser (only Firefox 4 has been tested thus far) on either the computer where you launched bustserver-example.rb, or any computer that has TCP port 8080 forwarded to the computer where you launched bustserver-example.rb.
@@ -1,23 +0,0 @@
1
- require 'rubygems'
2
- require 'bud'
3
- require 'bud/bust/client/restclient'
4
-
5
- class TwitterExample # :nodoc: all
6
- include Bud
7
- include RestClient
8
-
9
- bootstrap do
10
- # get the 20 most recent tweets from twitter
11
- rest_req <= [[1, :get, :json,
12
- 'http://api.twitter.com/1/statuses/public_timeline']]
13
- end
14
-
15
- bloom :print_recent_tweets do
16
- # print the tweets with user screen names
17
- stdio <~ rest_response do |r|
18
- [r.resp.map {|s| s["user"]["screen_name"] + ": " + s["text"]}] if r.rid==1
19
- end
20
- end
21
- end
22
-
23
- TwitterExample.new.run_fg
@@ -1,135 +0,0 @@
1
- <html>
2
- <head>
3
- <title>BUST Inspector</title>
4
-
5
- <script type="text/javascript">
6
- function pollState()
7
- {
8
-
9
- // 1. GET the list of tables
10
- var xmlhttp = new XMLHttpRequest();
11
- xmlhttp.open("GET","http://localhost:8080/t_table_info",false);
12
- xmlhttp.send();
13
-
14
- if (xmlhttp.readyState==4) {
15
- if (xmlhttp.status == 404){
16
- alert("error fetching 't_table_info'");
17
- }
18
- if (xmlhttp.status == 200){
19
- tableArray = JSON.parse(xmlhttp.responseText);
20
-
21
- var tablenames = document.getElementById("tablenames");
22
-
23
- for (var i = 0; i < tableArray.length; i++) {
24
- var tablename = tableArray[i][0]
25
- // if the collection is new
26
- if (!document.getElementById("coll_" + tablename)) {
27
- var newspan = document.createElement("span");
28
- newspan.innerHTML = '<input type="checkbox" id="coll_' + tablename + '"/>' + tablename + '(<small><b>' + tableArray[i][1] + '</b></small>) <br/>'
29
- while (newspan.firstChild) {
30
- tablenames.appendChild(newspan.firstChild);
31
- }
32
- }
33
- }
34
-
35
- }
36
- }
37
-
38
-
39
- // 2. GET the schema table
40
- var schemareq = new XMLHttpRequest();
41
- schemareq.open("GET","http://localhost:8080/t_table_schema",false);
42
- schemareq.send();
43
-
44
- if (schemareq.status == 404) {
45
- alert("error fetching schema info");
46
- }
47
- if (schemareq.status == 200) {
48
- schemaArray = JSON.parse(schemareq.responseText)
49
- }
50
-
51
-
52
- // 3. GET the list of checked tables
53
- form_elts = document.forms[0].elements
54
- for (var i = 0; i < form_elts.length; i++) {
55
- var tablename = form_elts[i].id.substr(5);
56
-
57
- //look it up in the schema
58
- var schemaIdx;
59
- var found = false;
60
- for (schemaIdx = 0; schemaIdx < schemaArray.length; schemaIdx++) {
61
- if (schemaArray[schemaIdx][0] == tablename) {
62
- found = true;
63
- break;
64
- }
65
- }
66
- if (!found) {
67
- alert ("no schema information for table " + tablename);
68
- }
69
-
70
- var ourSchema = schemaArray[schemaIdx][1];
71
-
72
- if (form_elts[i].checked) {
73
- var tablereq = new XMLHttpRequest();
74
- tablereq.open("GET","http://localhost:8080/"+tablename,false);
75
- tablereq.send();
76
-
77
- if (tablereq.status == 404){
78
- alert("error fetching table " + tablename);
79
- }
80
- if (tablereq.status == 200){
81
- responseArray = JSON.parse(tablereq.responseText)
82
-
83
- //schema
84
- tableText = "<table style='border-width: 1px; border-spacing: 2px; border-style: outset; border-color: gray; border-collapse: separate;'><tr>";
85
- for (var j = 0; j < ourSchema.length; j++) {
86
- tableText += "<td style='border-width: 1px; padding: 1px; border-style: inset; border-color: gray;'><b>" + ourSchema[j] + "</b></td>";
87
- }
88
- tableText += "</tr>";
89
-
90
- //data
91
- for (var k = 0; k < responseArray.length; k++) {
92
- tableText += "<tr>";
93
- for (var l = 0; l < responseArray[k].length; l++) {
94
- tableText += "<td style='border-width: 1px; padding: 1px; border-style: inset; border-color: gray;'>" + responseArray[k][l] + "</td>";
95
- }
96
- tableText += "</tr>";
97
- }
98
- tableText += "</table>";
99
-
100
- if (!document.getElementById("disp_" + tablename)) {
101
- document.getElementById("tabledisplay").innerHTML += '<div style="border: 1px solid black; float:left; padding: 0px; margin:5px;" id="disp_' + tablename + '"><h4 style="margin-top:0px;">' + tablename + '</h4>' + tableText + '</div>';
102
- } else {
103
- document.getElementById("disp_" + tablename).innerHTML = '<h4 style="margin-top:0px;">' + tablename + '</h4>' + tableText;
104
- }
105
- }
106
- } else { //if not checked
107
- if (document.getElementById("disp_" + tablename)) {
108
- document.getElementById("tabledisplay").removeChild(document.getElementById("disp_" + tablename))
109
- }
110
- }
111
-
112
- } //end for
113
-
114
-
115
- setTimeout('pollState()', 1000);
116
- }
117
-
118
- </script>
119
-
120
- </head>
121
-
122
- <body onLoad="setTimeout('pollState()', 1000);">
123
-
124
- <div style="width:100%;"><h3>BUST Inspector</h3></div>
125
- <div style="height:100%; border: 1px solid black; float:left; padding:0px; margin:5px;">
126
- <h4 style="margin-top:0px;">Collections</h4>
127
- <form id="tableform">
128
- <span id="tablenames">
129
- </span>
130
- </form>
131
- </div>
132
- <span id="tabledisplay">
133
- </span>
134
- </body>
135
- </html>
@@ -1,18 +0,0 @@
1
- require 'rubygems'
2
- require 'bud'
3
- require 'bud/bust/bust'
4
-
5
- class BustExample # :nodoc: all
6
- include Bud
7
- include Bust
8
-
9
- state do
10
- table :foo, [:bar, :baz, :qux]
11
- end
12
-
13
- bloom do
14
- stdio <~ foo {|t| [t.inspect]}
15
- end
16
- end
17
-
18
- BustExample.new(:bust_port => 8080).run_fg
data/lib/bud/bust/bust.rb DELETED
@@ -1,137 +0,0 @@
1
- require 'rubygems'
2
- require 'bud'
3
- require 'json'
4
- require 'socket'
5
- require 'uri'
6
- require 'cgi'
7
-
8
- HTTP_VERBS = ["GET", "POST"] #, "DELETE"]
9
-
10
- # a RESTful interface to Bloom code
11
- module Bust
12
- include Bud
13
- attr_reader :bust_port
14
-
15
- # used this for inspiration:
16
- # http://blogs.msdn.com/b/abhinaba/archive/2005/10/14/474841.aspx
17
-
18
- bootstrap do
19
- # copied from peter's code; this should probably be in the Bud runtime or in
20
- # some meta module
21
- @tables.each do |t|
22
- t_table_schema << [t[0], t[1].cols.clone]
23
- t_table_info << [t[0], t[1].class.to_s]
24
- end
25
-
26
- q = Queue.new
27
- Thread.start(self) do |bud|
28
- BustClass.new(bud, q)
29
- end
30
- # Wait for socket to be ready before we return from bootstrap.
31
- r = q.pop
32
- if r.class <= Exception
33
- raise r
34
- else
35
- @bust_port = r
36
- end
37
- end
38
-
39
- class BustClass
40
- class BustHandler
41
- def initialize(session, request, body, bud)
42
- @session = session
43
- @request = request
44
- @body = body
45
- @bud = bud
46
- end
47
-
48
- def serve()
49
- puts "Request: " + @request
50
- puts "Body: " + @body.inspect if @body
51
-
52
- for type in HTTP_VERBS
53
- if @request =~ Regexp.new(type + " .* HTTP*")
54
- break reqstr = @request.gsub(Regexp.new(type + " "), '').gsub(/ HTTP.*/, '')
55
- end
56
- end
57
-
58
- uri = URI.parse(reqstr)
59
- uri_params = {}
60
- uri_params = CGI.parse(uri.query) if uri.query
61
- table_name = uri.path[1..-1].split(".")[0] # hack; we always return JSON
62
- # "Access-Control-Allow-Origin: *" disables same-origin policy to allow
63
- # XMLHttpRequests from any origin
64
- success = "HTTP/1.1 200 OK\r\nServer: Bud\r\nContent-type: application/json\r\nAccess-Control-Allow-Origin: *\r\n\r\n"
65
- failure = "HTTP/1.1 404 Object Not Found\r\nServer: Bud\r\nAccess-Control-Allow-Origin: *\r\n\r\n"
66
-
67
- begin
68
- if @request =~ /GET .* HTTP*/
69
- puts "GET shouldn't have body" if @body
70
- # select the appropriate elements from the table
71
- desired_elements = @bud.send(table_name.to_sym).find_all do |t|
72
- uri_params.all? {|k, v|
73
- (eval "t." + k.to_s) == v[0]
74
- }
75
- end
76
- @session.print success
77
- desired_elements = desired_elements .map{|elem|
78
- elem.class <= Struct ? elem.to_a : elem
79
- }
80
- @session.print desired_elements.to_json
81
- elsif @request =~ /POST .* HTTP*/
82
- # instantiate a new tuple
83
- tuple_to_insert = []
84
- @body.each do |k, v|
85
- index = @bud.send(table_name.to_sym).cols.find_index(k.to_sym)
86
- for i in (tuple_to_insert.size..index)
87
- tuple_to_insert << nil
88
- end
89
- tuple_to_insert[index] = v[0]
90
- end
91
- # actually insert the puppy
92
- @bud.async_do {
93
- @bud.send(table_name.to_sym) <+ [tuple_to_insert]
94
- }
95
- @session.print success
96
- end
97
- rescue Exception
98
- puts "exception: #{$!}"
99
- @session.print failure
100
- ensure
101
- @session.close
102
- end
103
- end
104
- end
105
-
106
- def initialize(bud, q)
107
- # allow user-configurable port
108
- begin
109
- server = TCPServer.new(bud.ip, (bud.options[:bust_port] or 0))
110
- port = server.addr[1]
111
- puts "Bust server listening on #{bud.ip}:#{port}"
112
- # We're now ready to accept connections
113
- q << port
114
- rescue Exception => e
115
- # Avoid deadlock on queue, report exception to caller
116
- q << e
117
- end
118
-
119
- loop do
120
- session = server.accept
121
- request = session.gets
122
- length = nil
123
- body = nil
124
- while req = session.gets
125
- length = Integer(req.split(" ")[1]) if req.match(/^Content-Length:/)
126
- if req.match(/^\r\n$/)
127
- body = CGI.parse(session.read(length)) if length
128
- break
129
- end
130
- end
131
- Thread.start(session, request, body, bud) do |session, request, body, bud|
132
- BustHandler.new(session, request, body, bud).serve()
133
- end
134
- end
135
- end
136
- end
137
- end
@@ -1,10 +0,0 @@
1
- require 'rubygems'
2
- require 'bud'
3
-
4
- module Idempotence #:nodoc: all
5
- state do
6
- table :dead, [:dead]
7
- end
8
-
9
- def bust_idempotent(r) (dead.include? r) ? false : dead.insert(r) end
10
- end