Skip to content

Instantly share code, notes, and snippets.

@nanasess
Last active March 17, 2017 08:31
Show Gist options
  • Save nanasess/c3a35e64bbabb6bb6fdf45ea3b6537c4 to your computer and use it in GitHub Desktop.
Save nanasess/c3a35e64bbabb6bb6fdf45ea3b6537c4 to your computer and use it in GitHub Desktop.
Doctrine で使用可能なツリーライブラリの検証

以下の機能をサポートしているか検証する

see also http://www.geocities.jp/mickindex/database/db_tree_ns.html

入れ子集合モデルを使った検索

以下のようなデータを生成しておく

INSERT INTO "dtb_category" VALUES(1,1,NULL,1,'キッチンツール',0,5,'2017-03-07 10:14:52','2017-03-17 13:57:14',0,1,8,'category');
INSERT INTO "dtb_category" VALUES(2,2,NULL,1,'インテリア',0,6,'2017-03-07 10:14:52','2017-03-17 13:57:14',0,1,2,'category');
INSERT INTO "dtb_category" VALUES(3,1,1,1,'食器',1,3,'2017-03-07 10:14:52','2017-03-17 13:57:14',0,2,5,'category');
INSERT INTO "dtb_category" VALUES(4,1,1,1,'調理器具',1,4,'2017-03-07 10:14:52','2017-03-17 13:57:14',0,6,7,'category');
INSERT INTO "dtb_category" VALUES(5,1,3,1,'フォーク',2,2,'2017-03-07 10:14:52','2017-03-17 13:57:14',0,3,4,'category');
INSERT INTO "dtb_category" VALUES(6,6,NULL,1,'新入荷',0,1,'2017-03-07 10:14:52','2017-03-17 13:57:14',0,1,2,'category');
category_id category_name tree_root parent_category_id level lft rgt
1 キッチンツール 1 0 1 8
2 インテリア 2 0 1 2
3 食器 1 1 1 2 5
4 調理器具 1 1 1 6 7
5 フォーク 1 3 2 3 4
6 新入荷 6 0 1 2

ルートとリーフを見つける

ルートを見つける

SELECT * 
FROM   dtb_category 
WHERE  parent_category_id IS NULL; 
$RootNodes = $app['eccube.repository.category']->getRootNodes();

リーフを見つける

SELECT
  *
FROM dtb_category
WHERE tree_root = <tree_root_id>
AND rgt = lft + 1;
$Roots = $app['eccube.repository.category']->getRootNodes();
$Leafs = $app['eccube.repository.category']->getLeafs($Roots[0]);

ノードの深さを計算する

dtb_category.hierarchy を取得

木の高さを計算する

SELECT MAX(hierarchy) AS height
FROM dtb_category
WHERE tree_root = <tree_root_id>;

木をインデント付きで表示する

$Tree = $app['eccube.repository.category']->childrenHierarchy();

直属の親・子を取得する

直属の親を取得

$Parent = $Category->getParent();

直属の子を取得

$Parent = $Category->getChildren();

部分木を列挙する

$Node = $app['eccube.repository.category']->findOneByName('キッチンツール');
$Tree = $app['eccube.repository.category']->childrenHierarchy($Node, false);

添え字に欠番がないか調べる

$app['eccube.repository.category']->verify();

パスを列挙する(列持ちバージョン)

$Node = $app['eccube.repository.category']->findOneByName('キッチンツール');
$Paths = $app['eccube.repository.category']->getPath($Node);

二つのノード間のパスを探す(行持ちバージョン)

TODO

二つのノードの相対位置を表示する

TODO

入れ子集合モデルを使った更新

部分木の削除

$Node = $app['eccube.repository.category']->findOneByName('キッチンツール');
$app['eccube.repository.category']->removeFromTree($Node);

単一ノードの削除

TODO 要動作確認

$Node = $app['eccube.repository.category']->findOneByName('キッチンツール');
$app['eccube.repository.category']->remove($Node);
$app['eccube.repository.category']->recover();

リーフを追加する

$Node = $app['eccube.repository.category']->findOneByName('キッチンツール');
$app['eccube.repository.category']->persistAsLastChild($Node);

親を追加する

TODO 要動作確認

$Node = $app['eccube.repository.category']->findOneByName('キッチンツール');
$app['eccube.repository.category']->persistAsFirstChild($Node);

ノードを入れ替える

$Node = $app['eccube.repository.category']->findOneByName('キッチンツール');
$app['eccube.repository.category']->moveUp($Node);
$app['eccube.repository.category']->moveDown($Node);

添え字の欠番を埋める

$app['eccube.repository.category']->recover();
$app['orm.em']->flush();

隣接リストモデルから入れ子集合モデルへ変換する

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment