nosql-tutorial 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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"
|