<commit_before><?php
namespace MyPlot\provider;

use MyPlot\MyPlot;
use MyPlot\Plot;
use SQLite3;
use SQLite3Stmt;

class SQLiteDataProvider implements DataProvider
{
    private $plugin;

    /** @var SQLite3 */
    private $db;

    /** @var SQLite3Stmt */
    private $sqlGetPlot, $sqlSavePlot, $sqlSavePlotById, $sqlRemovePlot,
            $sqlRemovePlotById, $sqlGetPlotsByOwner, $sqlGetPlotsByOwnerAndLevel,
            $sqlGetExistingXZ;

    public function __construct(MyPlot $plugin) {
        $this->plugin = $plugin;
        $this->db = new SQLite3($plugin->getDataFolder() . "plots.db");
        $this->db->exec(
            "CREATE TABLE IF NOT EXISTS plots
            (id INTEGER PRIMARY KEY AUTOINCREMENT, level TEXT, X INTEGER, Z INTEGER, name TEXT,
             owner TEXT, helpers TEXT, biome TEXT)"
        );
        //$this->db->exec("CREATE TABLE IF NOT EXISTS comments (plotID INT, player TEXT, comment TEXT)");

        $this->sqlGetPlot = $this->db->prepare(
            "SELECT id, name, owner, helpers, biome FROM plots WHERE level = :level AND X = :X AND Z = :Z"
        );
        $this->sqlSavePlot = $this->db->prepare(
            "INSERT OR REPLACE INTO plots (id, level, X, Z, name, owner, helpers, biome) VALUES
            ((select id from plots where level = :level AND X = :X AND Z = :Z),
             :level, :X, :Z, :name, :owner, :helpers, :biome);"
        );
        $this->sqlSavePlotById = $this->db->prepare(
            "UPDATE plots SET name = :name, owner = :owner, helpers = :helpers, name = :name, biome = :biome WHERE id = :id"
        );
        $this->sqlRemovePlot = $this->db->prepare(
            "DELETE FROM plots WHERE level = :level AND X = :X AND Z = :Z"
        );
        $this->sqlRemovePlotById = $this->db->prepare("DELETE FROM plots WHERE id = :id");
        $this->sqlGetPlotsByOwner = $this->db->prepare("SELECT * FROM plots WHERE owner = :owner");
        $this->sqlGetPlotsByOwnerAndLevel = $this->db->prepare(
            "SELECT * FROM plots WHERE owner = :owner AND level = :level"
        );
        $this->sqlGetExistingXZ = $this->db->prepare(
            "SELECT X, Z FROM plots WHERE (
                level = :level
                AND (
                    (abs(X) == :number AND abs(Z) <= :number) OR
                    (abs(Z) == :number AND abs(X) <= :number)
                )
            )"
        );
    }

    public function close() {
        $this->db->close();
    }

    public function savePlot(Plot $plot) {
        $helpers = implode(",", $plot->helpers);
        // Need to be fixed
        //if ($plot->id >= 0) {
        //    $stmt = $this->sqlSavePlotById;
        //    $stmt->bindValue(":id", $plot->id, SQLITE3_INTEGER);
        //} else {
        $stmt = $this->sqlSavePlot;
        $stmt->bindValue(":level", $plot->levelName, SQLITE3_TEXT);
        $stmt->bindValue(":X", $plot->X, SQLITE3_INTEGER);
        $stmt->bindValue(":Z", $plot->Z, SQLITE3_INTEGER);
        //}
        $stmt->bindValue(":name", $plot->name, SQLITE3_TEXT);
        $stmt->bindValue(":owner", $plot->owner, SQLITE3_TEXT);
        $stmt->bindValue(":helpers", $helpers, SQLITE3_TEXT);
        $stmt->bindValue(":biome", $plot->biome, SQLITE3_TEXT);

        $result = $this->sqlSavePlot->execute();
        if ($result === false) {
            return false;
        } else {
            return true;
        }
    }

    public function deletePlot(Plot $plot) {
        if ($plot->id >= 0) {
            $stmt = $this->sqlRemovePlotById;
            $stmt->bindValue(":id", $plot->id, SQLITE3_INTEGER);
        } else {
            $stmt = $this->sqlRemovePlot;
            $stmt->bindValue(":level", $plot->levelName, SQLITE3_TEXT);
            $stmt->bindValue(":X", $plot->X, SQLITE3_INTEGER);
            $stmt->bindValue(":Z", $plot->Z, SQLITE3_INTEGER);
        }

        $result = $stmt->execute();
        if ($result === false) {
            return false;
        } else {
            return true;
        }
    }

    public function getPlot($levelName, $X, $Z) {
        $this->sqlGetPlot->bindValue(":level", $levelName, SQLITE3_TEXT);
        $this->sqlGetPlot->bindValue(":X", $X, SQLITE3_INTEGER);
        $this->sqlGetPlot->bindValue(":Z", $Z, SQLITE3_INTEGER);
        $result = $this->sqlGetPlot->execute();
        if ($val = $result->fetchArray(SQLITE3_ASSOC)) {
            if ($val["helpers"] === null or $val["helpers"] === "") {
                $helpers = [];
            } else {
                $helpers = explode(",", (string)$val["helpers"]);
            }
            return new Plot($levelName, $X, $Z, (string)$val["name"], (string)$val["owner"],
                $helpers, (string)$val["biome"], (int)$val["id"]);
        }
        return null;
    }

    public function getPlotsByOwner($owner, $levelName = "") {
        if ($levelName === "") {
            $stmt = $this->sqlGetPlotsByOwner;
        } else {
            $stmt = $this->sqlGetPlotsByOwnerAndLevel;
            $stmt->bindValue(":level", $levelName, SQLITE3_TEXT);
        }
        $stmt->bindValue(":owner", $owner, SQLITE3_TEXT);
        $plots = [];
        $result = $stmt->execute();
        while ($val = $result->fetchArray(SQLITE3_ASSOC)) {
            $helpers = explode(",", (string)$val["helpers"]);
            $plots[] = new Plot((string)$val["level"], (int)$val["X"], (int)$val["Z"], (string)$val["name"],
                (string)$val["owner"], $helpers, (string)$val["biome"], (int)$val["id"]);
        }
        usort($plots, function ($plot1, $plot2) {
            /** @var Plot $plot1 */
            /** @var Plot $plot2 */
            return strcmp($plot1->levelName, $plot2->levelName);
        });
        return $plots;
    }

    public function getNextFreePlot($levelName, $limitXZ = 20) {
        $this->sqlGetExistingXZ->bindValue(":level", $levelName, SQLITE3_TEXT);
        $i = 0;
        $this->sqlGetExistingXZ->bindParam(":number", $i, SQLITE3_INTEGER);
        for (; $i < $limitXZ; $i++) {<commit_msg>Reset prepared statements before reuse<commit_after><?php
namespace MyPlot\provider;

use MyPlot\MyPlot;
use MyPlot\Plot;
use SQLite3;
use SQLite3Stmt;

class SQLiteDataProvider implements DataProvider
{
    private $plugin;

    /** @var SQLite3 */
    private $db;

    /** @var SQLite3Stmt */
    private $sqlGetPlot, $sqlSavePlot, $sqlSavePlotById, $sqlRemovePlot,
            $sqlRemovePlotById, $sqlGetPlotsByOwner, $sqlGetPlotsByOwnerAndLevel,
            $sqlGetExistingXZ;

    public function __construct(MyPlot $plugin) {
        $this->plugin = $plugin;
        $this->db = new SQLite3($plugin->getDataFolder() . "plots.db");
        $this->db->exec(
            "CREATE TABLE IF NOT EXISTS plots
            (id INTEGER PRIMARY KEY AUTOINCREMENT, level TEXT, X INTEGER, Z INTEGER, name TEXT,
             owner TEXT, helpers TEXT, biome TEXT)"
        );
        //$this->db->exec("CREATE TABLE IF NOT EXISTS comments (plotID INT, player TEXT, comment TEXT)");

        $this->sqlGetPlot = $this->db->prepare(
            "SELECT id, name, owner, helpers, biome FROM plots WHERE level = :level AND X = :X AND Z = :Z"
        );
        $this->sqlSavePlot = $this->db->prepare(
            "INSERT OR REPLACE INTO plots (id, level, X, Z, name, owner, helpers, biome) VALUES
            ((select id from plots where level = :level AND X = :X AND Z = :Z),
             :level, :X, :Z, :name, :owner, :helpers, :biome);"
        );
        $this->sqlSavePlotById = $this->db->prepare(
            "UPDATE plots SET name = :name, owner = :owner, helpers = :helpers, name = :name, biome = :biome WHERE id = :id"
        );
        $this->sqlRemovePlot = $this->db->prepare(
            "DELETE FROM plots WHERE level = :level AND X = :X AND Z = :Z"
        );
        $this->sqlRemovePlotById = $this->db->prepare("DELETE FROM plots WHERE id = :id");
        $this->sqlGetPlotsByOwner = $this->db->prepare("SELECT * FROM plots WHERE owner = :owner");
        $this->sqlGetPlotsByOwnerAndLevel = $this->db->prepare(
            "SELECT * FROM plots WHERE owner = :owner AND level = :level"
        );
        $this->sqlGetExistingXZ = $this->db->prepare(
            "SELECT X, Z FROM plots WHERE (
                level = :level
                AND (
                    (abs(X) == :number AND abs(Z) <= :number) OR
                    (abs(Z) == :number AND abs(X) <= :number)
                )
            )"
        );
    }

    public function close() {
        $this->db->close();
    }

    public function savePlot(Plot $plot) {
        $helpers = implode(",", $plot->helpers);
        // Need to be fixed
        //if ($plot->id >= 0) {
        //    $stmt = $this->sqlSavePlotById;
        //    $stmt->bindValue(":id", $plot->id, SQLITE3_INTEGER);
        //} else {
        $stmt = $this->sqlSavePlot;
        $stmt->bindValue(":level", $plot->levelName, SQLITE3_TEXT);
        $stmt->bindValue(":X", $plot->X, SQLITE3_INTEGER);
        $stmt->bindValue(":Z", $plot->Z, SQLITE3_INTEGER);
        //}
        $stmt->bindValue(":name", $plot->name, SQLITE3_TEXT);
        $stmt->bindValue(":owner", $plot->owner, SQLITE3_TEXT);
        $stmt->bindValue(":helpers", $helpers, SQLITE3_TEXT);
        $stmt->bindValue(":biome", $plot->biome, SQLITE3_TEXT);
        $stmt->reset();
        $result = $this->sqlSavePlot->execute();
        if ($result === false) {
            return false;
        } else {
            return true;
        }
    }

    public function deletePlot(Plot $plot) {
        if ($plot->id >= 0) {
            $stmt = $this->sqlRemovePlotById;
            $stmt->bindValue(":id", $plot->id, SQLITE3_INTEGER);
        } else {
            $stmt = $this->sqlRemovePlot;
            $stmt->bindValue(":level", $plot->levelName, SQLITE3_TEXT);
            $stmt->bindValue(":X", $plot->X, SQLITE3_INTEGER);
            $stmt->bindValue(":Z", $plot->Z, SQLITE3_INTEGER);
        }
        $stmt->reset();
        $result = $stmt->execute();
        if ($result === false) {
            return false;
        } else {
            return true;
        }
    }

    public function getPlot($levelName, $X, $Z) {
        $this->sqlGetPlot->bindValue(":level", $levelName, SQLITE3_TEXT);
        $this->sqlGetPlot->bindValue(":X", $X, SQLITE3_INTEGER);
        $this->sqlGetPlot->bindValue(":Z", $Z, SQLITE3_INTEGER);
        $this->sqlGetPlot->reset();
        $result = $this->sqlGetPlot->execute();
        if ($val = $result->fetchArray(SQLITE3_ASSOC)) {
            if ($val["helpers"] === null or $val["helpers"] === "") {
                $helpers = [];
            } else {
                $helpers = explode(",", (string)$val["helpers"]);
            }
            return new Plot($levelName, $X, $Z, (string)$val["name"], (string)$val["owner"],
                $helpers, (string)$val["biome"], (int)$val["id"]);
        }
        return null;
    }

    public function getPlotsByOwner($owner, $levelName = "") {
        if ($levelName === "") {
            $stmt = $this->sqlGetPlotsByOwner;
        } else {
            $stmt = $this->sqlGetPlotsByOwnerAndLevel;
            $stmt->bindValue(":level", $levelName, SQLITE3_TEXT);
        }
        $stmt->bindValue(":owner", $owner, SQLITE3_TEXT);
        $plots = [];
        $stmt->reset();
        $result = $stmt->execute();
        while ($val = $result->fetchArray(SQLITE3_ASSOC)) {
            $helpers = explode(",", (string)$val["helpers"]);
            $plots[] = new Plot((string)$val["level"], (int)$val["X"], (int)$val["Z"], (string)$val["name"],
                (string)$val["owner"], $helpers, (string)$val["biome"], (int)$val["id"]);
        }
        usort($plots, function ($plot1, $plot2) {
            /** @var Plot $plot1 */
            /** @var Plot $plot2 */
            return strcmp($plot1->levelName, $plot2->levelName);
        });
        return $plots;
    }

    public function getNextFreePlot($levelName, $limitXZ = 20) {
        $this->sqlGetExistingXZ->bindValue(":level", $levelName, SQLITE3_TEXT);
        $i = 0;
        $this->sqlGetExistingXZ->bindParam(":number", $i, SQLITE3_INTEGER);
        for (; $i < $limitXZ; $i++) {
{'fraction_non_alphanumeric': 0.1723486404337468, 'fraction_numerical': 0.0060790273556231, 'mean_word_length': 2.186910994764398, 'pattern_counts': {'":': 38, '<': 11, '<?xml version=': 0, '>': 186, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5515146', 'n_tokens_mistral': 3937, 'n_tokens_neox': 3812, 'n_words': 836}