Skip to content

Commit

Permalink
Working on the MPTT.
Browse files Browse the repository at this point in the history
  • Loading branch information
Matthew A Mattson committed Oct 5, 2012
1 parent baee27a commit ac963b8
Show file tree
Hide file tree
Showing 10 changed files with 55 additions and 46 deletions.
24 changes: 16 additions & 8 deletions classes/base/db/orm/mptt.php
Expand Up @@ -124,13 +124,17 @@ abstract class Base_DB_ORM_MPTT extends DB_ORM_Model {
*
* @access public
*/
public function __construct() {
public function __construct(Array $columns = NULL) {
parent::__construct();

$primary_key = static::primary_key();
if (count($primary_key) != 1) {
throw new Kohana_Exception('Message: Unable to initialize model. Reason: May not use a composite primary key with MPTT.');
}

if ($columns !== NULL) {
$this->columns += $columns; // id, title, parent_id, left_id, right_id, level_id, scope_id
}
}

/**
Expand Down Expand Up @@ -286,7 +290,7 @@ protected function create_space($start, $size = 2) {
->where($this->scope_column, DB_SQL_Operator::_EQUAL_TO_, $this->{$this->scope_column})
->execute();

$this->delete_space($this->{$this->left_column}, $this->get_size());
$this->delete_space($this->{$this->left_column}, $this->size());
}

/**
Expand Down Expand Up @@ -370,12 +374,12 @@ protected function get_scopes() {
}

/**
* This function gets the number of children nodes.
* This function returns the size of the current node.
*
* @access protected
* @return integer the number of children nodes
* @return integer the size of the current node
*/
protected function get_size() {
protected function size() {
return ($this->{$this->right_column} - $this->{$this->left_column}) + 1;
}

Expand Down Expand Up @@ -516,7 +520,7 @@ public function is_child(DB_ORM_MPTT $target) {
* of the supplied node
*/
public function is_descendant(DB_ORM_MPTT $target) {
return (($this->{$this->left_column} > $target->{$this->left_column}) AND ($this->{$this->right_column} < $target->{$this->right_column}) AND ($this->{$this->scope_column} = $target->{$this->scope_column}));
return (($this->{$this->left_column} > $target->{$this->left_column}) AND ($this->{$this->right_column} < $target->{$this->right_column}) AND ($this->{$this->scope_column} == $target->{$this->scope_column}));
}

/**
Expand Down Expand Up @@ -629,7 +633,7 @@ protected function move($target, $left_column, $left_offset, $level_offset, $all
: $target->{$this->right_column}) + $left_offset;
$level_offset = $target->{$this->level_column} - $this->{$this->level_column} + $level_offset;

$size = $this->get_size();
$size = $this->size();

$this->create_space($left_offset, $size);

Expand Down Expand Up @@ -847,7 +851,7 @@ public function root($scope = NULL) {
}

/**
* Returns the siblings of the current node
* This function returns the siblings of the current node.
*
* @access public
* @param boolean $self whether to include the current node
Expand All @@ -857,6 +861,10 @@ public function root($scope = NULL) {
* @return DB_ResultSet an array of sibling nodes
*/
public function siblings($self = FALSE, $ordering = 'ASC') {
if ($this->root()) {
return new DB_ResultSet(array(), 0);
}

$builder = DB_ORM::select(get_class($this))
->where($this->left_column, DB_SQL_Operator::_GREATER_THAN_, $this->parent->{$this->left_column})
->where($this->right_column, DB_SQL_Operator::_LESS_THAN_, $this->parent->{$this->right_column})
Expand Down
15 changes: 8 additions & 7 deletions schema/mptt/db2.sql
Expand Up @@ -15,14 +15,15 @@
----

----
-- Table structure for the "mptt_example" table
-- Table structure for the "mptt" table
----

CREATE TABLE "mptt_example" (
CREATE TABLE "mptt" (
"id" INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
"name" VARCHAR(35) NOT NULL DEFAULT '',
"lft" INTEGER NOT NULL,
"rgt" INTEGER NOT NULL,
"lvl" INTEGER NOT NULL,
"scope" INTEGER NOT NULL
"title" VARCHAR(35) NOT NULL DEFAULT '',
"parent_id" INTEGER NOT NULL,
"left_id" INTEGER NOT NULL,
"right_id" INTEGER NOT NULL,
"level_id" INTEGER NOT NULL,
"scope_id" INTEGER NOT NULL
);
4 changes: 2 additions & 2 deletions schema/mptt/drizzle.sql
Expand Up @@ -15,10 +15,10 @@
----

----
-- Table structure for the "mptt_example" table
-- Table structure for the "mptt" table
----

CREATE TABLE IF NOT EXISTS `mptt_example` (
CREATE TABLE IF NOT EXISTS `mptt` (
`id` INT NOT NULL AUTO_INCREMENT,
`name` VARCHAR(35) NOT NULL DEFAULT '',
`lft` INT NOT NULL,
Expand Down
16 changes: 8 additions & 8 deletions schema/mptt/firebird.sql
Expand Up @@ -15,30 +15,30 @@
----

----
-- Table structure for the "mptt_example" table
-- Table structure for the "mptt" table
----

CREATE TABLE "mptt_example" (
CREATE TABLE "mptt" (
"id" INTEGER NOT NULL,
"name" VARCHAR(32) NOT NULL DEFAULT '',
"lft" INTEGER NOT NULL,
"rgt" INTEGER NOT NULL,
"lvl" INTEGER NOT NULL,
"scope" INTEGER NOT NULL,
CONSTRAINT "mptt_example_id_pkey" PRIMARY KEY ("id")
CONSTRAINT "mptt_id_pkey" PRIMARY KEY ("id")
);

----
-- Auto-increment the "mptt_example" table (see, http://www.firebirdfaq.org/faq29/)
-- Auto-increment the "mptt" table (see, http://www.firebirdfaq.org/faq29/)
----

CREATE GENERATOR "mptt_example_id_gen";
CREATE GENERATOR "mptt_id_gen";

SET GENERATOR "mptt_example_id_gen" TO 0;
SET GENERATOR "mptt_id_gen" TO 0;

SET TERM !! ;
CREATE TRIGGER "mptt_example_id_trig" FOR "mptt_example" ACTIVE BEFORE INSERT POSITION 0 AS
CREATE TRIGGER "mptt_id_trig" FOR "mptt" ACTIVE BEFORE INSERT POSITION 0 AS
BEGIN
IF (NEW.ID IS NULL) THEN NEW.ID = GEN_ID("mptt_example_id_gen", 1);
IF (NEW.ID IS NULL) THEN NEW.ID = GEN_ID("mptt_id_gen", 1);
END!!
SET TERM ; !!
4 changes: 2 additions & 2 deletions schema/mptt/mariadb.sql
Expand Up @@ -15,10 +15,10 @@
----

----
-- Table structure for the "mptt_example" table
-- Table structure for the "mptt" table
----

CREATE TABLE IF NOT EXISTS `mptt_example` (
CREATE TABLE IF NOT EXISTS `mptt` (
`id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
`name` VARCHAR(35) NOT NULL DEFAULT '',
`lft` INT(11) UNSIGNED NOT NULL,
Expand Down
4 changes: 2 additions & 2 deletions schema/mptt/mssql.sql
Expand Up @@ -15,10 +15,10 @@
----

----
-- Table structure for the "mptt_example" table
-- Table structure for the "mptt" table
----

CREATE TABLE [mptt_example] (
CREATE TABLE [mptt] (
[id] [int] IDENTITY(1,1) NOT NULL PRIMARY KEY,
[name] [varchar](35) NOT NULL DEFAULT (''),
[lft] [int] NOT NULL,
Expand Down
4 changes: 2 additions & 2 deletions schema/mptt/mysql.sql
Expand Up @@ -15,10 +15,10 @@
----

----
-- Table structure for the "mptt_example" table
-- Table structure for the "mptt" table
----

CREATE TABLE IF NOT EXISTS `mptt_example` (
CREATE TABLE IF NOT EXISTS `mptt` (
`id` INT(11) NOT NULL,
`name` VARCHAR(35) NOT NULL DEFAULT '',
`lft` INT(11) NOT NULL,
Expand Down
20 changes: 10 additions & 10 deletions schema/mptt/oracle.sql
Expand Up @@ -15,40 +15,40 @@
----

----
-- Table structure for the "mptt_example" table
-- Table structure for the "mptt" table
----

CREATE TABLE `mptt_example` (
CREATE TABLE `mptt` (
"id" NUMBER(11) NOT NULL,
`name` VARCHAR(35) NOT NULL DEFAULT '',
"lft" NUMBER(11) NOT NULL,
"rgt" NUMBER(11) NOT NULL,
"lvl" NUMBER(11) NOT NULL,
"scope" NUMBER(11) NOT NULL,
CONSTRAINT "mptt_example_id_pkey" PRIMARY KEY ("id")
CONSTRAINT "mptt_id_pkey" PRIMARY KEY ("id")
);

----
-- Auto-increment the "mptt_example" table (see, http://earlruby.org/2009/01/creating-auto-increment-columns-in-oracle/)
-- Auto-increment the "mptt" table (see, http://earlruby.org/2009/01/creating-auto-increment-columns-in-oracle/)
----

CREATE SEQUENCE "mptt_example_id_seq" START WITH 1 INCREMENT BY 1;
CREATE SEQUENCE "mptt_id_seq" START WITH 1 INCREMENT BY 1;

CREATE TRIGGER "mptt_example_id_trig" BEFORE INSERT ON "mptt_example" FOR EACH ROW
CREATE TRIGGER "mptt_id_trig" BEFORE INSERT ON "mptt" FOR EACH ROW
DECLARE
max_id NUMBER;
cur_seq NUMBER;
BEGIN
IF :new.id IS NULL THEN
-- No ID passed, get one from the sequence
SELECT "mptt_example_id_seq".nextval INTO :new.id FROM dual;
SELECT "mptt_id_seq".nextval INTO :new.id FROM dual;
ELSE
-- ID was set via insert, so update the sequence
SELECT greatest(nvl(max(id),0), :new.id) INTO max_id FROM "mptt_example";
SELECT "mptt_example_id_seq".nextval INTO cur_seq FROM dual;
SELECT greatest(nvl(max(id),0), :new.id) INTO max_id FROM "mptt";
SELECT "mptt_id_seq".nextval INTO cur_seq FROM dual;
WHILE cur_seq < max_id
LOOP
SELECT "mptt_example_id_seq".nextval INTO cur_seq FROM dual;
SELECT "mptt_id_seq".nextval INTO cur_seq FROM dual;
END LOOP;
END IF;
END;
6 changes: 3 additions & 3 deletions schema/mptt/postgresql.sql
Expand Up @@ -15,15 +15,15 @@
----

----
-- Table structure for the "mptt_example" table
-- Table structure for the "mptt" table
----

CREATE TABLE "mptt_example" (
CREATE TABLE "mptt" (
"id" serial,
"name" varchar(35) NOT NULL DEFAULT '',
"lft" integer NOT NULL,
"rgt" integer NOT NULL,
"lvl" integer NOT NULL,
"scope" integer NOT NULL,
CONSTRAINT "mptt_example_id_pkey" PRIMARY KEY ("id")
CONSTRAINT "mptt_id_pkey" PRIMARY KEY ("id")
);
4 changes: 2 additions & 2 deletions schema/mptt/sqlite.sql
Expand Up @@ -15,10 +15,10 @@
----

----
-- Table structure for the "mptt_example" table
-- Table structure for the "mptt" table
----

CREATE TABLE IF NOT EXISTS [mptt_example] (
CREATE TABLE IF NOT EXISTS [mptt] (
[id] INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
[name] VARCHAR(35) NOT NULL DEFAULT '',
[lft] INTEGER NOT NULL,
Expand Down

0 comments on commit ac963b8

Please sign in to comment.