Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ require 'rake/rdoctask'
require 'rake/gempackagetask'
require 'rubygems/specification'
require 'date'
require 'rspec/core/rake_task'

require File.dirname(__FILE__) + '/lib/tiny_ds/version'

Expand Down Expand Up @@ -43,3 +44,4 @@ Rake::RDocTask.new do |rd|
rd.rdoc_files.include("README.rdoc", "lib/**/*.rb")
end

RSpec::Core::RakeTask.new(:spec)
76 changes: 71 additions & 5 deletions lib/tiny_ds/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,28 @@ module TinyDS
class Base
class << self; attr_accessor :_property_definitions; end
RESERVED_PROPERTY_NAME = [:id, :name, :key, :entity, :parent_key, :parent]
VALID_PROPERTY_TYPE = [:string, :integer, :float, :boolean, :text, :time, :list]
VALID_PROPERTY_TYPE = [:string, :integer, :float, :boolean, :text, :time, :list, :type, :user, :key]
def self.property(pname, ptype, opts={})
pname = pname.to_sym
if RESERVED_PROPERTY_NAME.include?(pname)
raise "property name '#{pname}' is reserved."
end
property_definitions[pname] = PropertyDefinition.new(pname, ptype, opts)
(self._property_definitions||={})[pname] = PropertyDefinition.new(pname, ptype, opts)
define_method "#{pname}" do
get_property(pname)
end
define_method "#{pname}=" do |value|
set_property(pname, value)
end
end

def self.property_definitions
self._property_definitions ||= {}
if superclass != Base
defs = superclass.property_definitions
else
defs = {}
end
defs.merge(self._property_definitions ||= {})
end

def self.property_definition(name)
Expand Down Expand Up @@ -46,9 +57,22 @@ def self.default_attrs
attrs
end

def self.sti_property_definition
name, sti_def = property_definitions.detect {|pname, pdef| pdef.ptype == :type}
sti_def
end
def self.sti?
!!sti_property_definition
end


# kind-string of entity
def self.kind
name
if superclass != Base && superclass.sti?
superclass.kind
else
name
end
end

#include ActiveModel::Naming
Expand Down Expand Up @@ -129,14 +153,32 @@ def initialize(attrs={}, opts={})
end

def self.new_from_entity(_entity)
new(nil, :entity=>_entity)
clazz = self
if sti_def = self.sti_property_definition
if type_name = _entity[sti_def.pname]
clazz = constantize(type_name)
end
end
clazz.new(nil, :entity=>_entity)
end
attr_reader :entity

def new_record?
@new_record
end

def persisted?
!new_record?
end

def to_param
self.key.to_s if persisted?
end

def to_key
[self.key] if persisted?
end

# foo.save
def save
do_save
Expand All @@ -148,6 +190,7 @@ def do_save
# raise "entity is readonly."
logger.warn "entity is readonly. key=[#{self.key.inspect}]"
end
__before_save_set_type
__before_save_set_timestamps
# if @new_record && @entity.key && parent
# TinyDS.tx{
Expand All @@ -164,6 +207,11 @@ def do_save
end
# class KeyIsAlreadyTaken < StandardError
# end
def __before_save_set_type
if type_prop = self.class.sti_property_definition
self.set_property(type_prop.pname, self.class.name)
end
end

def __before_save_set_timestamps
if self.class.has_property?(:created_at) && new_record?
Expand Down Expand Up @@ -336,6 +384,23 @@ def get_property(k)
v
end

def ==(other)
return true if equal?(other)
return false unless other.kind_of?(Base)
return key == other.key
end

def eql?(other)
return true if equal?(other)
return false unless other.kind_of?(Base)
return key.eql? other.key
end

def hash
key.hash
end

=begin
def method_missing(m, *args)
k, is_set = if m.to_s =~ /(.+)=$/
[$1.to_sym, true]
Expand All @@ -355,6 +420,7 @@ def method_missing(m, *args)
super(m, *args)
end
end
=end

def logger
self.class.logger
Expand Down
1 change: 1 addition & 0 deletions lib/tiny_ds/base_tx.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
require 'yaml'
module TinyDS
class BaseTx
class SrcJournal < ::TinyDS::Base
Expand Down
22 changes: 20 additions & 2 deletions lib/tiny_ds/property_definition.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
module TinyDS
class PropertyDefinition
attr_reader :ptype, :pname
def initialize(pname, ptype, opts)
@pname = pname
@ptype = ptype
Expand All @@ -26,7 +27,7 @@ def index?

def to_ds_value(v)
case @ptype
when :string
when :string, :type
v.nil? ? nil : v.to_s
when :integer
v.nil? ? nil : v.to_i
Expand All @@ -41,6 +42,21 @@ def to_ds_value(v)
# ![nil, false].include?(v)
when :text
v.nil? ? nil : com.google.appengine.api.datastore::Text.new(v.to_s)
when :key
v.nil? ? nil : TinyDS::Base.to_key(v)
when :user
case v
when NilClass, com.google.appengine.api.users::User
v
when String
if defined?(AppEngine::Users::User)
AppEngine::Users::User.new(v)
else
com.google.appengine.api.users::User.new(v, 'gmail.com')
end
else
raise "not User or String value"
end
when :time
case v
when Time
Expand All @@ -65,14 +81,16 @@ def to_ds_value(v)
end
def to_ruby_value(ds_v)
case @ptype
when :string
when :string, :type
ds_v.nil? ? nil : ds_v.to_s
when :integer
ds_v.nil? ? nil : ds_v.to_i
when :float
ds_v.nil? ? nil : ds_v.to_f
when :boolean
ds_v
when :user, :key
ds_v
when :text
ds_v.nil? ? nil : ds_v.to_s
when :time
Expand Down
39 changes: 39 additions & 0 deletions spec/am_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
require File.dirname(__FILE__) + '/spec_helper'

require 'active_model'

class ActiveComment < TinyDS::Base
include ActiveModel::Validations
property :num, :integer
property :title, :string
property :body, :text
property :flag, :integer, :default=>5
property :new_at, :time, :default=>proc{ Time.now }
property :rate, :float
property :updated_at, :time
property :created_at, :time
property :view_at, :time
end


describe ActiveComment do
before :each do
AppEngine::Testing.install_test_datastore
end
after :all do
AppEngine::Testing.teardown
end
it_should_behave_like "ActiveModel"

it "should return string key for to_param" do
c1 = ActiveComment.create({},{:id => 4})
c1.to_param.should == c1.to_key.to_s
c1.to_param.should == 'agR0ZXN0chMLEg1BY3RpdmVDb21tZW50GAQM'
end

it "should key array for to_key" do
c1 = ActiveComment.create({},{:id => 4})
c1.to_key.should == [c1.key]
end

end
Loading