nosql-tutorial 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.markdown +25 -14
- data/Rakefile +2 -2
- data/VERSION.yml +2 -2
- data/lib/public/doc/activerecord/000-activerecord.rb +77 -0
- data/lib/public/doc/activerecord/100-datamapper.rb +60 -0
- data/lib/public/doc/activerecord/activerecord_spec_helper.rb +13 -0
- data/lib/public/doc/activerecord/datamapper_spec_helper.rb +15 -0
- data/lib/public/doc/couchdb/blog-inline.rb +60 -0
- data/lib/public/doc/couchdb/collseq.rb +22 -0
- data/lib/public/doc/datamapper/000-sqlite3.rb +65 -0
- data/lib/public/doc/datamapper/001-ale-kino.rb +69 -0
- data/lib/public/doc/datamapper/010-postgres.rb +95 -0
- data/lib/public/doc/datamapper/bug.rb +25 -0
- data/lib/public/doc/mail/mail-20.rb +40 -0
- data/lib/public/doc/mail/mail-21.rb +62 -0
- data/lib/public/doc/mail/mail-gmail.rb +34 -0
- data/lib/public/doc/mail/private.yaml +7 -0
- data/lib/public/doc/mail/swistak.jpeg +0 -0
- data/lib/public/images/kumkwat.jpg +0 -0
- data/lib/public/stylesheets/nosql.css +8 -0
- data/lib/views/blogi.rdiscount +5 -0
- data/lib/views/couchdb-couchapp.rdiscount +83 -0
- data/lib/views/couchdb-crud.rdiscount +205 -0
- data/lib/views/couchdb-futon.rdiscount +116 -0
- data/lib/views/couchdb-ruby.rdiscount +53 -0
- data/lib/views/couchdb-views.rdiscount +162 -0
- data/lib/views/couchdb.rdiscount +122 -0
- data/lib/views/main.rdiscount +55 -12
- data/lib/views/summary.rdiscount +52 -3
- data/lib/views/zadania.rdiscount +9 -0
- metadata +30 -6
@@ -0,0 +1,95 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
#
|
3
|
+
# 1. zakładamy bazę:
|
4
|
+
# createdb test
|
5
|
+
# 2. uruchamiamy ten skrypt:
|
6
|
+
# ruby 010-postgres.rb
|
7
|
+
# 3. przyłączamy się do bazy:
|
8
|
+
# psql test
|
9
|
+
# \d
|
10
|
+
# \encoding # powinno być UTF8
|
11
|
+
# \q
|
12
|
+
|
13
|
+
require 'rubygems'
|
14
|
+
require 'dm-core'
|
15
|
+
|
16
|
+
# http://cheat.errtheblog.com/s/datamapper/
|
17
|
+
# DataMapper.setup(:default, "adapter://user:password@hostname/dbname")
|
18
|
+
|
19
|
+
# sudo gem install dm-imap-adapter
|
20
|
+
# sudo gem install dm-yaml-adapter
|
21
|
+
|
22
|
+
# http://datamapper.rubyforge.org/dm-core/DataMapper.html
|
23
|
+
#
|
24
|
+
# DataMapper.setup(:default, {
|
25
|
+
# :adapter => 'adapter_name_here',
|
26
|
+
# :database => "path/to/repo",
|
27
|
+
# :username => 'username',
|
28
|
+
# :password => 'password',
|
29
|
+
# :host => 'hostname'
|
30
|
+
# })
|
31
|
+
|
32
|
+
# :fatal, :error, :warn, :info, :debug
|
33
|
+
|
34
|
+
log = DataMapper::Logger.new(STDOUT, :debug)
|
35
|
+
|
36
|
+
log.push "==== hello datamapper"
|
37
|
+
|
38
|
+
DataMapper.setup(:default,'postgres:test')
|
39
|
+
|
40
|
+
class Post
|
41
|
+
include DataMapper::Resource
|
42
|
+
|
43
|
+
property :id, Serial
|
44
|
+
property :title, String
|
45
|
+
property :body, Text
|
46
|
+
property :created_at, DateTime
|
47
|
+
|
48
|
+
has n, :comments
|
49
|
+
end
|
50
|
+
|
51
|
+
class Comment
|
52
|
+
include DataMapper::Resource
|
53
|
+
|
54
|
+
property :id, Serial
|
55
|
+
property :posted_by, String
|
56
|
+
property :email, String
|
57
|
+
property :url, String
|
58
|
+
property :body, Text
|
59
|
+
|
60
|
+
belongs_to :post
|
61
|
+
end
|
62
|
+
|
63
|
+
class Category
|
64
|
+
include DataMapper::Resource
|
65
|
+
|
66
|
+
property :id, Serial
|
67
|
+
property :name, String
|
68
|
+
end
|
69
|
+
|
70
|
+
class Categorization
|
71
|
+
include DataMapper::Resource
|
72
|
+
|
73
|
+
property :id, Serial
|
74
|
+
property :created_at, DateTime
|
75
|
+
|
76
|
+
belongs_to :category
|
77
|
+
belongs_to :post
|
78
|
+
end
|
79
|
+
|
80
|
+
class Post
|
81
|
+
has n, :categorizations
|
82
|
+
has n, :categories, :through => :categorizations
|
83
|
+
end
|
84
|
+
|
85
|
+
class Category
|
86
|
+
has n, :categorizations
|
87
|
+
has n, :posts, :through => :categorizations
|
88
|
+
end
|
89
|
+
|
90
|
+
# Post.auto_migrate!
|
91
|
+
# Category.auto_migrate!
|
92
|
+
# Comment.auto_migrate!
|
93
|
+
# Categorization.auto_migrate!
|
94
|
+
|
95
|
+
DataMapper.auto_migrate!
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'dm-core'
|
3
|
+
require 'extlib'
|
4
|
+
|
5
|
+
DataMapper.setup :default, 'sqlite3:test.sqlite3'
|
6
|
+
|
7
|
+
Extlib::Inflection.plural_word 'xs', 'xse'
|
8
|
+
|
9
|
+
class Xs
|
10
|
+
#class Comment
|
11
|
+
include DataMapper::Resource
|
12
|
+
property :id, Serial
|
13
|
+
property :name, String
|
14
|
+
belongs_to :film
|
15
|
+
end
|
16
|
+
|
17
|
+
class Film
|
18
|
+
include DataMapper::Resource
|
19
|
+
property :id, Serial
|
20
|
+
property :name, String
|
21
|
+
has n, :xse
|
22
|
+
#has n, :comments
|
23
|
+
end
|
24
|
+
|
25
|
+
DataMapper.auto_migrate!
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'action_mailer'
|
5
|
+
require 'yaml'
|
6
|
+
|
7
|
+
# wczytujemy login + hasło z pliku private.yaml
|
8
|
+
#
|
9
|
+
# ---
|
10
|
+
# sigma:
|
11
|
+
# :login: wbzyl
|
12
|
+
# :password: 'alamakota'
|
13
|
+
# julia:
|
14
|
+
# :login: matwb
|
15
|
+
# :password: 'razdwatrzy'
|
16
|
+
|
17
|
+
private = YAML.load(IO.read('../../../../../private.yaml'))
|
18
|
+
|
19
|
+
ActionMailer::Base.smtp_settings = {
|
20
|
+
:address => 'inf.ug.edu.pl',
|
21
|
+
:port => 25,
|
22
|
+
:domain => 'ug.edu.pl',
|
23
|
+
:user_name => private['sigma'][:login],
|
24
|
+
:password => private['sigma'][:password],
|
25
|
+
:authentication => :login
|
26
|
+
}
|
27
|
+
|
28
|
+
class Notification < ActionMailer::Base
|
29
|
+
def signup_message(recipient)
|
30
|
+
from 'wbzyl@inf.ug.edu.pl'
|
31
|
+
content_type 'text/plain; charset=utf-8'
|
32
|
+
recipients recipient
|
33
|
+
subject 'action mailer test: 4'
|
34
|
+
body 'Treść emaila #4.'
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
puts Notification.create_signup_message('matwb@ug.edu.pl')
|
39
|
+
|
40
|
+
Notification.deliver_signup_message('matwb@ug.edu.pl')
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'action_mailer'
|
5
|
+
require 'mime/types'
|
6
|
+
require 'yaml'
|
7
|
+
|
8
|
+
# wczytujemy login + hasło z pliku private.yaml
|
9
|
+
#
|
10
|
+
# ---
|
11
|
+
# sigma:
|
12
|
+
# :login: wbzyl
|
13
|
+
# :password: 'alamakota'
|
14
|
+
# julia:
|
15
|
+
# :login: matwb
|
16
|
+
# :password: 'razdwatrzy'
|
17
|
+
|
18
|
+
private = YAML.load(IO.read('../../../../../private.yaml'))
|
19
|
+
|
20
|
+
ActionMailer::Base.smtp_settings = {
|
21
|
+
:address => 'inf.ug.edu.pl',
|
22
|
+
:port => 25,
|
23
|
+
:domain => 'ug.edu.pl',
|
24
|
+
:user_name => private['sigma'][:login],
|
25
|
+
:password => private['sigma'][:password],
|
26
|
+
:authentication => :login
|
27
|
+
}
|
28
|
+
|
29
|
+
class Notification < ActionMailer::Base
|
30
|
+
def directory_dump(recipient, directory=Dir.pwd)
|
31
|
+
from 'wbzyl@inf.ug.edu.pl'
|
32
|
+
content_type 'text/plain; charset=utf-8'
|
33
|
+
recipients recipient
|
34
|
+
subject "zdjęcia z katalogu: #{directory}"
|
35
|
+
body %{Zdjęcia z katalogu: "#{directory}":}
|
36
|
+
Dir.glob('*.jpeg') do |f|
|
37
|
+
path = File.join(directory, f)
|
38
|
+
attachment('image/jpeg') do |a|
|
39
|
+
a.body = File.read(path)
|
40
|
+
a.filename = f
|
41
|
+
a.transfer_encoding = 'base64'
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
#puts Notification.create_directory_dump('matwb@ug.edu.pl', Dir.pwd)
|
48
|
+
|
49
|
+
Notification.deliver_directory_dump('matwb@ug.edu.pl')
|
50
|
+
|
51
|
+
__END__
|
52
|
+
|
53
|
+
removing file from repo:
|
54
|
+
|
55
|
+
git filter-branch --index-filter \
|
56
|
+
'git rm --cached --ignore-unmatch private.yaml' merge-point..HEAD
|
57
|
+
|
58
|
+
# remove the temporary history git-filter-branch otherwise leaves behind for a long time
|
59
|
+
rm -rf .git/refs/original/ && git reflog expire --all && git gc --aggressive --prune
|
60
|
+
|
61
|
+
git push
|
62
|
+
#git push -f
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
# sudo gem install ambethia-smtp-tls -v '1.1.2' --source http://gems.github.com
|
4
|
+
|
5
|
+
require 'rubygems'
|
6
|
+
require 'action_mailer'
|
7
|
+
require 'smtp-tls'
|
8
|
+
|
9
|
+
require 'yaml'
|
10
|
+
|
11
|
+
private = YAML.load(IO.read('../../../../../private.yaml'))['gmail']
|
12
|
+
|
13
|
+
ActionMailer::Base.delivery_method = :smtp
|
14
|
+
|
15
|
+
class SimpleMailer < ActionMailer::Base
|
16
|
+
def simple_message(recipient)
|
17
|
+
from 'wlodek.bzyl@gmail.com'
|
18
|
+
recipients recipient
|
19
|
+
subject 'Tę wiadomość wysłano z Gmail'
|
20
|
+
body 'To naprawdę działa!'
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
ActionMailer::Base.smtp_settings = {
|
25
|
+
:address => 'smtp.gmail.com',
|
26
|
+
:domain => 'gmail.com',
|
27
|
+
:port => 587,
|
28
|
+
:user_name => private['login'],
|
29
|
+
:password => private['password'],
|
30
|
+
:authentication => 'plain',
|
31
|
+
:enable_starttls_auto => true
|
32
|
+
}
|
33
|
+
|
34
|
+
SimpleMailer.deliver_simple_message('matwb@ug.edu.pl')
|
Binary file
|
Binary file
|
@@ -110,6 +110,14 @@ blockquote p.author {
|
|
110
110
|
text-align: right;
|
111
111
|
}
|
112
112
|
|
113
|
+
blockquote h2 {
|
114
|
+
font-size: 100%;
|
115
|
+
font-family: Cyklop, sans-serif;
|
116
|
+
padding-bottom: 0px;
|
117
|
+
border-bottom: none;
|
118
|
+
color: #A00;
|
119
|
+
}
|
120
|
+
|
113
121
|
h2 {
|
114
122
|
font-size: 130%;
|
115
123
|
padding-bottom: 6px;
|
@@ -0,0 +1,83 @@
|
|
1
|
+
#### {% title "CouchDB — CouchApp" %}
|
2
|
+
|
3
|
+
# CouchDB — CouchApp
|
4
|
+
|
5
|
+
Czym jest [CouchApp]():
|
6
|
+
„CouchApp—a set of scripts that allow complete, stand-alone CouchDB
|
7
|
+
applications to be built using just HTML and JavaScript. These
|
8
|
+
applications are housed in the CouchDB database, meaning that when the
|
9
|
+
database is replicated, any applications stored in that database are
|
10
|
+
also replicated.”
|
11
|
+
|
12
|
+
## Instalacja
|
13
|
+
|
14
|
+
CouchApp jest modułem do Pythona. Moduły można instalować
|
15
|
+
korzystając z programu *easy_install*.
|
16
|
+
Program ten znajdziemy w paczce o nazwie *setuptool*
|
17
|
+
(albo o podobnej nazwie).
|
18
|
+
|
19
|
+
sudo yum install setuptool
|
20
|
+
sudo easy_install couchdb
|
21
|
+
sudo easy_install simplejson
|
22
|
+
sudo easy_install couchapp
|
23
|
+
|
24
|
+
## Hello World
|
25
|
+
|
26
|
+
mkdir ~/couchapps
|
27
|
+
cd ~/couchapps
|
28
|
+
couchapp hello_world
|
29
|
+
|
30
|
+
Teraz
|
31
|
+
|
32
|
+
tree hello_world
|
33
|
+
hello_world/
|
34
|
+
|-- _attachments
|
35
|
+
| |-- index.html
|
36
|
+
| `-- style
|
37
|
+
| `-- main.css
|
38
|
+
|-- _id
|
39
|
+
|-- couchapp.json
|
40
|
+
|-- lists
|
41
|
+
|-- shows
|
42
|
+
|-- updates
|
43
|
+
|-- vendor
|
44
|
+
| `-- couchapp
|
45
|
+
| |-- README.md
|
46
|
+
| |-- _attachments
|
47
|
+
| | `-- jquery.couchapp.js
|
48
|
+
| |-- couchapp.js
|
49
|
+
| |-- date.js
|
50
|
+
| |-- metadata.json
|
51
|
+
| |-- path.js
|
52
|
+
| `-- template.js
|
53
|
+
`-- views
|
54
|
+
|
55
|
+
Następnie:
|
56
|
+
|
57
|
+
couchapp push hello_world http://127.0.0.1:5984/hello_world
|
58
|
+
[INFO] Visit your CouchApp here:
|
59
|
+
http://127.0.0.1:5984/hello_world/_design/hello_world/index.html
|
60
|
+
|
61
|
+
Wchodzimy na powyżej wypisany URI.
|
62
|
+
|
63
|
+
Wymieniamy zawartość pliku *index.html*:
|
64
|
+
|
65
|
+
<!DOCTYPE html>
|
66
|
+
<html>
|
67
|
+
<head>
|
68
|
+
<meta charset="utf-8">
|
69
|
+
<title>Witaj CouchApp</title>
|
70
|
+
<link rel="stylesheet" href="style/main.css" type="text/css">
|
71
|
+
</head>
|
72
|
+
<body>
|
73
|
+
<h1>Witaj CouchApp</h1>
|
74
|
+
<p>Jest fajnie!</p>
|
75
|
+
</body>
|
76
|
+
<script src="/_utils/script/json2.js"></script>
|
77
|
+
<script src="/_utils/script/jquery.js?1.3.2"></script>
|
78
|
+
<script src="/_utils/script/jquery.couch.js?0.11.0b"></script>
|
79
|
+
</html>
|
80
|
+
|
81
|
+
Uaktualniamy aplikację, wykonując z katalogu *hello_world* polecenie:
|
82
|
+
|
83
|
+
couchapp push . http://127.0.0.1:5984/hello_world
|
@@ -0,0 +1,205 @@
|
|
1
|
+
#### {% title "CouchDB – CRUD" %}
|
2
|
+
|
3
|
+
# CouchDB – Dokumenty
|
4
|
+
|
5
|
+
W przykładach poniżej będziemy korzystać z:
|
6
|
+
|
7
|
+
* [HTTP Document API](http://wiki.apache.org/couchdb/HTTP_Document_API)
|
8
|
+
|
9
|
+
|
10
|
+
## Wykonywanie CRUD na dokumentach
|
11
|
+
|
12
|
+
Zaczynamy od utworzenia bazy o nazwie *owoce*:
|
13
|
+
|
14
|
+
curl -X PUT http://127.0.0.1:5984/owoce/
|
15
|
+
|
16
|
+
### Create
|
17
|
+
|
18
|
+
Dodajemy kilka rekordów do bazy korzystając z programu *curl*:
|
19
|
+
|
20
|
+
curl -X PUT http://127.0.0.1:5984/owoce/1001 \
|
21
|
+
-d '{"item":"jabłko","price":{"biedronka":3.44,"tesco":2.12,"real":4.10}}'
|
22
|
+
curl -X PUT http://127.0.0.1:5984/owoce/1002 \
|
23
|
+
-d '{"item":"banan","price":{"biedronka":6.44,"tesco":1.12,"real":4.50}}'
|
24
|
+
curl -X PUT http://127.0.0.1:5984/owoce/1003 \
|
25
|
+
-d '{"item":"kiwi","price":{"biedronka":1.44,"tesco":1.12,"real":1.10}}'
|
26
|
+
curl -X PUT http://127.0.0.1:5984/owoce/1004 \
|
27
|
+
-d '{"item":"kumkwat"}'
|
28
|
+
|
29
|
+
Dodawanie rekordów do bazy w ten sposób jest trochę męczące.
|
30
|
+
[HTTP Bulk Document API](http://wiki.apache.org/couchdb/HTTP_Bulk_Document_API)
|
31
|
+
ułatwia wprowadzanie (usuwanie, uaktualnianie – też) wielu rekordów do bazy:
|
32
|
+
|
33
|
+
curl -X POST -d @owoce.json http://127.0.0.1:5984/owoce/_bulk_docs
|
34
|
+
|
35
|
+
gdzie plik *owoce.json* zawiera:
|
36
|
+
|
37
|
+
:::json
|
38
|
+
{
|
39
|
+
"docs": [
|
40
|
+
{"_id":"2001", "item":"gruszka", "price":{"tesco":5.00, "real":4.10}},
|
41
|
+
{"_id":"2002", "item":"wiśnia", "price":{"tesco":3.14, "real":2.71}},
|
42
|
+
{"_id":"2003", "item":"morela", "price":{"tesco":4.28, "real":4.10}}
|
43
|
+
]
|
44
|
+
}
|
45
|
+
|
46
|
+
Jaką funkcję spełniają liczby 1001, …, 1004, 2001, 2002, 2003.
|
47
|
+
Czy można by było zamiast tych liczb użyć napisów: apple, banana, itd.?
|
48
|
+
|
49
|
+
curl -X PUT http://127.0.0.1:5984/owoce/orange -d '{"item":"pomarańcze"}'
|
50
|
+
=> {"ok":true,"id":"orange","rev":"1-512c"}
|
51
|
+
|
52
|
+
Pole **rev**. Do czego ono służy?
|
53
|
+
|
54
|
+
|
55
|
+
### Delete
|
56
|
+
|
57
|
+
Usuwamy ten dokument z bazy:
|
58
|
+
|
59
|
+
curl -X DELETE http://127.0.0.1:5984/owoce/orange?rev=1-2618
|
60
|
+
=> {"ok":true,"id":"orange","rev":"1-123d"}
|
61
|
+
|
62
|
+
|
63
|
+
### Get
|
64
|
+
|
65
|
+
Pobieramy dokument z bazy *owoce*:
|
66
|
+
|
67
|
+
curl -X GET http://127.0.0.1:5984/owoce/1001
|
68
|
+
=> { "_id":"1001",
|
69
|
+
"_rev":"1-627c94",
|
70
|
+
"item":"jab\u0142ko","price":{"biedronka":3.44,"tesco":2.12,"real":4.1}
|
71
|
+
}
|
72
|
+
|
73
|
+
|
74
|
+
### Copy (tego nie ma w CRUD)
|
75
|
+
|
76
|
+
Kopiujemy dokument z *_id = 1004*:
|
77
|
+
|
78
|
+
curl -X COPY http://127.0.0.1:5984/owoce/1004 -H "Destination: orange"
|
79
|
+
=> {"id":"orange","rev":"1-46050e"}
|
80
|
+
|
81
|
+
Do czego służy opcja `-H`? Wskazówka: skorzystać z opcji `-v` (ang. *verbose*).
|
82
|
+
|
83
|
+
*Uwaga:* klucz **rev** wypisany powyżej jest przykładowy.
|
84
|
+
|
85
|
+
|
86
|
+
### Update
|
87
|
+
|
88
|
+
Uaktualniamy dokument *orange*:
|
89
|
+
|
90
|
+
curl -X PUT http://127.0.0.1:5984/owoce/orange \
|
91
|
+
-d '{"_rev":"1-46050e3","item":"orange"}'
|
92
|
+
|
93
|
+
*Uwaga:* powyżej należy wpisać klucz **rev** wypisany przez polecenie *COPY*.
|
94
|
+
|
95
|
+
|
96
|
+
## Wbudowane widoki
|
97
|
+
|
98
|
+
Jaki widok? Tak naprawdę, to zadajemy zapytanie.
|
99
|
+
|
100
|
+
Do pobrania wszystkich dokumentów z bazy *owoce* skorzystamy
|
101
|
+
z wbudowanego widoku *_all_docs*:
|
102
|
+
|
103
|
+
curl -X GET http://127.0.0.1:5984/owoce/_all_docs
|
104
|
+
=> {"total_rows":6,"offset":0,"rows":[
|
105
|
+
{"id":"1001","key":"1001","value":{"rev":"1-627c"}},
|
106
|
+
...
|
107
|
+
{"id":"orange","key":"orange","value":{"rev":"2-9014"}},
|
108
|
+
]}
|
109
|
+
|
110
|
+
Można też zmienić kolejność pobieranych dokumentów:
|
111
|
+
|
112
|
+
curl -X GET http://127.0.0.1:5984/owoce/_all_docs?descending=true
|
113
|
+
|
114
|
+
Można też pobrać kilka dokumentów, np. tylko jeden dokument:
|
115
|
+
|
116
|
+
curl -X GET http://127.0.0.1:5984/owoce/_all_docs?descending=true\&limit=1
|
117
|
+
|
118
|
+
Można pobrać dokumenty z zawartością:
|
119
|
+
|
120
|
+
curl -X GET http://127.0.0.1:5984/owoce/_all_docs?include_docs=true
|
121
|
+
|
122
|
+
I jeszcze kilka przykładów (bazę *collator* tworzymy za pomocą
|
123
|
+
skryptu {%= link_to "collseq.rb", "/doc/couchdb/collseq.rb" %}):
|
124
|
+
|
125
|
+
curl -X GET http://localhost:5984/collator/_all_docs?startkey=\"64\"\&limit=4
|
126
|
+
curl -X GET http://localhost:5984/collator/_all_docs?startkey=\"64\"\&limit=2\&descending=true
|
127
|
+
curl -X GET http://localhost:5984/collator/_all_docs?startkey=\"64\"\&endkey=\"68\"
|
128
|
+
|
129
|
+
Skorzystamy jeszcze z jednego wbudowanego widoku:
|
130
|
+
|
131
|
+
curl -X GET http://127.0.0.1:5984/collator/_all_docs_by_seq
|
132
|
+
|
133
|
+
(Został usunięty w ostatniej wersji CouchDB?)
|
134
|
+
|
135
|
+
|
136
|
+
## Załączniki
|
137
|
+
|
138
|
+
Dodajemy obrazek *kumkwat.jpg* do pierwszego rekordu z *_id=2001*:
|
139
|
+
|
140
|
+
curl -vX PUT http://127.0.0.1:5984/owoce/2001/kumkwat.jpg?rev=1-3854 \
|
141
|
+
-H "Content-Type: image/jpg" --data-binary @kumkwat.jpg
|
142
|
+
|
143
|
+
Obrazek pobieramy tak:
|
144
|
+
|
145
|
+
curl -X GET http://127.0.0.1:5984/owoce/2001/kumkwat.jpg > k.jpg
|
146
|
+
|
147
|
+
|
148
|
+
## Przykłady
|
149
|
+
|
150
|
+
Pobieramy obrazek z bazy i wyświetlamy go na stronie:
|
151
|
+
|
152
|
+
:::html
|
153
|
+
<!DOCTYPE html>
|
154
|
+
<meta charset="utf-8" />
|
155
|
+
<title>Kumkwaty</title>
|
156
|
+
<p>
|
157
|
+
Kumkwaty są smaczne:
|
158
|
+
<img src="http://localhost:5984/owoce/2001/kumkwat.jpg">
|
159
|
+
</p>
|
160
|
+
|
161
|
+
Zaczynamy od omówienia przykładu
|
162
|
+
[jQuery.getJSON() – jQuery API](http://api.jquery.com/jQuery.getJSON/)
|
163
|
+
|
164
|
+
Teraz drugi przykład korzystający z
|
165
|
+
CouchDB + jQuery + JSONP oraz owocowa baza danych:
|
166
|
+
|
167
|
+
:::html
|
168
|
+
<!DOCTYPE html>
|
169
|
+
<html>
|
170
|
+
<head>
|
171
|
+
<meta charset="utf-8">
|
172
|
+
<title>JSONP</title>
|
173
|
+
</head>
|
174
|
+
<body>
|
175
|
+
|
176
|
+
<h4 id="item"></h4>
|
177
|
+
<p id="price"></p>
|
178
|
+
|
179
|
+
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.1/jquery.min.js"></script>
|
180
|
+
<script>
|
181
|
+
$.getJSON('http://localhost:5984/owoce/2002', "callback=?", function(data){
|
182
|
+
$("#item").html(data.item);
|
183
|
+
$("#price").html("tesco: " + data.price["tesco"] + " real: " + data.price["real"]);
|
184
|
+
//console.log(data);
|
185
|
+
});
|
186
|
+
</script>
|
187
|
+
|
188
|
+
</body>
|
189
|
+
</html>
|
190
|
+
|
191
|
+
Powyższy kod umieszczamy w pliku *owoce.html* a sam plik w katalogu
|
192
|
+
*public_html* i sprawdzamy czy wszystko działa wchodząc na stronę:
|
193
|
+
|
194
|
+
http://localhost/~wbzyl/owoce.html
|
195
|
+
|
196
|
+
Czy zadziała, jeśli plik *owoce.html* umieścimy na *Sigmie*
|
197
|
+
i wejdziemy na stronę:
|
198
|
+
|
199
|
+
http://sigma.ug.edu.pl/~wbzyl/owoce.html
|
200
|
+
|
201
|
+
Dlaczego? A jeśli zmienimy URI przy `$.getJSON`?
|
202
|
+
|
203
|
+
|
204
|
+
[couchdb]: http://books.couchdb.org/relax/ "CouchDB: The Definitive Guide"
|
205
|
+
[couchdb wiki]: http://wiki.apache.org/couchdb/ "Couchdb Wiki"
|