Skip to content

Commit 8d053bd

Browse files
docs: Improve README and add ROADMAP for future features
- I enhanced README.md with a more detailed project description, prerequisites, usage clarifications for SqlDumperClass (including execute() and where() methods), and new examples for first(), reset(), and distinct(). - I corrected MigrateClass constraint usage examples in README.md to align with the current implementation. - I created ROADMAP.md outlining planned features and improvements for SqlDumperClass and MigrateClass. - I linked ROADMAP.md from README.md. - I documented a critical syntactic bug in SqlDumperClass's WHERE clause construction in ROADMAP.md and added related warnings in README.md.
1 parent b283148 commit 8d053bd

File tree

2 files changed

+172
-42
lines changed

2 files changed

+172
-42
lines changed

README.md

Lines changed: 94 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,16 @@
55
[![GitHub Code Style Action Status](https://img.shields.io/github/workflow/status/furkifor/sql_dumper/Check%20&%20fix%20styling?label=code%20style)](https://github.com/furkifor/sql_dumper/actions?query=workflow%3A"Check+%26+fix+styling"+branch%3Amaster)
66
[![Total Downloads](https://img.shields.io/packagist/dt/furkifor/sql_dumper.svg?style=flat-square)](https://packagist.org/packages/furkifor/sql_dumper)
77

8-
SQL query builder and database migration tool.
8+
## About The Project
9+
10+
This package provides tools for database interactions in PHP. It is designed as a project to get SQL query strings in ORM operations, drawing inspiration from Laravel Eloquent's logic. The package offers two main components:
11+
12+
* **SQL Query Builder**: A fluent interface to construct SQL SELECT queries programmatically.
13+
* **Database Migration Tool**: A tool to define and create database table schemas.
14+
15+
## Prerequisites
16+
17+
This package requires PHP 7.2 or higher.
918

1019
## Installation
1120

@@ -20,92 +29,135 @@ $sql_dumper = new Furkifor\SqlDumper("users");
2029

2130
// Simple query
2231
echo $sql_dumper->select('*')->get();
23-
// SELECT * FROM users
32+
// Output: SELECT * FROM users
2433

2534
// Query with conditions
2635
echo $sql_dumper->select('name, email')
2736
->where('age > ?', [18])
2837
->orderBy('name', 'DESC')
2938
->limit(10)
3039
->get();
31-
// SELECT name, email FROM users WHERE age > ? ORDER BY name DESC LIMIT 10
40+
// Output: SELECT name, email FROM users WHERE age > ? ORDER BY name DESC LIMIT 10
3241

3342
// JOIN operations
3443
echo $sql_dumper->select('users.*, roles.name as role_name')
3544
->join('INNER', 'roles', 'users.role_id = roles.id')
3645
->where('users.active = ?', [1])
3746
->get();
38-
// SELECT users.*, roles.name as role_name FROM users
47+
// Output: SELECT users.*, roles.name as role_name FROM users
3948
// INNER JOIN roles ON users.role_id = roles.id WHERE users.active = ?
4049

4150
// Grouping and HAVING
4251
echo $sql_dumper->select('country, COUNT(*) as user_count')
4352
->groupBy('country')
4453
->having('user_count > 100')
4554
->get();
46-
// SELECT country, COUNT(*) as user_count FROM users
55+
// Output: SELECT country, COUNT(*) as user_count FROM users
4756
// GROUP BY country HAVING user_count > 100
57+
58+
// Get the first user
59+
echo $sql_dumper->select('*')->where('id = ?', [1])->first();
60+
// Output: SELECT * FROM users WHERE id = ? LIMIT 1
61+
62+
// Select distinct countries
63+
echo $sql_dumper->select('country')->distinct()->get();
64+
// Output: SELECT DISTINCT country FROM users
65+
66+
// Resetting the query
67+
$query = $sql_dumper->select('name')->where('age > ?', [18]);
68+
echo $query->get(); // Output: SELECT name FROM users WHERE age > ?
69+
$query->reset();
70+
// Now the query builder is reset. You can build a new query on $sql_dumper from scratch.
71+
// For example:
72+
echo $sql_dumper->select('*')->where('status = ?', ['active'])->get();
73+
// Output: SELECT * FROM users WHERE status = ?
4874
```
4975

76+
### Important Notes on `execute()` and `where()`:
77+
78+
* **`execute()` Method**: The `SqlDumperClass` includes an `execute()` method. However, this method is a basic implementation that instantiates its own PDO connection internally. This is not suitable for production environments or scenarios requiring configurable database connections. It also directly fetches all results. For more complex applications or production use, it is **highly recommended** to use the `get()` method to retrieve the generated SQL query string and then execute it using your application's existing database connection setup (e.g., your own configured PDO instance or other database abstraction layer).
79+
80+
* **`where()` Method Safety**: When using the `where()` method, be cautious if you are embedding parameters directly into the condition string, especially for non-numeric values. The safest approach is to use `?` placeholders for values and pass an array of corresponding values as the second argument to `where()`. This helps prevent SQL injection vulnerabilities. For example, `->where('name = ?', ['John Doe'])` is preferred over `->where("name = 'John Doe'")`.
81+
5082
## Migration Tool Usage
5183

84+
The `MigrateClass` helps you define and create database tables.
85+
5286
```php
53-
$table = new MigrateClass("mysql");
87+
$table = new MigrateClass("mysql"); // Specify the database type (e.g., "mysql", "pgsql")
5488

55-
// Simple table creation
89+
// Simple table creation with constraints
5690
$table->name("users")
57-
->string('username', 255)->unique()->notnull()
58-
->string('email', 255)->unique()->notnull()
59-
->string('password', 255)->notnull()
60-
->datetime('created_at')->default("CURRENT_TIMESTAMP")
91+
->string('username', 255, ['UNIQUE', 'NOT NULL'])
92+
->string('email', 255, ['UNIQUE', 'NOT NULL'])
93+
->string('password', 255, ['NOT NULL'])
94+
->datetime('created_at', ['DEFAULT "CURRENT_TIMESTAMP"']) // Note: DEFAULT value needs to be a string within the array
6195
->createTable();
6296

63-
// Table with relationships
97+
// Table with relationships and other constraints
6498
$table->name("posts")
65-
->string('title', 255)->notnull()
66-
->text('content')
67-
->int('user_id')->notnull()
68-
->foreignKey('user_id', 'users', 'id')
69-
->datetime('published_at')->nullable()
70-
->boolean('is_published')->default(0)
99+
->string('title', 255, ['NOT NULL'])
100+
->text('content') // No specific constraints, column will be TEXT
101+
->int('user_id', ['NOT NULL']) // Assuming user_id is INT and required
102+
->foreignKey('user_id', 'users', 'id') // foreignKey() handles its own specific constraints
103+
->datetime('published_at', ['NULL']) // Explicitly allowing NULL values
104+
->boolean('is_published', ['DEFAULT 0']) // Example for a boolean with a default value
71105
->createTable();
72106

73-
// Table with custom constraints
107+
// Table with custom check constraints
74108
$table->name("products")
75-
->string('name', 100)->notnull()
76-
->decimal('price', 10, 2)->notnull()
77-
->int('stock')->notnull()->default(0)
78-
->check('price > 0')
79-
->check('stock >= 0')
109+
->string('name', 100, ['NOT NULL'])
110+
->decimal('price', "10, 2", ['NOT NULL']) // Ensure precision and scale are passed as a string if combined
111+
->int('stock', ['NOT NULL', 'DEFAULT 0'])
112+
->check('price > 0') // Table-level CHECK constraint
113+
->check('stock >= 0') // Another table-level CHECK constraint
80114
->createTable();
81115
```
82116

117+
### Understanding Constraints:
118+
119+
When defining columns using methods like `string()`, `int()`, `datetime()`, etc., you can pass an array of constraint strings as the third argument (or second for `text`, where length is not applicable). Common constraints include:
120+
121+
* `'NOT NULL'`
122+
* `'NULL'`
123+
* `'UNIQUE'`
124+
* `'PRIMARY KEY'` (though `id()` method is typically used for auto-incrementing primary keys)
125+
* `'DEFAULT <value>'` (e.g., `'DEFAULT 0'`, `'DEFAULT "CURRENT_TIMESTAMP"'`, `'DEFAULT "pending"'`)
126+
* For data types like `VARCHAR` (string) or `DECIMAL`, the size/precision is usually the second argument.
127+
128+
The `foreignKey()` and `check()` methods apply their specific types of constraints at the table level or column level as appropriate based on their design.
129+
83130
## Features
84131

85132
### SQL Query Builder
86-
- CREATE SELECT queries
87-
- WHERE conditions
88-
- JOIN operations (INNER, LEFT, RIGHT)
89-
- ORDER BY sorting
90-
- GROUP BY grouping
91-
- HAVING filtering
92-
- LIMIT clause
93-
- Parameter binding support
94-
- DISTINCT queries
133+
- Fluent interface to create SELECT queries
134+
- `WHERE` conditions with parameter binding (using `?`)
135+
- `JOIN` operations (INNER, LEFT, RIGHT)
136+
- `ORDER BY` sorting
137+
- `GROUP BY` grouping
138+
- `HAVING` filtering
139+
- `LIMIT` clause for pagination
140+
- `DISTINCT` queries
141+
- `first()` method to retrieve a single record (by appending `LIMIT 1`)
142+
- `reset()` method to clear the current query state
143+
- `get()` method to retrieve the generated SQL string
95144

96145
### Migration Tool
97-
- Multiple database system support (MySQL, MongoDB, SQL Server)
98-
- Support for all common data types
99-
- Automatic ID/Primary Key generation
100-
- Foreign Key relationships
101-
- Unique constraints
102-
- NOT NULL constraints
103-
- DEFAULT values
104-
- CHECK constraints
146+
- Support for multiple database systems (e.g., MySQL, SQL Server - driver dependent).
147+
- Common data types: `string`, `int`, `text`, `datetime`, `boolean`, `decimal`, etc.
148+
- Automatic `id()` method for auto-incrementing primary keys.
149+
- Fluent definition for:
150+
- Foreign Key relationships (`foreignKey()`)
151+
- Column constraints like `UNIQUE`, `NOT NULL`, `DEFAULT` (passed as an array to type methods)
152+
- Table-level `CHECK` constraints (`check()`)
153+
154+
## Future Enhancements / Roadmap
155+
156+
We have a documented roadmap for planned features and improvements. You can view it here: [ROADMAP.md](ROADMAP.md)
105157

106158
## Contributing
107159

108-
Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
160+
Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change. Please ensure to update tests as appropriate.
109161

110162
## License
111163

ROADMAP.md

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
# Roadmap
2+
3+
This document outlines planned future enhancements and features for the SqlDumper package.
4+
The project is actively maintained, and contributions are welcome! If you'd like to contribute, please see our [CONTRIBUTING.md](.github/CONTRIBUTING.md) or open an issue to discuss a new feature.
5+
6+
## SqlDumperClass (Query Builder)
7+
8+
The `SqlDumperClass` provides a fluent interface for building SQL SELECT queries. Future enhancements aim to expand its capabilities and improve its robustness:
9+
10+
* **CRUD Operations:**
11+
* **INSERT Statements:** Add functionality to build `INSERT` queries.
12+
* **UPDATE Statements:** Add functionality to build `UPDATE` queries.
13+
* **DELETE Statements:** Add functionality to build `DELETE` queries.
14+
15+
* **Enhanced Querying:**
16+
* **Advanced WHERE Clauses:**
17+
* Easier `OR WHERE` conditions.
18+
* Support for nested conditions (e.g., `WHERE (col1 = ? AND col2 = ?) OR col3 = ?`).
19+
* Dedicated methods for `WHERE IN (...)`, `WHERE BETWEEN ...`, `WHERE NULL`, `WHERE NOT NULL`.
20+
* **Subqueries:** Enable the use of subqueries within `SELECT`, `FROM`, or `WHERE` clauses.
21+
* **OFFSET Clause:** Add an `offset()` method for pagination, complementing the existing `limit()` method.
22+
* **Aggregate Function Helpers:** Introduce convenient methods for common aggregate functions with aliases (e.g., `countAs('total')`, `sumAs('amount', 'total_amount')`).
23+
* **Raw SQL Expressions:** Provide a way to inject raw SQL snippets for complex scenarios not covered by the builder.
24+
25+
* **Execution and Utility:**
26+
* **Improved `execute()` Method:**
27+
* Refactor `execute()` to accept an existing database connection (e.g., PDO, mysqli object) instead of instantiating one internally.
28+
* Allow specifying the fetch mode or returning different types of results (e.g., single row, specific column, success boolean for write operations).
29+
* **Schema Introspection:** Potentially add utility methods to retrieve basic schema information like listing tables or columns (could also be a separate companion utility).
30+
* **Fix WHERE Clause Construction:** Correct the syntactic issue in the `get()` method where `WHERE` clauses are assembled. Currently, it can incorrectly prepend `AND` or `OR` to the first condition (e.g., `SELECT * FROM users WHERE AND age > ?`). The logic needs to ensure that `WHERE` is followed directly by the first condition, and subsequent conditions are correctly appended with `AND` or `OR`.
31+
* **Refined Parameter Handling:** Further review and solidify parameter handling in `where()` clauses to ensure security and prevent SQL injection vulnerabilities, promoting the use of prepared statements for all parameters.
32+
33+
## MigrateClass (Migration Tool)
34+
35+
The `MigrateClass` assists in database table creation. The goal is to evolve this into a more comprehensive migration and schema management tool.
36+
37+
* **Broader Database Support:**
38+
* **Full Implementation for MongoDB:** Complete the connection and schema generation logic for MongoDB.
39+
* **Full Implementation for SQL Server:** Complete the connection and schema generation logic for SQL Server.
40+
* **Support for PostgreSQL and SQLite:** Extend compatibility to other popular database systems.
41+
42+
* **Extended Data Types and Constraints:**
43+
* **Additional Data Types:** Introduce support for `DATE`, `TIME`, `TIMESTAMP` (with precision), `FLOAT`, `DOUBLE`, `DECIMAL` (with precision, currently uses `VARCHAR`), `BLOB`, `ENUM`, `SET`, `JSON`.
44+
* **More Column Constraints/Modifiers:**
45+
* `UNSIGNED` for numeric types.
46+
* `ON UPDATE` / `ON DELETE` actions for foreign keys (e.g., `CASCADE`, `SET NULL`).
47+
* Ability to set `PRIMARY KEY` on specific columns or composite keys, not just the default `id`.
48+
* Full support for `INDEX` creation (normal, unique, fulltext).
49+
* `COMMENT` support for tables and columns.
50+
* `CHARACTER SET` and `COLLATION` options per column/table.
51+
* **Fluent Constraint Methods:** Introduce dedicated chainable methods for common constraints like `->unique()`, `->nullable()`, `->default(<value>)` for a more expressive API, aligning with initial README examples.
52+
53+
* **Schema Manipulation:**
54+
* **Table Alteration (`ALTER TABLE`):**
55+
* Add new columns to existing tables.
56+
* Drop columns from existing tables.
57+
* Modify existing column definitions (type, constraints, default value).
58+
* Rename columns.
59+
* Rename tables.
60+
* Add/drop constraints on existing tables.
61+
* **Dropping Tables:** Implement a `dropTable()` or `dropTableIfExists()` method.
62+
* **Dropping Foreign Keys/Indexes:** Methods to specifically remove these.
63+
64+
* **Full Migration System:**
65+
* **Migration Tracking:** Implement a system to track executed migrations (e.g., using a dedicated database table).
66+
* **Up and Down Migrations:** Define migrations with `up()` (to apply changes) and `down()` (to revert changes) methods.
67+
* **CLI Tool:** Develop a basic command-line interface (CLI) tool for managing migrations (e.g., `migrate`, `rollback`, `status`).
68+
* **Migration Generation:** Commands to generate new blank migration files.
69+
70+
* **Data Seeding:**
71+
* Provide a mechanism to define and run seeders for populating tables with initial or test data.
72+
73+
* **Improved Configuration:**
74+
* Move away from `config.ini` for database connections in `MigrateClass` towards a more flexible configuration approach, perhaps by passing connection parameters or a connection object directly, similar to the proposed changes for `SqlDumperClass::execute()`.
75+
76+
---
77+
78+
This roadmap is subject to change based on community feedback and project priorities.

0 commit comments

Comments
 (0)