拙作のKeyValueSource(key-valueストアのためのDataSource)で、スキーマ・レスなデータを保存できるようにしてみました。
cakephp-key-value-source – GitHub
(このプロジェクトは実用より実験を重視しているので、頻繁に仕様が変わります)
モデルクラスで $looseSchema というプロパティを設定すると、プライマリキーidを除いて、どんな構造のデータでも保存できるようになります。
class SchemalessUser extends AppModel { var $useDbConfig = 'memcache'; var $looseSchema = true; } // in Controllers $SchemalessUser->save(array('id' => 1234, 'name' => 'John Smith', 'hobby' => array('baseball', 'soccer'))); $SchemalessUser->save(array('id' => 1235, 'firstname' => 'John', 'lasttname' => 'Smith', 'age' => 20));
saveメソッドの fieldList オプションでキーを制限することができます。
$SchemalessUser->save(array('id' => 1234, 'name' => 'John Smith', 'hobby' => array('baseball', 'soccer')), array('fieldList' => array('id', 'name'))); // hobby は保存されない // array('id' => 1234, 'name' => 'John Smith') $ret = $SchemalessUser->read(null, 1234);
$looseSchema プロパティで一部のスキーマを明示的に設定しておくこともできます。下の例ではプライマリキーを key に変更し、更新日時を入力するために updated フィールドを定義しています。
class LooseSchemaUser extends AppModel { var $useDbConfig = 'memcache'; var $primaryKey = 'key'; var $looseSchema = array('key' => array('type' => 'string', 'length' => 255), 'updated' => array('type' => 'datetime')); } // in Controllers $LooseSchemaUser->save(array('key' => 1234, 'name' => 'John Smith')); // array('key' => 1234, 'name' => 'John Smith', 'updated' => '2010-02-07 22:23:13') $ret = $LooseSchemaUser->read(null, 1234);
$looseSchemaを設定せず、$_schema を設定すれば通常の動作になります。
class StrictUser extends AppModel { var $useDbConfig = 'memcache'; var $_schema = array('id' => array('type' => 'string', 'length' => 255), 'name' => array('type' => 'string')); } // in Controllers $StrictUser->save(array('id' => 1234, 'name' => 'John Smith', 'hobby' => array('baseball', 'soccer'))); // hobby は保存されない // array('id' => 1234, 'name' => 'John Smith') $ret = $StrictUser->read(null, 1234);
…
裏側では KeyValueLooseSchemaBehavior というBehaviorを使って、$_schema に存在しないデータを一旦別のフィールドに退避しておき、DataSource の中で取り出しています。退避用のフィールドはデフォルトでは _schemaless_data という名前で、DataSource の describe メソッドの中で組み込まれます。さらに(ちょっと反則気味ですが) Behavior 自体も describe メソッドの中で $actsAs に設定することで、特別な設定なしで動くようになっています。
自動設定される部分を書き下すと、おおむね次のようになります。
class User extends AppModel { var $actsAs = array('KeyValueLooseSchema' => array('schemalessField' => '_schemaless_data')); var $_schema = array('id' => array('type' => 'string', 'length' => 255), '_schemaless_data' => array('type' => 'schemaless')); }
KeyValueLooseSchemaBehavior の実装は汎用的になっているので、他の DataSource にほとんどそのまま持っていけるはずです。
[...] This post was mentioned on Twitter by Takayuki Miwa, Takayuki Miwa and cakephp_jp, ひろみ. ひろみ said: RT @tkykmw: CakePHPでSchemalessなデータを扱う http://bit.ly/beA67A [...]