Skip to content

Instantly share code, notes, and snippets.

@quinn
Created April 21, 2009 16:24
Show Gist options
  • Save quinn/99223 to your computer and use it in GitHub Desktop.
Save quinn/99223 to your computer and use it in GitHub Desktop.
working on a datamapper wrapper for a drupal database...
module Drupal
module CCK
class Builder
def self.code
types.
map{|t| table = Table.new t}.
select{|t| t.valid?}.
join("\n")
end
def self.types
@types ||= Drupal::Repository.adapter.query('select type from node').uniq
end
def self.fields
@fields ||= Drupal::Repository.adapter.query('show tables').select{|t| t.match(/^content_field/)}
end
end
class Table
attr_accessor :type
def initialize type
self.type = type
end
def table
"content_type_#{type}"
end
def fields
Drupal::CCK::ContentNodeFieldInstance.all :type_name => type
end
def columns
@columns ||= fields
end
def ignore_columns
%w{nid vid}
end
def to_s
"
class #{type.camel_case}
#{Drupal.common}
storage_names[:drupal] = '#{table}'
property :nid, Serial
property :vid, Integer
belongs_to :node,
:child_key => [:nid]
#{columns.map{|c| c.to_s}.join "\n"}
def self.type; :#{type}; end
extend CCK::FieldMethods
end
"
end
def valid?
columns
true
rescue MysqlError
false
end
end
end
def self.generate
Drupal.class_eval do
eval( CCK::Builder.fields.map do |field|
CCK::ThroughField.new field
end.join("\n") )
eval CCK::Builder.code
end
end
end
module Drupal
module CCK
module NodeMethods
def cck_class
@cck_class ||= eval("Drupal::#{type.camel_case}")
end
def cck
@cck ||= cck_class.first(:nid => nid)
end
def find_or_create_cck
return cck if cck
@cck = cck_class.create! :vid => vid, :nid => nid
end
end
class ContentNodeFieldInstance
eval Drupal.common
storage_names[:drupal] = 'content_node_field_instance'
property :field_name, String,
:length => 32, :key => true
property :type_name, String,
:length => 32, :key => true
def field
@field ||= ContentNodeField.first :field_name => field_name
end
def field_type
@field_type ||= field.type
end
def to_s
f = field_name.match(/^field_(.*)/)[1]
case field_type
when 'userreference'
if through?
r = "has 1, :#{f},
:class_name => Drupal::#{f.camel_case},
:child_key => [:#{field_name}_uid]"
else
r = "belongs_to :#{field_name},
:class_name => 'Drupal::User'"
end
# when 'nodereference'
# r = "belongs_to :#{field_name},
# :class_name => 'Drupal::Node',
# :child_key => [:#{field_name}_nid]"
# else
# r = "property :#{field_name}, #{type}"
# r += ", :field => '#{field_name}_value'"
end
r
end
def through?
false
end
end
class ContentNodeField
eval Drupal.common
storage_names[:drupal] = 'content_node_field'
property :type, String,
:length => 127
property :field_name, String,
:length => 32
end
end
Node.send :include, CCK::NodeMethods
end
require 'drupal/cck/fields.rb'
require 'drupal/cck/builder.rb'
module Drupal
RepositoryName = :drupal
Repository = repository(Drupal::RepositoryName)
def self.common
"
include DataMapper::Resource
def self.default_repository_name
Drupal::RepositoryName
end
"
end
end
$:<< File.expand_path(Pathname.new(__FILE__).dirname)
require 'drupal/user'
require 'drupal/node'
require 'drupal/cck'
module Drupal
module CCK
module FieldMethods
def fields
Drupal::CCK::ContentNodeFieldInstance.all :type_name => type
end
end
class ThroughField
attr_accessor :field_name, :table
def initialize field
self.table = field
self.field_name = field.match(/^content_field_(.*)/)[1]
end
def field
@field ||= ContentNodeField.first :field_name => "field_#{field_name}"
end
def valid?
!field.nil?
end
def field_type
case field.type
when 'userreference'
"belongs_to :user,
:class_name => 'Drupal::User',
:child_key => [:#{field.field_name}_uid]"
end
end
def to_s
return "" unless valid?
"
class #{field_name.camel_case}
#{Drupal.common}
storage_names[:drupal] = '#{table}'
belongs_to :node,
:class_name => 'Drupal::Node',
:child_key => [:nid]
Drupal::User
#{field_type}
end
"
end
end
end
end
module Drupal
class Node
eval Drupal.common
storage_names[:drupal] = 'node'
property :nid, Serial
property :vid, Integer
property :uid, Integer
property :type, String
property :title, String
after :save, :write_node_revision
def write_node_revision
find_or_init_node_revision.attributes = {
:nid => nid,
:vid => vid,
:uid => uid,
:title => title,
:body => '',
:teaser => '',
:log => ''
}
node_revision.save!
end
def find_or_init_node_revision
return node_revision if node_revision
@node_revision = Drupal::NodeRevision.new
end
def node_revision
@node_revision ||= Drupal::NodeRevision.get nid
end
end
class NodeRevision
eval Drupal.common
storage_names[:drupal] = 'node_revisions'
property :nid, Serial
property :vid, Integer
property :uid, Integer
property :title, String
property :body, Text
property :teaser, Text
property :log, Text
end
end
module Drupal
class User
eval Drupal.common
storage_names[:drupal] = 'users'
property :uid, Serial
property :name, String,
:length => 60,
:nullable => false
has n, :nodes,
:child_key => [:uid],
:repository => Drupal::Repository
def profile
Drupal::Node.first :type => 'profile', :uid => uid
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment