Class: Tilia::Dav::PropertyStorage::Backend::Sequel
- Includes:
- BackendInterface
- Defined in:
- lib/tilia/dav/property_storage/backend/sequel.rb
Overview
PropertyStorage PDO backend.
This backend class uses a PDO-enabled database to store webdav properties. Both sqlite and mysql have been tested.
The database structure can be found in the examples/sql/ directory.
Constant Summary collapse
- VT_STRING =
Value is stored as string.
1
- VT_XML =
Value is stored as XML fragment.
2
- VT_OBJECT =
Value is stored as a property object.
3
Instance Attribute Summary collapse
-
#table_name ⇒ Object
PDO table name we’ll be using.
Instance Method Summary collapse
-
#delete(path) ⇒ Object
This method is called after a node is deleted.
-
#initialize(sequel) ⇒ Sequel
constructor
Creates the PDO property storage engine.
-
#move(source, destination) ⇒ Object
This method is called after a successful MOVE.
-
#prop_find(path, prop_find) ⇒ Object
Fetches properties for a path.
-
#prop_patch(path, prop_patch) ⇒ Object
Updates properties for a path.
Constructor Details
#initialize(sequel) ⇒ Sequel
Creates the PDO property storage engine
42 43 44 45 |
# File 'lib/tilia/dav/property_storage/backend/sequel.rb', line 42 def initialize(sequel) @sequel = sequel @table_name = 'propertystorage' end |
Instance Attribute Details
#table_name ⇒ Object
PDO table name we’ll be using
37 38 39 |
# File 'lib/tilia/dav/property_storage/backend/sequel.rb', line 37 def table_name @table_name end |
Instance Method Details
#delete(path) ⇒ Object
This method is called after a node is deleted.
This allows a backend to clean up all associated properties.
The delete method will get called once for the deletion of an entire tree.
140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 |
# File 'lib/tilia/dav/property_storage/backend/sequel.rb', line 140 def delete(path) child_path = path.gsub( /[=%_]/, '=' => '==', '%' => '=%', '_' => '=_' ) child_path << '/%' delete_ds = @sequel[ "DELETE FROM #{@table_name} WHERE path = ? OR path LIKE ? ESCAPE '='", path, child_path ] delete_ds.delete end |
#move(source, destination) ⇒ Object
This method is called after a successful MOVE
This should be used to migrate all properties from one path to another. Note that entire collections may be moved, so ensure that all properties for children are also moved along.
165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 |
# File 'lib/tilia/dav/property_storage/backend/sequel.rb', line 165 def move(source, destination) # I don't know a way to write this all in a single sql query that's # also compatible across db engines, so we're letting PHP do all the # updates. Much slower, but it should still be pretty fast in most # cases. update = "UPDATE #{table_name} SET path = ? WHERE id = ?" @sequel.fetch("SELECT id, path FROM #{@table_name} WHERE path = ? OR path LIKE ?", source, "#{source}/%") do |row| # Sanity check. SQL may select too many records, such as records # with different cases. next if row[:path] != source && row[:path].index("#{source}/") != 0 trailing_part = row[:path][source.size + 1..-1] new_path = destination new_path << "/#{trailing_part}" unless trailing_part.blank? update_ds = @sequel[ update, new_path, row[:id] ] update_ds.update end end |
#prop_find(path, prop_find) ⇒ Object
Fetches properties for a path.
This method received a PropFind object, which contains all the information about the properties that need to be fetched.
Ususually you would just want to call ‘get404Properties’ on this object, as this will give you the exact list of properties that need to be fetched, and haven’t yet.
However, you can also support the ‘allprops’ property here. In that case, you should check for prop_find.all_props?.
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/tilia/dav/property_storage/backend/sequel.rb', line 62 def prop_find(path, prop_find) if !prop_find.all_props? && prop_find.load_404_properties.size == 0 return end @sequel.fetch("SELECT name, value, valuetype FROM #{@table_name} WHERE path = ?", path) do |row| case row[:valuetype] when nil, VT_STRING prop_find.set(row[:name], row[:value]) when VT_XML prop_find.set(row[:name], Xml::Property::Complex.new(row[:value])) when VT_OBJECT prop_find.set(row[:name], YAML.load(row[:value])) end end end |
#prop_patch(path, prop_patch) ⇒ Object
Updates properties for a path
This method received a PropPatch object, which contains all the information about the update.
Usually you would want to call ‘handleRemaining’ on this object, to get a list of all properties that need to be stored.
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 |
# File 'lib/tilia/dav/property_storage/backend/sequel.rb', line 90 def prop_patch(path, prop_patch) prop_patch.handle_remaining( lambda do |properties| update_stmt = "REPLACE INTO #{@table_name} (path, name, valuetype, value) VALUES (?, ?, ?, ?)" delete_stmt = "DELETE FROM #{@table_name} WHERE path = ? AND name = ?" properties.each do |name, value| if !value.nil? if value.scalar? value_type = VT_STRING elsif value.is_a?(Xml::Property::Complex) value_type = VT_XML value = value.xml else value_type = VT_OBJECT value = YAML.dump(value) end update_ds = @sequel[ update_stmt, path, name, value_type, value ] update_ds.update else delete_ds = @sequel[ delete_stmt, path, name ] delete_ds.delete end end true end ) end |