wbzyl-datamapper-tutorial 0.0.8 → 0.0.9
Sign up to get free protection for your applications and to get access to all the features.
- data/README.markdown +9 -7
- data/Rakefile +8 -8
- data/VERSION.yml +4 -0
- data/config.ru +0 -5
- data/lib/config.ru +12 -0
- data/lib/datamapper-tutorial.rb +20 -5
- data/lib/public/doc/plain-text-files/contacts.yaml +11 -0
- data/lib/public/doc/plain-text-files/contacts_g.rb +105 -0
- data/lib/public/doc/plain-text-files/contacts_g_test.rb +51 -0
- data/lib/public/doc/plain-text-files/contacts_y.rb +57 -0
- data/lib/public/doc/plain-text-files/contacts_y_test.rb +39 -0
- data/lib/public/doc/plain-text-files/gdbm-example.rb +22 -0
- data/lib/public/doc/plain-text-files/gdbm_contacts/Ja/305/233_Ma/305/202gosia/extras +0 -0
- data/lib/public/doc/plain-text-files/gdbm_contacts/Ja/305/233_Ma/305/202gosia/home +0 -0
- data/lib/public/doc/plain-text-files/gdbm_contacts/Ja/305/233_Ma/305/202gosia/work +0 -0
- data/lib/public/doc/plain-text-files/gdbm_contacts/Joe_Smith/extras +0 -0
- data/lib/public/doc/plain-text-files/gdbm_contacts/Joe_Smith/home +0 -0
- data/lib/public/doc/plain-text-files/gdbm_contacts/Joe_Smith/work +0 -0
- data/lib/public/doc/using-plain-text-files-for-data-persistence.pdf +0 -0
- data/lib/public/images/datamapper.png +0 -0
- data/lib/public/images/datamapper.svg +95 -0
- data/lib/public/stylesheets/datamapper.css +160 -0
- data/lib/public/stylesheets/fonts/Cyklop-Italic.otf +0 -0
- data/lib/public/stylesheets/ie.css +1 -0
- data/lib/public/stylesheets/screen.css +48 -66
- data/lib/public/stylesheets/uv.css +121 -0
- data/lib/views/intro.rdiscount +10 -0
- data/lib/views/layout.rdiscount +28 -7
- data/lib/views/main.rdiscount +16 -6
- data/lib/views/using-plain-text-files-for-data-persistence.rdiscount +53 -0
- metadata +32 -12
- data/lib/public/Onyx_Mother_O_Pearl.html +0 -122
- data/lib/public/stylesheets/application.css +0 -113
- data/lib/public/stylesheets/coderay.css +0 -99
data/README.markdown
CHANGED
@@ -2,16 +2,18 @@
|
|
2
2
|
|
3
3
|
1. [pastie](http://www.dzone.com/links/datamapper_sinatra_tutorial.html),
|
4
4
|
[pastie2](http://blog.zerosum.org/2008/7/2/clone-pastie-with-sinatra-datamapper-redux).
|
5
|
-
2. [
|
5
|
+
2. [apps written in sinatra, uses datamapper](http://github.com/zapnap/mogo/)
|
6
6
|
3. [A simple Twitter application template, built in Ruby with
|
7
7
|
Sinatra and DataMapper](http://github.com/zapnap/retweet/)
|
8
|
-
|
9
8
|
|
10
|
-
##
|
9
|
+
## Data persistence
|
11
10
|
|
12
|
-
1.
|
13
|
-
|
11
|
+
1. [using plain-text files for data persistence](/doc/using-plain-text-files-for-data-persistence.pdf)
|
12
|
+
1. [ohm](http://ohm.keyvalue.org/) — Object-hash mapping library for
|
13
|
+
[Redis](http://code.google.com/p/redis/). Datamapper adapter for Redis:
|
14
|
+
[DataMapper loves Redis](http://whoahbot.com/2009/05/27/redis-and-datamapper.html)
|
15
|
+
\([source, example](http://github.com/whoahbot/dm-redis-adapter/)\).
|
14
16
|
|
15
|
-
|
16
|
-
1_000_000 : czas?
|
17
|
+
## Todo
|
17
18
|
|
19
|
+
1. redis.spec for Fedora?
|
data/Rakefile
CHANGED
@@ -13,13 +13,13 @@ Moje notatki do Datamappera.
|
|
13
13
|
EOF
|
14
14
|
s.summary = "Prosta aplikacja Sinatry."
|
15
15
|
|
16
|
-
s.files = %w[TODO Rakefile config.ru VERSION.yml] + FileList["lib/**/*"]
|
16
|
+
s.files = %w[LICENSE TODO Rakefile config.ru VERSION.yml] + FileList["lib/**/*"]
|
17
17
|
|
18
18
|
s.add_dependency 'rack'
|
19
19
|
s.add_dependency 'sinatra'
|
20
20
|
s.add_dependency 'rdiscount'
|
21
|
-
s.add_dependency 'sinatra-rdiscount'
|
22
|
-
s.add_dependency 'codehighlighter-middleware'
|
21
|
+
s.add_dependency 'wbzyl-sinatra-rdiscount'
|
22
|
+
s.add_dependency 'wbzyl-codehighlighter-middleware'
|
23
23
|
s.add_dependency 'coderay'
|
24
24
|
|
25
25
|
s.rubyforge_project = 'datamapper-tutorial'
|
@@ -31,8 +31,8 @@ rescue LoadError
|
|
31
31
|
puts " sudo gem install technicalpickles-jeweler -s http://gems.github.com"
|
32
32
|
end
|
33
33
|
|
34
|
-
Rake::TestTask.new(:test) do |t|
|
35
|
-
t.libs << 'lib' << 'test'
|
36
|
-
t.pattern = 'test/**/*_test.rb'
|
37
|
-
t.verbose = false
|
38
|
-
end
|
34
|
+
#Rake::TestTask.new(:test) do |t|
|
35
|
+
# t.libs << 'lib' << 'test'
|
36
|
+
# t.pattern = 'test/**/*_test.rb'
|
37
|
+
# t.verbose = false
|
38
|
+
#end
|
data/VERSION.yml
ADDED
data/config.ru
CHANGED
@@ -3,11 +3,6 @@
|
|
3
3
|
$LOAD_PATH.unshift("#{File.dirname(__FILE__)}/lib")
|
4
4
|
require 'config'
|
5
5
|
|
6
|
-
#FileUtils.mkdir_p 'log' unless File.exists?('log')
|
7
|
-
#log = File.new("log/sinatra.log", "a")
|
8
|
-
#STDOUT.reopen(log)
|
9
|
-
#STDERR.reopen(log)
|
10
|
-
|
11
6
|
# require 'rack/cache'
|
12
7
|
# use Rack::Cache
|
13
8
|
run WB_DatamapperTutorial
|
data/lib/config.ru
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'datamapper-tutorial'
|
2
|
+
|
3
|
+
gem 'wbzyl-rack-codehighlighter'
|
4
|
+
require 'rack/codehighlighter'
|
5
|
+
|
6
|
+
gem 'ultraviolet'
|
7
|
+
require 'uv'
|
8
|
+
|
9
|
+
use Rack::ShowExceptions
|
10
|
+
use Rack::Lint
|
11
|
+
use Rack::Codehighlighter, :ultraviolet, :element => '//pre/code', :markdown => true
|
12
|
+
run WB::DatamapperTutorial.new
|
data/lib/datamapper-tutorial.rb
CHANGED
@@ -2,16 +2,25 @@
|
|
2
2
|
|
3
3
|
# Zobacz przykład: http://gist.github.com/38605
|
4
4
|
|
5
|
-
gem 'rdiscount'
|
6
|
-
gem 'sinatra'
|
7
|
-
|
5
|
+
#gem 'rdiscount'
|
6
|
+
#gem 'sinatra'
|
7
|
+
|
8
|
+
#gem 'wbzyl-sinatra-rdiscount'
|
9
|
+
#gem 'emk-sinatra-url-for'
|
10
|
+
#gem 'wbzyl-sinatra-static-assets'
|
8
11
|
|
9
12
|
require 'rdiscount'
|
10
13
|
require 'sinatra/base'
|
11
14
|
require 'sinatra/rdiscount'
|
12
15
|
|
16
|
+
require 'sinatra/url_for'
|
17
|
+
require 'sinatra/static_assets'
|
18
|
+
|
13
19
|
module WB
|
14
20
|
class DatamapperTutorial < Sinatra::Base
|
21
|
+
helpers Sinatra::UrlForHelper
|
22
|
+
helpers Sinatra::StaticAssets
|
23
|
+
|
15
24
|
# disable overriding public and views dirs
|
16
25
|
set :app_file, __FILE__
|
17
26
|
set :static, true
|
@@ -33,7 +42,14 @@ module WB
|
|
33
42
|
|
34
43
|
# helper methods
|
35
44
|
|
36
|
-
|
45
|
+
def page_title
|
46
|
+
@title || ""
|
47
|
+
end
|
48
|
+
|
49
|
+
# def title=(name)... does not work, bug?
|
50
|
+
def title(name)
|
51
|
+
@title = " | #{name}"
|
52
|
+
end
|
37
53
|
|
38
54
|
get '/' do
|
39
55
|
rdiscount :main
|
@@ -53,4 +69,3 @@ module WB
|
|
53
69
|
use Rack::Lint
|
54
70
|
end
|
55
71
|
end
|
56
|
-
|
@@ -0,0 +1,105 @@
|
|
1
|
+
require 'gdbm'
|
2
|
+
require 'fileutils'
|
3
|
+
|
4
|
+
class ContactList
|
5
|
+
|
6
|
+
attr_reader :contact_cache
|
7
|
+
|
8
|
+
def initialize(dir)
|
9
|
+
@dir = dir
|
10
|
+
@contact_cache = []
|
11
|
+
end
|
12
|
+
|
13
|
+
def [](name)
|
14
|
+
contact = @contact_cache.find {|c| c.name == name }
|
15
|
+
return contact if contact
|
16
|
+
contact = Contact.new(name)
|
17
|
+
Dir.chdir(@dir) do
|
18
|
+
if File.directory?(contact.dirname)
|
19
|
+
populate_contact(contact)
|
20
|
+
@contact_cache << contact
|
21
|
+
else
|
22
|
+
contact = nil
|
23
|
+
end
|
24
|
+
end
|
25
|
+
contact
|
26
|
+
end
|
27
|
+
|
28
|
+
def populate_contact(contact)
|
29
|
+
Dir.chdir(contact.dirname) do
|
30
|
+
contact.open
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def <<(contact)
|
35
|
+
Dir.chdir(@dir) do
|
36
|
+
Dir.mkdir(contact.dirname) unless File.exists?(contact.dirname)
|
37
|
+
populate_contact(contact)
|
38
|
+
end
|
39
|
+
@contact_cache << contact
|
40
|
+
end
|
41
|
+
|
42
|
+
def delete(name)
|
43
|
+
contact = self[name]
|
44
|
+
return false unless contact
|
45
|
+
contact.close
|
46
|
+
Dir.chdir(@dir) do
|
47
|
+
FileUtils.rm_rf(contact.dirname)
|
48
|
+
end
|
49
|
+
contact_cache.delete_if {|c| c.name == name }
|
50
|
+
true
|
51
|
+
end
|
52
|
+
|
53
|
+
def directory_names
|
54
|
+
Dir["#{@dir}/*"]
|
55
|
+
end
|
56
|
+
|
57
|
+
def size
|
58
|
+
directory_names.size
|
59
|
+
end
|
60
|
+
|
61
|
+
def empty?
|
62
|
+
directory_names.empty?
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
|
68
|
+
class Contact
|
69
|
+
|
70
|
+
COMPONENTS = ["home", "extras", "work"]
|
71
|
+
|
72
|
+
attr_accessor :name, *COMPONENTS
|
73
|
+
|
74
|
+
attr_reader :dirname
|
75
|
+
|
76
|
+
def initialize(name)
|
77
|
+
@name = name
|
78
|
+
@dirname = @name.gsub(" ", "_")
|
79
|
+
end
|
80
|
+
|
81
|
+
def components
|
82
|
+
COMPONENTS.map {|comp_name| self.send(comp_name) }
|
83
|
+
end
|
84
|
+
|
85
|
+
def open
|
86
|
+
COMPONENTS.each do |component|
|
87
|
+
self.send(component + "=", GDBM.new(component))
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def close
|
92
|
+
components.each do |component|
|
93
|
+
component.close unless component.closed?
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def email
|
98
|
+
extras["email"]
|
99
|
+
end
|
100
|
+
|
101
|
+
def email=(e)
|
102
|
+
extras["email"] = e
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'contacts_g'
|
3
|
+
|
4
|
+
Dir.mkdir("gdbm_contacts") unless File.exist?("gdbm_contacts")
|
5
|
+
|
6
|
+
class GDBMTest < Test::Unit::TestCase
|
7
|
+
|
8
|
+
def setup
|
9
|
+
@list = ContactList.new("gdbm_contacts")
|
10
|
+
@contact = Contact.new("Joe Smith")
|
11
|
+
|
12
|
+
@list << @contact
|
13
|
+
|
14
|
+
@contact.home["street1"] = "123 Main Street"
|
15
|
+
@contact.home["city"] = "Somewhere"
|
16
|
+
@contact.work["phone"] = "(000) 123-4567"
|
17
|
+
@contact.extras["instrument"] = "Cello"
|
18
|
+
@contact.email = "joe@somewhere.abc"
|
19
|
+
end
|
20
|
+
|
21
|
+
def teardown
|
22
|
+
@list.delete("Joe Smith") if @list["Joe Smith"]
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_retrieving_a_contact_from_list
|
26
|
+
contact = @list["Joe Smith"]
|
27
|
+
assert_equal("Joe Smith", contact.name)
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_delete_a_contact_from_list
|
31
|
+
assert(!@list.empty?)
|
32
|
+
@list.delete("Joe Smith")
|
33
|
+
assert(@list.empty?)
|
34
|
+
assert(@list.contact_cache.empty?)
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_home
|
38
|
+
contact = @list["Joe Smith"]
|
39
|
+
assert_equal("123 Main Street", contact.home["street1"])
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_email
|
43
|
+
contact = @list["Joe Smith"]
|
44
|
+
assert_equal("joe@somewhere.abc", contact.email)
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_non_existent_contact_is_nil
|
48
|
+
assert_equal(nil, @list["Some Person"])
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require "yaml"
|
2
|
+
|
3
|
+
class ContactList
|
4
|
+
attr_accessor :contacts
|
5
|
+
|
6
|
+
def initialize(file)
|
7
|
+
@file = file
|
8
|
+
@contacts = []
|
9
|
+
end
|
10
|
+
|
11
|
+
def <<(contact)
|
12
|
+
@contacts << contact
|
13
|
+
end
|
14
|
+
|
15
|
+
def delete(name)
|
16
|
+
@contacts.delete_if {|c| c.name == name }
|
17
|
+
end
|
18
|
+
|
19
|
+
def empty?
|
20
|
+
@contacts.empty?
|
21
|
+
end
|
22
|
+
|
23
|
+
def size
|
24
|
+
@contacts.size
|
25
|
+
end
|
26
|
+
|
27
|
+
def [](name)
|
28
|
+
@contacts.find {|c| c.name == name }
|
29
|
+
end
|
30
|
+
|
31
|
+
def save
|
32
|
+
File.open(@file, "w") do |fh|
|
33
|
+
fh.puts(@contacts.to_yaml)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.load(file)
|
38
|
+
list = new(file)
|
39
|
+
list.contacts = YAML.load(File.read(file))
|
40
|
+
list
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
class Contact
|
47
|
+
attr_reader :name, :email, :home, :work, :extras
|
48
|
+
attr_writer :name, :email
|
49
|
+
|
50
|
+
def initialize(name)
|
51
|
+
@name = name
|
52
|
+
@home = {}
|
53
|
+
@work = {}
|
54
|
+
@extras = {}
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require "test/unit"
|
2
|
+
require "contacts_y"
|
3
|
+
|
4
|
+
class TestContacts < Test::Unit::TestCase
|
5
|
+
|
6
|
+
def setup
|
7
|
+
@filename = "contacts.yaml"
|
8
|
+
@list = ContactList.new(@filename)
|
9
|
+
@contact = Contact.new("Joe Smith")
|
10
|
+
|
11
|
+
@contact.email = "joe@somewhere.abc"
|
12
|
+
@contact.home[:street1] = "123 Main Street"
|
13
|
+
@contact.home[:city] = "Somewhere"
|
14
|
+
@contact.work[:phone] = "(000) 123-4567"
|
15
|
+
@contact.extras[:instrument] = "Cello"
|
16
|
+
|
17
|
+
@list << @contact
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_retrieve_contact_from_list
|
21
|
+
contact = @list["Joe Smith"]
|
22
|
+
assert_equal("Joe Smith", contact.name)
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_delete_contact_from_list
|
26
|
+
assert(!@list.empty?)
|
27
|
+
@list.delete(@contact.name)
|
28
|
+
assert(@list.empty?)
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_save_and_load_list
|
32
|
+
@list.save
|
33
|
+
relist = ContactList.load(@filename)
|
34
|
+
assert_equal(1, relist.size)
|
35
|
+
contact = relist["Joe Smith"]
|
36
|
+
assert_equal("Joe Smith", contact.name)
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'gdbm'
|
2
|
+
|
3
|
+
movies = GDBM.new("movies.db")
|
4
|
+
|
5
|
+
movies.update(
|
6
|
+
{ "Vertigo" => "Alfred Hitchcock",
|
7
|
+
"In a Lonely Place" => "Nicholas Ray",
|
8
|
+
"Johnny Guitar" => "Nicholas Ray",
|
9
|
+
"Touch of Evil" => "Orson Welles",
|
10
|
+
"Psycho" => "Alfred Hitchcock",
|
11
|
+
})
|
12
|
+
|
13
|
+
movies.close
|
14
|
+
|
15
|
+
__END__
|
16
|
+
|
17
|
+
# irb session
|
18
|
+
|
19
|
+
require "gdbm"
|
20
|
+
|
21
|
+
movies = GDBM.new("movies.db")
|
22
|
+
movies.values.uniq
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|