DBAL 사용자를 위한 다중 루트 중첩 세트 구현입니다.
이 라이브러리는 테이블당 여러 루트 노드가 있는 중첩 세트에 대한 쓰기, 읽기 및 검사 클래스를 제공합니다. 오로지 Doctrine DBAL에만 의존합니다.
다른 솔루션과 달리 이 라이브러리는 경계가 명확하며 소프트웨어 설계를 사용자에게 맡깁니다.
작곡가를 사용하여 라이브러리 설치
> composer require shopware/dbal-nested-set
구현의 기본 열 이름을 설정하는 구성은 항상 필요합니다.
use Shopware DbalNestedSet NestedSetConfig ;
$ config = new NestedSetConfig (
' id ' , // Primary key column name
' left ' , // left column name
' right ' , // right column name
' level ' // level column name
);
그런 다음 NestedSetFactory
를 사용하여 라이브러리의 다양한 클래스를 만들 수 있습니다.
use Shopware DbalNestedSet NestedSetFactory ;
use Doctrine DBAL Connection ;
$ writer = NestedSetFactory:: createWriter ( $ dbalConnection , $ config );
중첩된 세트 테이블에 대한 정규화된 스키마를 생성할 수 있으며 이는 NestedSetTableFactory
를 통해 수행할 수 있습니다. 인덱스가 있는 트리에 대한 기본 DDL을 생성합니다. 따라서 이름 열과 자동 증가 ID가 있는 간단한 트리를 추가하려는 경우 다음과 같습니다.
$ tableFactory = NestedSetFactory:: createTableFactory ( $ connection , $ config );
$ schema = new Doctrine DBAL Schema Schema ();
$ table = $ tableFactory -> createTable (
$ schema ,
' tree ' , // table name
' root_id ' // nested set root id
);
$ table -> addColumn ( ' id ' , ' integer ' , [ ' unsigned ' => true , ' autoincrement ' => true ]);
$ table -> addColumn ( ' name ' , ' string ' , [ ' length ' => 255 ]);
$ table -> setPrimaryKey ([ ' id ' ]);
$ addSql = $ schema -> toSql ( $ connection -> getDatabasePlatform ());
물론 이는 선택 사항이며 모든 스키마 구성 도구를 통해 수행할 수 있습니다.
라이브러리는 모든 삽입, 이동 및 업데이트 작업을 포함하는 NestedSetWriter
클래스를 제공합니다. 모든 작업은 DoctrineDBALConnection::insert()
및 DoctrineDBALConnection::update()
연상시켜야 하며 일반 데이터만 필요합니다.
예를 들어 이것을 사용하여 트리를 만들 수 있습니다.
$ writer = NestedSetFactory:: createWriter ( $ dbalConnection , $ config );
// create a Root node
$ writer -> insertRoot ( ' tree ' , ' root_id ' , 100 , [ ' name ' => ' Clothing ' ]);
// create subnodes
$ writer -> insertAsFirstChild ( ' tree ' , ' root_id ' , 1 , [ ' name ' => ' Men ' ]);
$ writer -> insertAsNextSibling ( ' tree ' , ' root_id ' , 2 , [ ' name ' => ' Women ' ]);
$ writer -> insertAsFirstChild ( ' tree ' , ' root_id ' , 2 , [ ' name ' => ' Suits ' ]);
$ writer -> insertAsFirstChild ( ' tree ' , ' root_id ' , 3 , [ ' name ' => ' Dresses ' ]);
$ writer -> insertAsNextSibling ( ' tree ' , ' root_id ' , 5 , [ ' name ' => ' Skirts ' ]);
$ writer -> insertAsNextSibling ( ' tree ' , ' root_id ' , 6 , [ ' name ' => ' Blouses ' ]);
$ writer -> insertAsFirstChild ( ' tree ' , ' root_id ' , 4 , [ ' name ' => ' Jackets ' ]);
$ writer -> insertAsFirstChild ( ' tree ' , ' root_id ' , 4 , [ ' name ' => ' Slacks ' ]);
$ writer -> insertAsFirstChild ( ' tree ' , ' root_id ' , 5 , [ ' name ' => ' Evening Gowns ' ]);
$ writer -> insertAsNextSibling ( ' tree ' , ' root_id ' , 10 , [ ' name ' => ' Sun Dresses ' ]);
그런 다음 작성자를 사용하여 노드를 이동합니다.
$ writer -> moveAsNextSibling ( ' tree ' , ' root_id ' , 4 , 7 );
다른 노드에 대한 정보를 검색할 수 있습니다. 이는 NestedSetTableNodeInspector
를 통해 수행할 수 있습니다.
$ inspector = NestedSetFactory:: createTableNodeInspector ( $ connection , $ config );
$ inspector -> isLeaf ( ' tree ' , ' root_id ' , 9 ); // true | false
$ inspector -> isAncestor ( ' tree ' , ' root_id ' , 1 , 2 ) // true | false
NestedSetQueryFactory
는 트리에서 노드 집합을 검색하는 데 도움이 됩니다. 라이브러리에는 엔터티 개념이 없으므로 선택, 조인 및 기타 조건을 추가할 수 있는 쿼리 빌더만 준비합니다.
$ queryFactory = NestedSetFactory:: createQueryFactory ( $ connection , $ config );
$ data = $ queryFactory
-> createChildrenQueryBuilder ( ' tree ' , ' t ' , ' root_id ' , 2 )
-> select ( ' * ' )
-> execute ()
-> fetchAll ();
로컬에서 개발하려면 작은 쉘 스크립트를 통해 데이터베이스 액세스를 구성해야 할 수도 있습니다.
#! /usr/bin/env bash
export DB_USER= ' foo '
export DB_PASSWORD= ' bar '
export DB_HOST= ' baz '
export DB_NAME= ' dbal_nested_set '
bin/phpunit