marley 0.7.2 → 0.8.0

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.
@@ -4,7 +4,7 @@ module Marley
4
4
  def initialize(model)
5
5
  @model=model
6
6
  if $request[:path][1].to_s.match(/^\d+$/) #references a specific instance by ID
7
- @instance=@model[$request[:path][1].to_i]
7
+ @instance=@model.list_dataset(:"#{@model.table_name}__id" => $request[:path][1].to_i).all[0]
8
8
  raise RoutingError unless @instance
9
9
  @method_name=$request[:path][2].sub(/[\?\&\+]$/,'') rescue nil #ditch trailing characters, if any
10
10
  if @method_name
@@ -1,38 +1,48 @@
1
-
2
1
  module Marley
3
2
  module Plugins
4
3
  class MessageThreading < Plugin
4
+ def apply(*klasses)
5
+ super
6
+ klasses.flatten.each do |klass|
7
+ Marley.plugin('orm_materialized_path').apply(klass)
8
+ end
9
+ end
5
10
  module ClassMethods
6
11
  def topics(params=nil)
7
12
  filters=[]
8
13
  if params && params[:tags]
9
14
  filters << {:id => MR::Tag.join(:messages_tags, :tag_id => :id).select(:message_id).filter(:tag => params[:tags])}
10
15
  end
11
- filters.inject(self.dataset.filter(:parent_id => nil)) {|ds,f| ds.filter(f)}
16
+ filters.inject(self.roots) {|ds,f| ds.filter(f)}
17
+ end
18
+ def list(params={})
19
+ reggae_instance_list(params)
12
20
  end
13
- def list(params=nil)
14
- (params.is_a?(Sequel::Dataset) ? params : topics(params)).eager(associations).all.map{|t| t.thread}
21
+ def reggae_instance_list(params={})
22
+ t=topics(params).all
23
+ if t.length==0
24
+ Marley::ReggaeMsg.new(:title => 'Nothing Found')
25
+ else
26
+ Marley::ReggaeInstanceList.new(
27
+ :name => resource_name,
28
+ :schema => t[0].reggae_schema(true) << [:resource,resource_name,RESTRICT_RO],
29
+ :items => t.map{|t| t.thread_vals}
30
+ )
31
+ end
15
32
  end
16
33
  end
17
34
  module InstanceMethods
35
+ def thread_vals;values_tree;end
36
+ def thread; tree;end
18
37
  def write_cols
19
- super.push(:topic_id, :parent_id)
20
- end
21
- def children
22
- self.class.filter(:parent_id => id).eager(associations)
23
- end
24
- def thread
25
- return reggae_instance if children.all.length==0
26
- foo=reggae_instance
27
- foo[2] = children.all.map{|m| m.thread}
28
- foo
38
+ new? ? super.push(:topic_id, :path) : super
29
39
  end
30
40
  def before_save
31
41
  super
32
42
  self.topic_id||=self.class.max(:topic_id).to_i+1
33
43
  end
34
44
  def reply
35
- self.class.new(self.values.dup.delete_if{|k,v| k==:id}.merge({:parent_id => self[:id],:title => "re: #{title}"}))
45
+ new_child(:title => "re: #{title}")
36
46
  end
37
47
  end
38
48
  end
@@ -43,11 +53,11 @@ module Marley
43
53
  self.reggae_link(:new, 'New Post'),
44
54
  self.reggae_link(:list, 'All Posts'),
45
55
  self.reggae_link(:recent_topics, 'Recent Topics'),
46
- Marley::ReggaeSection.new({:title => 'Topics Tagged With:', :navigation => MR::Tag.filter(:id => topics.join(:messages_tags).where(:messages__id => :message_id).select(:tag_id)).map{|t| reggae_link('list',t.tag,"#{resource_name}[tags]=#{t.tag}")}})
56
+ Marley::ReggaeSection.new({:title => 'Public Tags', :navigation => MR::PublicTag.filter(:id => topics.all.map{|t|}).map{|t| reggae_link('list',t.tag,"#{resource_name}[_public_tags]=#{t.tag}")}})
47
57
  ]
48
58
  end
49
59
  def recent_topics
50
- list(:date_created > Date.today - 2)
60
+ list(lambda {date_created > Date.today - 2})
51
61
  end
52
62
  end
53
63
  end
@@ -35,7 +35,7 @@ module Marley
35
35
  [:recipients] + super
36
36
  end
37
37
  Marley::Utils.many_to_many_join(self, MR::User)
38
- def self.list_dataset
38
+ def self.list_dataset(params={})
39
39
  super.filter(:messages__id => DB[:messages_users].filter(:user_id => current_user[:id]).select(:message_id))
40
40
  end
41
41
  def current_user_role
@@ -5,7 +5,9 @@ module Marley
5
5
  def apply(*klasses)
6
6
  klasses.each do |klass|
7
7
  klass=MR.const_get(klass) if klass.is_a?(String)
8
+
8
9
  klass.derived_after_cols![:new?][:all] << @tag_col_name.to_sym
10
+ klass.extend @class_methods_mod
9
11
  @instance_methods_mod.send(:append_features,klass)
10
12
  Marley::Utils.many_to_many_join(klass, @tag_class)
11
13
  end
@@ -16,33 +18,29 @@ module Marley
16
18
  tag_col_name=@tag_col_name="_#{@tag_type}_tags"
17
19
  tag_class=@tag_class=MR.const_get(@tag_col_name.sub(/^_/,'').singularize.camelcase)
18
20
  tags_ds_name=@tags_ds_name="#{tag_col_name.sub(/^_/,'')}_dataset"
21
+ tags_meth=tag_class.resource_name.pluralize.to_sym
22
+ @class_methods_mod=Module.new do |m|
23
+ define_method(:list_dataset) {|*args|
24
+ super.eager_graph({tags_meth => proc{|ds| ds.filter(:tags__user_id => tag_class.associations.include?(:user) ? current_user[:id] : nil)}})
25
+ }
26
+ end
19
27
  @instance_methods_mod=Module.new do |m|
20
- attr_accessor tag_col_name
28
+ attr_writer tag_col_name
21
29
  define_method(:write_cols) {
22
30
  super << tag_col_name.to_sym
23
31
  }
24
-
25
- #list dataset should take care of most of this
26
-
27
- define_method("#{tag_col_name}_ds".to_sym) { #e.g. _private_tags_ds
28
- send(tags_ds_name).filter({:tags__user_id => (tag_class.associations.include?(:user) ? self.class.current_user[:id] : nil)})
29
- }
30
32
  define_method(tag_col_name.to_sym) { #e.g. _private_tags
31
- send("#{tag_col_name}_ds").map {|t| t.tag}.join(', ') unless new?
32
- }
33
- define_method("add#{tag_col_name}".to_sym) {|tags| #e.g. add_private_tags
34
- vals_hash={:user_id => (tag_class.associations.include?(:user) ? self.class.current_user[:id] : nil)}
35
- tags.to_s.split(',').each {|tag| self.send("add#{tag_col_name.singularize}",tag_class.find_or_create(vals_hash.update(:tag => tag))) }
33
+ send(tags_meth).map {|t| t.tag}.join(', ') unless new?
36
34
  }
37
35
  define_method("replace#{tag_col_name}".to_sym) { #e.g. replace_private_tags
38
- send("#{tag_col_name}_ds").each {|tag| send("remove#{tag_col_name}".singularize,tag)}
36
+ send(tags_meth).each {|tag| send("remove#{tag_col_name}".singularize,tag)}
39
37
  send("add#{tag_col_name}",instance_variable_get("@#{tag_col_name}"))
40
38
  }
41
39
  define_method(:after_save) {
42
40
  super
43
- methods.select {|m| m.match(/^replace_.+_tags/)}.each do |replace_method|
44
- send(replace_method)
45
- end
41
+ send("#{tags_meth}_dataset").filter({:tags__user_id => (tag_class.associations.include?(:user) ? self.class.current_user[:id] : nil)}).each {|tag| send("remove#{tag_col_name}".singularize,tag)}
42
+ vals_hash={:user_id => (tag_class.associations.include?(:user) ? self.class.current_user[:id] : nil)}
43
+ instance_variable_get("@#{tag_col_name}").to_s.split(/\s*,\s*/).each {|tag| self.send("add#{tag_col_name.singularize}",tag_class.find_or_create(vals_hash.update(:tag => tag))) }
46
44
  }
47
45
  end
48
46
  end
@@ -53,7 +51,7 @@ module Marley
53
51
  module Resources
54
52
  class Tag < Sequel::Model
55
53
  sti
56
- def self.list_dataset
54
+ def self.list_dataset(params={})
57
55
  dataset.order(:tag)
58
56
  end
59
57
  def validate
@@ -74,7 +72,7 @@ module Marley
74
72
  end
75
73
  class PrivateTag < Tag
76
74
  MR::User.join_to(self) if MR::User
77
- def self.list_dataset
75
+ def self.list_dataset(params={})
78
76
  current_user_ds.order(:tag)
79
77
  end
80
78
  end
@@ -0,0 +1,49 @@
1
+ module Marley
2
+ module Plugins
3
+ class OrmMaterializedPath < Plugin
4
+ @default_opts={:path_col => :path, :path_separator => '-'}
5
+ def apply(klasses)
6
+ super
7
+ end
8
+ def initialize(opts={})
9
+ super
10
+ [ClassMethods,InstanceMethods].each do |mod|
11
+ mod.const_set(:PATH_COL,@opts[:path_col])
12
+ mod.const_set(:SEP,@opts[:path_separator])
13
+ end
14
+ end
15
+ module ClassMethods
16
+ def roots(params={})
17
+ list_dataset.filter({PATH_COL => nil}.update(params))
18
+ end
19
+ def path_col_num
20
+ columns.index(PATH_COL)
21
+ end
22
+ end
23
+ module InstanceMethods
24
+ def tree_ds; self.class.list_dataset.filter(PATH_COL.like("#{children_path}%")); end
25
+ def _path;send(PATH_COL);end
26
+ def path_arr; _path.to_s.split(SEP).map &:to_i; end
27
+ def root_id; path_arr[0]; end
28
+ def parent_id; path_arr[-1]; end
29
+ def children_path;("#{_path}#{id}#{SEP}");end
30
+ def children_path_arr; children_path.split(SEP).map &:to_i; end
31
+ def new_child(vals={}); self.class.new({PATH_COL => children_path}.update(vals)); end
32
+ def depth; path_arr.length; end
33
+
34
+ def tree
35
+ res=block_given? ? (yield self) : [self,[]]
36
+ tree_ds.all.sort {|x,y| x.children_path_arr <=> y.children_path_arr}.each do |node|
37
+ node.path_arr.inject(res) {|arr,i| arr[-1]} << (block_given? ? (yield node) : [node,[]])
38
+ end
39
+ res
40
+ end
41
+ def values_tree
42
+ tree do |n|
43
+ foo=n.rest_cols.map{|c| n.send(c)} << []
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -9,13 +9,14 @@ module Marley
9
9
  @default_opts={
10
10
  :required_plugins => [:rest_convenience],
11
11
  :class_attrs =>[ [:model_actions,{:get => [:new, :list]}] ],
12
- :lazy_class_attrs => [ :new?,[:instance_actions,{:all => nil}],
13
- [:derived_before_cols,{:all => []}],
14
- [:derived_after_cols,{:all => []}],
15
- [:reject_cols,{true => [/^id$/,/_type$/,/date_(created|updated)/], false => [/_type$/]}],
16
- [:ro_cols,{true => [/^id$/,/_id$/], false => [/^id$/,/_id$/,/date_(created|updated)/]}],
17
- [:hidden_cols,{:all => [/_id$/]}],
18
- [:required_cols,{:all => []}] ]
12
+ :lazy_class_attrs => [ :new?,
13
+ [:instance_actions,{:all => nil}],
14
+ [:derived_before_cols,{:all => []}],
15
+ [:derived_after_cols,{:all => []}],
16
+ [:reject_cols,{true => [/^id$/,/_type$/,/date_(created|updated)/], false => [/_type$/]}],
17
+ [:ro_cols,{true => [/^id$/,/_id$/], false => [/^id$/,/_id$/,/date_(created|updated)/]}],
18
+ [:hidden_cols,{:all => [/_id$/]}],
19
+ [:required_cols,{:all => []}] ]
19
20
  }
20
21
  module ClassMethods
21
22
  def controller; Marley::ModelController.new(self); end
@@ -25,11 +26,24 @@ module Marley
25
26
 
26
27
  def foreign_key_name; :"#{(respond_to?(:table_name) ? table_name : resource_name).to_s.singularize}_id"; end
27
28
 
28
- def list_dataset
29
- dataset
29
+ def list_dataset(params={})
30
+ dataset.filter(params)
30
31
  end
31
32
  def list(params={})
32
- list_dataset.filter(params).all
33
+ list_dataset(params).all
34
+ end
35
+ def reggae_instance_list(params={})
36
+ items=list(params)
37
+ if items.length==0
38
+ Marley::ReggaeMessage.new(:title => 'Nothing Found')
39
+ else
40
+ cols=items[0].rest_cols
41
+ Marley::ReggaeInstanceList.new(
42
+ :name => resource_name,
43
+ :schema => items[0].reggae_schema(true),
44
+ :items => items.map{|i| cols.map{|c|i.send(c)}}
45
+ )
46
+ end
33
47
  end
34
48
  def sti
35
49
  plugin :single_table_inheritance, :"#{self.to_s.sub(/.*::/,'').underscore}_type", :model_map => lambda{|v| MR.const_get(v.to_sym)}, :key_map => lambda{|klass|klass.name.sub(/.*::/,'')}
@@ -50,17 +64,23 @@ module Marley
50
64
 
51
65
  def rest_associations;[];end
52
66
 
53
- def reggae_schema
67
+ def reggae_schema(list_schema=false)
54
68
  Marley::ReggaeSchema.new(
55
69
  rest_cols.map do |col_name|
56
70
  db_spec=db_schema.to_hash[col_name]
57
71
  col_type=db_spec ? db_spec[:db_type].downcase : "text"
58
72
  col_type=:password if col_name.to_s.match(/password/)
59
- restrictions=0
60
- restrictions|=RESTRICT_HIDE if hidden_cols.include?(col_name)
61
- restrictions|=RESTRICT_RO unless write_cols.include?(col_name)
62
- restrictions|=RESTRICT_REQ if required_cols.include?(col_name) || (db_spec && !db_spec[:allow_null])
63
- [col_type, col_name, restrictions,send(col_name)]
73
+ if list_schema
74
+ restrictions=RESTRICT_RO
75
+ restrictions|=RESTRICT_HIDE if hidden_cols.include?(col_name)
76
+ [col_type, col_name, restrictions]
77
+ else
78
+ restrictions=0
79
+ restrictions|=RESTRICT_HIDE if hidden_cols.include?(col_name)
80
+ restrictions|=RESTRICT_RO unless write_cols.include?(col_name)
81
+ restrictions|=RESTRICT_REQ if required_cols.include?(col_name) || (db_spec && !db_spec[:allow_null])
82
+ [col_type, col_name, restrictions,send(col_name)]
83
+ end
64
84
  end
65
85
  )
66
86
  end
@@ -107,8 +107,7 @@ module Marley
107
107
  end
108
108
  end
109
109
  class ReggaeInstanceList < ReggaeResource
110
- properties :name,:description,:actions,:items
111
- #not implemented yet
110
+ properties :name,:description,:actions,:group_actions,:items
112
111
  end
113
112
  class ReggaeMsg < ReggaeResource
114
113
  properties :title,:description
@@ -56,10 +56,10 @@ module Marley
56
56
  def self.sti(klass)
57
57
  klass.plugin :single_table_inheritance, :"#{klass.to_s.sub(/.*::/,'').underscore}_type", :model_map => lambda{|v| MR.const_get(v.to_sym)}, :key_map => lambda{|clss|clss.name.sub(/.*::/,'')}
58
58
  end
59
- def self.many_to_many_join(lclass, rclass)
59
+ def self.many_to_many_join(lclass, rclass,lopts={},ropts={})
60
60
  join_table=[lclass.table_name.to_s,rclass.table_name.to_s ].sort.join('_').to_sym
61
- lclass.many_to_many(rclass.resource_name.pluralize.to_sym,:join_table => join_table,:class =>rclass, :left_key => lclass.foreign_key_name, :right_key => rclass.foreign_key_name)
62
- rclass.many_to_many(lclass.resource_name.pluralize.to_sym,:join_table => join_table, :class =>lclass,:left_key => rclass.foreign_key_name, :right_key => lclass.foreign_key_name)
61
+ lclass.many_to_many(rclass.resource_name.pluralize.to_sym,{:join_table => join_table,:class =>rclass, :left_key => lclass.foreign_key_name, :right_key => rclass.foreign_key_name}).update(lopts)
62
+ rclass.many_to_many(lclass.resource_name.pluralize.to_sym,{:join_table => join_table, :class =>lclass,:left_key => rclass.foreign_key_name, :right_key => lclass.foreign_key_name}.update(ropts))
63
63
  end
64
64
  def self.hash_keys_to_syms(hsh)
65
65
  hsh.inject({}) {|h,(k,v)| h[k.to_sym]= v.class==Hash ? hash_keys_to_syms(v) : v;h }
@@ -14,7 +14,7 @@ end
14
14
  DB.create_table :messages do
15
15
  primary_key :id
16
16
  integer :topic_id, :index => true
17
- integer :parent_id, :index => true
17
+ text :path, :index => true
18
18
  integer :user_id, :index => true
19
19
  datetime :date_created, :index => true
20
20
  text :message_type, :index => true
@@ -31,6 +31,7 @@ end
31
31
  DB.create_table :tags do
32
32
  primary_key :id
33
33
  integer :user_id,:index => true
34
+ text :tag_type, :index => true
34
35
  text :tag,:index => true
35
36
  end
36
37
  DB.create_table :messages_tags do
@@ -27,7 +27,7 @@ FactoryGirl.define do
27
27
  _public_tags ''
28
28
  _private_tags ''
29
29
  end
30
- factory :private_message,:class => MR::PublicMessage do |n|
30
+ factory :private_message,:class => MR::PrivateMessage do |n|
31
31
  user
32
32
  recipients ''
33
33
  title
@@ -46,8 +46,15 @@ USERS.times do
46
46
  FactoryGirl.create(:user) do |u|
47
47
  $request={:user => u}
48
48
  TOPICS.times do
49
- FactoryGirl.create(:post,:user_id => u[:id])
49
+ FactoryGirl.create(:post,:user_id => u[:id],:_public_tags => (1 .. TAGS).to_a.map{|i| "tag#{i}"}.join(','))
50
50
  end
51
51
  end
52
52
  end
53
+ REPLIES.each do |r|
54
+ MR::PublicMessage.all.each do |m|
55
+ rep=m.reply
56
+ rep.user_id=m[:id].modulo USERS
57
+ rep.save
58
+ end
59
+ end
53
60
 
@@ -0,0 +1,21 @@
1
+
2
+ require 'marley'
3
+ require 'marley/test_helpers'
4
+
5
+ DB=Sequel.sqlite('')
6
+ DB.create_table :trees do
7
+ primary_key :id
8
+ text :name, :index => true
9
+ text :path, :index => true
10
+ end
11
+
12
+ Marley.plugin('orm_rest_convenience').apply(Sequel::Model)
13
+ Marley.config {}
14
+ module Marley
15
+ module Resources
16
+ class Tree < Sequel::Model
17
+ Marley.plugin('orm_materialized_path').apply(self)
18
+ end
19
+ end
20
+ end
21
+
@@ -0,0 +1,48 @@
1
+
2
+
3
+ examples:
4
+
5
+ >> MR::Tree.new(:name => 'asdf').save.reggae_instance
6
+ => [:instance, {:schema=> [[:integer, :id, 2, 1], [:text, :name, 0, "asdf"], [:text, :path, 0, nil]], :url=>"/tree/1", :new_rec=>false, :name=>"tree", :actions=>nil}, []]
7
+ >> MR::Tree[1].new_child.reggae_instance
8
+ => [:instance, {:schema=>[[:text, :name, 0, nil], [:text, :path, 0, "1-"]], :url=>"/tree/", :new_rec=>true, :name=>"tree", :actions=>nil}, nil]
9
+ >> MR::Tree[1].new_child.save.reggae_instance
10
+ => [:instance, {:schema=> [[:integer, :id, 2, 2], [:text, :name, 0, nil], [:text, :path, 0, "1-"]], :url=>"/tree/2", :new_rec=>false, :name=>"tree", :actions=>nil}, []]
11
+ >> MR::Tree[1].new_child.save.reggae_instance
12
+ => [:instance, {:schema=> [[:integer, :id, 2, 3], [:text, :name, 0, nil], [:text, :path, 0, "1-"]], :url=>"/tree/3", :new_rec=>false, :name=>"tree", :actions=>nil}, []]
13
+ >> MR::Tree[1].new_child.save.reggae_instance
14
+ => [:instance, {:schema=> [[:integer, :id, 2, 4], [:text, :name, 0, nil], [:text, :path, 0, "1-"]], :url=>"/tree/4", :new_rec=>false, :name=>"tree", :actions=>nil}, []]
15
+ >> MR::Tree[2].new_child.save.reggae_instance
16
+ => [:instance, {:schema=> [[:integer, :id, 2, 5], [:text, :name, 0, nil], [:text, :path, 0, "1-2-"]], :url=>"/tree/5", :new_rec=>false, :name=>"tree", :actions=>nil}, []]
17
+ >> MR::Tree[5].new_child.save.reggae_instance
18
+ => [:instance, {:schema=> [[:integer, :id, 2, 6], [:text, :name, 0, nil], [:text, :path, 0, "1-2-5-"]], :url=>"/tree/6", :new_rec=>false, :name=>"tree", :actions=>nil}, []]
19
+ >> MR::Tree[3].new_child.save.reggae_instance
20
+ => [:instance, {:schema=> [[:integer, :id, 2, 7], [:text, :name, 0, nil], [:text, :path, 0, "1-3-"]], :url=>"/tree/7", :new_rec=>false, :name=>"tree", :actions=>nil}, []]
21
+
22
+ >> MR::Tree[3].new_child.save.reggae_instance
23
+ => [:instance, {:schema=> [[:integer, :id, 2, 8], [:text, :name, 0, nil], [:text, :path, 0, "1-3-"]], :url=>"/tree/8", :new_rec=>false, :name=>"tree", :actions=>nil}, []]
24
+ >> MR::Tree[3].new_child.save.reggae_instance
25
+ => [:instance, {:schema=> [[:integer, :id, 2, 9], [:text, :name, 0, nil], [:text, :path, 0, "1-3-"]], :url=>"/tree/9", :new_rec=>false, :name=>"tree", :actions=>nil}, []]
26
+ >> MR::Tree[3].new_child.save.reggae_instance
27
+ => [:instance, {:schema=> [[:integer, :id, 2, 10], [:text, :name, 0, nil], [:text, :path, 0, "1-3-"]], :url=>"/tree/10", :new_rec=>false, :name=>"tree", :actions=>nil}, []]
28
+
29
+ >> MR::Tree[1].new_child.save.reggae_instance
30
+ => [:instance, {:schema=> [[:integer, :id, 2, 11], [:text, :name, 0, nil], [:text, :path, 0, "1-"]], :url=>"/tree/11", :new_rec=>false, :name=>"tree", :actions=>nil}, []]
31
+ >> MR::Tree[1].new_child.save.reggae_instance
32
+ => [:instance, {:schema=> [[:integer, :id, 2, 12], [:text, :name, 0, nil], [:text, :path, 0, "1-"]], :url=>"/tree/12", :new_rec=>false, :name=>"tree", :actions=>nil}, []]
33
+ >> MR::Tree[2].new_child.save.reggae_instance
34
+ => [:instance, {:schema=> [[:integer, :id, 2, 13], [:text, :name, 0, nil], [:text, :path, 0, "1-2-"]], :url=>"/tree/13", :new_rec=>false, :name=>"tree", :actions=>nil}, []]
35
+ >> MR::Tree[5].new_child.save.reggae_instance
36
+ => [:instance, {:schema=> [[:integer, :id, 2, 14], [:text, :name, 0, nil], [:text, :path, 0, "1-2-5-"]], :url=>"/tree/14", :new_rec=>false, :name=>"tree", :actions=>nil}, []]
37
+ >> MR::Tree[3].new_child.save.reggae_instance
38
+ => [:instance, {:schema=> [[:integer, :id, 2, 15], [:text, :name, 0, nil], [:text, :path, 0, "1-3-"]], :url=>"/tree/15", :new_rec=>false, :name=>"tree", :actions=>nil}, []]
39
+
40
+ >> MR::Tree[7].new_child.save.reggae_instance
41
+ => [:instance, {:schema=> [[:integer, :id, 2, 16], [:text, :name, 0, nil], [:text, :path, 0, "1-3-7-"]], :url=>"/tree/16", :new_rec=>false, :name=>"tree", :actions=>nil}, []]
42
+ >> MR::Tree[13].new_child.save.reggae_instance
43
+ => [:instance, {:schema=> [[:integer, :id, 2, 17], [:text, :name, 0, nil], [:text, :path, 0, "1-2-13-"]], :url=>"/tree/17", :new_rec=>false, :name=>"tree", :actions=>nil}, []]
44
+
45
+ >> MR::Tree[1].values_tree
46
+ => [1, "asdf", nil, [[2, nil, "1-", [], [5, nil, "1-2-", [], [6, nil, "1-2-5-", []], [14, nil, "1-2-5-", []]], [13, nil, "1-2-", [], [17, nil, "1-2-13-", []]]], [3, nil, "1-", [], [7, nil, "1-3-", [], [16, nil, "1-3-7-", []]], [8, nil, "1-3-", []], [9, nil, "1-3-", []], [10, nil, "1-3-", []], [15, nil, "1-3-", []]], [4, nil, "1-", []], [11, nil, "1-", []], [12, nil, "1-", []]]]
47
+
48
+
@@ -29,7 +29,9 @@ example: without the plugin, then with the plugin
29
29
 
30
30
  == Included Plugins
31
31
 
32
- Marley comes with 1 external plugin (there are others in the included Joints, described later):
32
+ Marley comes with 2 plugins (there are others in the included Joints, described later):
33
33
 
34
34
  :include: rdoc/orm_rest_convenience_plugin.rdoc
35
35
 
36
+ :include: rdoc/orm_materialized_path_plugin.rdoc
37
+
@@ -31,7 +31,6 @@ examples: announcements with private and public tags
31
31
  => [[:instance, {:url=>"/announcement/1", :new_rec=>false, :actions=>{:delete=>"/announcement/1"}, :schema=>[[:integer, :id, 2, 1], [:integer, :user_id, 3, 1], [:text, :name, 4, "user1 ann1"], [:text, :message, 0, "user1ann1 msg"], [:text, :_private_tags, 0, "aaa, bbb"], [:text, :_public_tags, 0, "ppp"]], :name=>"announcement"}, []], [:instance, {:url=>"/announcement/2", :new_rec=>false, :actions=>nil, :schema=>[[:integer, :id, 2, 2], [:integer, :user_id, 3, 2], [:text, :name, 6, "user2 ann1"], [:text, :message, 2, "user2ann1 msg"], [:text, :_private_tags, 0, ""], [:text, :_public_tags, 0, "yyy, zzz"]], :name=>"announcement"}, []]]
32
32
  >> @client2.read
33
33
  => [[:instance, {:url=>"/announcement/1", :new_rec=>false, :actions=>nil, :schema=>[[:integer, :id, 2, 1], [:integer, :user_id, 3, 1], [:text, :name, 6, "user1 ann1"], [:text, :message, 2, "user1ann1 msg"], [:text, :_private_tags, 0, ""], [:text, :_public_tags, 0, "ppp"]], :name=>"announcement"}, []], [:instance, {:url=>"/announcement/2", :new_rec=>false, :actions=>{:delete=>"/announcement/2"}, :schema=>[[:integer, :id, 2, 2], [:integer, :user_id, 3, 2], [:text, :name, 4, "user2 ann1"], [:text, :message, 0, "user2ann1 msg"], [:text, :_private_tags, 0, "xxx"], [:text, :_public_tags, 0, "yyy, zzz"]], :name=>"announcement"}, []]]
34
-
35
34
  >> @ann1client1=@client1.read({},:instance_id => 1)
36
35
  => [:instance, {:url=>"/announcement/1", :new_rec=>false, :actions=>{:delete=>"/announcement/1"}, :schema=>[[:integer, :id, 2, 1], [:integer, :user_id, 3, 1], [:text, :name, 4, "user1 ann1"], [:text, :message, 0, "user1ann1 msg"], [:text, :_private_tags, 0, "aaa, bbb"], [:text, :_public_tags, 0, "ppp"]], :name=>"announcement"}, []]
37
36
  :_public_tags, 0, "ppp"]], :name=>"announcement"}, []]
@@ -30,9 +30,9 @@ examples:
30
30
  => [:instance, {:schema=>[[:integer, :id, 2, 1], [:integer, :user_id, 3, 1], [:text, :name, 4, "user1 secret1"], [:text, :message, 0, nil], [:text, :_private_tags, 0, "foo"]], :url=>"/secret/1", :new_rec=>false, :actions=>nil, :name=>"secret"}, []]
31
31
 
32
32
  >> DB[:tags].all
33
- => [{:tag=>"xxxxxx", :id=>1, :tag_type=>"PrivateTag", :user_id=>1}, {:tag=>"sss", :id=>2, :tag_type=>"PrivateTag", :user_id=>1}, {:tag=>"sss", :id=>3, :tag_type=>"PrivateTag", :user_id=>1}, {:tag=>"zzz", :id=>4, :tag_type=>"PrivateTag", :user_id=>1}, {:tag=>"aaa", :id=>5, :tag_type=>"PrivateTag", :user_id=>1}, {:tag=>"foo", :id=>6, :tag_type=>"PrivateTag", :user_id=>1}]
33
+ => [{:tag=>"xxxxxx", :id=>1, :tag_type=>"PrivateTag", :user_id=>1}, {:tag=>"sss", :id=>2, :tag_type=>"PrivateTag", :user_id=>1}, {:tag=>"zzz", :id=>3, :tag_type=>"PrivateTag", :user_id=>1}, {:tag=>"aaa", :id=>4, :tag_type=>"PrivateTag", :user_id=>1}, {:tag=>"foo", :id=>5, :tag_type=>"PrivateTag", :user_id=>1}]
34
34
  >> DB[:messages_tags].all
35
- => [{:tag_id=>6, :message_id=>1, :id=>7}]
35
+ => [{:tag_id=>5, :message_id=>1, :id=>7}]
36
36
 
37
37
 
38
38
 
@@ -58,8 +58,8 @@ examples:
58
58
  => [:instance, {:schema=>[[:integer, :id, 2, 2], [:integer, :user_id, 3, 2], [:text, :name, 4, "user2 secret"], [:text, :message, 0, nil], [:text, :_private_tags, 0, "boo"]], :url=>"/secret/2", :new_rec=>false, :actions=>nil, :name=>"secret"}, []]
59
59
 
60
60
  >> DB[:tags].all
61
- => [{:tag=>"xxxxxx", :id=>1, :tag_type=>"PrivateTag", :user_id=>1}, {:tag=>"sss", :id=>2, :tag_type=>"PrivateTag", :user_id=>1}, {:tag=>"sss", :id=>3, :tag_type=>"PrivateTag", :user_id=>1}, {:tag=>"zzz", :id=>4, :tag_type=>"PrivateTag", :user_id=>1}, {:tag=>"aaa", :id=>5, :tag_type=>"PrivateTag", :user_id=>1}, {:tag=>"foo", :id=>6, :tag_type=>"PrivateTag",:user_id=>1}, {:tag=>"foo", :id=>7, :tag_type=>"PrivateTag", :user_id=>2}, {:tag=>"bar", :id=>8, :tag_type=>"PrivateTag", :user_id=>2}, {:tag=>"bar", :id=>9, :tag_type=>"PrivateTag", :user_id=>2}, {:tag=>"baz", :id=>10, :tag_type=>"PrivateTag", :user_id=>2}, {:tag=>"bat", :id=>11, :tag_type=>"PrivateTag", :user_id=>2}, {:tag=>"boo", :id=>12, :tag_type=>"PrivateTag", :user_id=>2}]
61
+ => [{:tag=>"xxxxxx", :id=>1, :tag_type=>"PrivateTag", :user_id=>1}, {:tag=>"sss", :id=>2, :tag_type=>"PrivateTag", :user_id=>1}, {:tag=>"zzz", :id=>3, :tag_type=>"PrivateTag", :user_id=>1}, {:tag=>"aaa", :id=>4, :tag_type=>"PrivateTag", :user_id=>1}, {:tag=>"foo", :id=>5, :tag_type=>"PrivateTag",:user_id=>1}, {:tag=>"foo", :id=>6, :tag_type=>"PrivateTag", :user_id=>2}, {:tag=>"bar", :id=>7, :tag_type=>"PrivateTag", :user_id=>2}, {:tag=>"baz", :id=>8, :tag_type=>"PrivateTag", :user_id=>2}, {:tag=>"bat", :id=>9, :tag_type=>"PrivateTag", :user_id=>2}, {:tag=>"boo", :id=>10, :tag_type=>"PrivateTag", :user_id=>2}]
62
62
  >> DB[:messages_tags].all
63
- => [{:tag_id=>6, :message_id=>1, :id=>7}, {:tag_id=>12, :message_id=>2, :id=>14}]
63
+ => [{:tag_id=>5, :message_id=>1, :id=>7}, {:tag_id=>10, :message_id=>2, :id=>14}]
64
64
 
65
65
 
@@ -40,7 +40,7 @@ module Marley
40
40
  end
41
41
  class Secret < Message
42
42
  User.join_to(self)
43
- def self.list_dataset
43
+ def self.list_dataset(params={})
44
44
  current_user_ds
45
45
  end
46
46
  end
@@ -63,8 +63,9 @@ example: user1 reading/writing secrets
63
63
  => [[:instance, {:new_rec=>false, :actions=>nil, :schema=>[[:integer, :id, 2, 1], [:integer, :user_id, 3, 1], [:text, :name, 4, "this is my secret"], [:text, :message, 0, nil]], :name=>"secret", :url=>"/secret/1"}, []]]
64
64
  >> @client.read({},:auth => @user2_auth)
65
65
  => []
66
- >> @client.read({},:auth => @user2_auth,:instance_id => 1, :code => 403)
67
- => [:error, {:error_type=>"authorization", :error_details=>nil, :description=>"You are not authorized for this operation"}]
66
+ >> @client.read({},:auth => @user2_auth,:instance_id => 1, :code => 404)
67
+ => [:error, {:error_type=>"routing", :description=>"Not Found", :error_details=>nil}]
68
+
68
69
 
69
70
  example: user2 reading/writing secrets
70
71
  >> @client.auth=@user2_auth
@@ -80,8 +81,8 @@ example: user2 reading/writing secrets
80
81
 
81
82
  >> @client.read({}, :auth => @user1_auth)
82
83
  => []
83
- >> @client.read({}, :auth => @user1_auth, :instance_id => 1,:code => 403)
84
- => [:error, {:error_type=>"authorization", :error_details=>nil, :description=>"You are not authorized for this operation"}]
84
+ >> @client.read({}, :auth => @user1_auth, :instance_id => 1,:code => 404)
85
+ => [:error, {:error_type=>"routing", :description=>"Not Found", :error_details=>nil}]
85
86
 
86
87
  examples: announcements
87
88
  >> @client.auth=@user1_auth
@@ -17,7 +17,7 @@ link_property ::= 'title' | 'description' | 'url'
17
17
 
18
18
  instance_property ::= 'name' | 'url' | 'new_rec' | 'search' | 'schema' | 'actions'
19
19
 
20
- instance_list_property ::='title' | 'description' | 'schema' | 'actions' | 'items'
20
+ instance_list_property ::='title' | 'description' | 'schema' | 'actions' | 'group_actions' | 'items'
21
21
 
22
22
  msg_property ::= 'title' | 'description'
23
23
 
@@ -41,6 +41,8 @@ items_value ::= '[' '[' col_value (',' col_value)* ']' (',' '[' col_value (',' c
41
41
 
42
42
  actions_value ::= '{' '"' ('get' | 'post' | 'put' | 'delete') '"' ':' methods (',' '"' ('get' | 'post' | 'put' | 'delete') '"' ':' methods )* '}'
43
43
 
44
+ group_actions_value ::= actions_value
45
+
44
46
  methods::= '[' ( get_method (',' get_method)* | post_method (',' post_method)* | put_method (',' put_method)* | delete_method (',' delete_method)* ) ']'
45
47
 
46
48
  get_action ::= string_literal
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: marley
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.2
4
+ version: 0.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Herb Daily
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2012-03-24 00:00:00 -03:00
12
+ date: 2012-03-29 00:00:00 -03:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -98,6 +98,7 @@ files:
98
98
  - lib/marley/joint.rb
99
99
  - lib/marley/plugins/orm_rest_convenience.rb
100
100
  - lib/marley/plugins/rest_convenience.rb
101
+ - lib/marley/plugins/orm_materialized_path.rb
101
102
  - lib/marley/controllers.rb
102
103
  - lib/marley/errors.rb
103
104
  - lib/marley/reggae.rb
@@ -109,6 +110,7 @@ files:
109
110
  - rdoc/user_joint/no_auth_provided.rdoc
110
111
  - rdoc/user_joint/exiting_users.rdoc
111
112
  - rdoc/messages_joint.rb
113
+ - rdoc/orm_materialized_path_plugin.rb
112
114
  - rdoc/messages_joint.rdoc
113
115
  - rdoc/hello.rb
114
116
  - rdoc/section_joint.rdoc
@@ -122,6 +124,7 @@ files:
122
124
  - rdoc/orm_rest_convenience_plugin.rdoc
123
125
  - rdoc/reggae/generate.rdoc
124
126
  - rdoc/reggae/parse.rdoc
127
+ - rdoc/orm_materialized_path_plugin.rdoc
125
128
  - rdoc/user_joint.rb
126
129
  - rdoc/joints.rdoc
127
130
  - rdoc/hello.rdoc