Class design to cater for different database in future - php

I'm implementing a database class to open connection, read, write, delete, update, etc. I'm currently using MySql server.
I'm attempting to write a database class that will be able to cater for different database in future. Maybe we will switch to SQL Server in future. because of this, I hope to design my class in such a way that I can write new classes for SQL Server and it wouldn't affect the client/controller that is calling the database class. I would like to stick to the design pattern principle, open for extension, closed for modification.
In strategy, I could create a abstract class, and create multiple concrete classes for MySql or SQL Server? Does anyone know which pattern should I follow that doesn't violate the rules for these patterns? I am not too sure about adapter. I read that adapter is used to interface existing classes. But in my case, I will be creating my new db classes for SQL Server. Unless I'm using an opensource class.

Related

Creating a PHP wrapper for MongoDB and MysqlDB X DevApi

I am working on a project that use MongoDB to house transactional data with MySQL housing all other data. For various reasons, we are looking at the possibility of moving from MongoDB to the MySQL xDevApi with the 8.0 version. In preparation for this possibility as well as to ease the learning curve as well as other database considerations, I am looking at creating a wrapper that will allow us to switch the database backend without having to update all the places in the code that interfaces with MongoDB.
I have an outline of one already, but am not sure it is the best way to do it. I think it is a decent start, I am just not certain of the file/folder structure.
The current file/folder structure is as follows:
\DocumentStore
abstract class DocumentStoreQueryBuilder
interface IDocumentStore
interface IDocumentStoreConnection
\DocumentStore\Mongo
class Connection implements IDocumentStoreConnection
class Query implements IDocumentStore
class QueryBuilder extends BuilderAlias
My thought is to use language similar to a relational database in order to help with the initial learning curve of those coming from a RDB background (the majority of those that will be coming onto the project).
I am sure that there is a better way to organize things, but to be honest, I am not too terribly familiar with Document Storage generally.
This is code that works with what I have so far.
In the connection file that is called from all files that need the connection.
$mgdbdoc = new DocumentStore\Mongo\Connection();
$connectionString = $mgdbdoc->buildConnectionString($settings);
$mgdbdoc->connect($connectionString);
$collection = new DocumentStore\Mongo\Query($mgdbdoc);
Defines the collection for action on. This could, theretically, be saved to a unique class name for each collection if necessary.
$collection->setCollection('transactions');
To be called whenever necessary.
$result = $collection->insert($document);
$result = $collection->filter($filter)->limit(2)->descending('_id')->select();
I haven't put in the update and remove functionality yet, and the and/or functionality is proving difficult, but I can get that.
My question is for any advice regarding this project. Any thoughts on proceeding forward? I haven't been able to locate a wrapper for multiple NoSQL databases like there is for PDO. I would appreciate any thoughts or advice.

PHP MVC: Multiple databases, multiple data mappers?

I am working on my HMVC project.
Right now I am using data mappers in order to move data between the models (domain objects) and a MySQL database. Each mapper receives a MySQL adapter as dependency. The injected adapter receives a PDO instance (a database connection) as dependency and runs sql queries on the database.
I also use a dependency injection container (Auryn).
I'd like to be able to simultaneously retrieve data from storages of different types (MySQL database, PostgreSQL database, XML feeds, etc).
Let's say, I want to retrieve User data from a PostgreSQL database (by using PDO data-access abstraction), to change it, and to save it into a MySQL database (by using mysqli data-access abstraction) on another server. So, there will be different data-access calls for the both database types.
My question is:
Should I create a different mapper for each storage type, like
UserMapperPgsql(PgsqlAdapter $adapter)
UserMapperMySql(MySqlAdapter $adapter)
, or should I create only one mapper with more adapters (one for each data type) as dependencies, like bellow?
UserMapper(PgsqlAdapter $adapter1, MySqlAdapter $adapter2, ...)
Thank you all for your suggestions!
What an odd project you have there.
Anyway. I would go with two separate mappers for separate storage mediums. Because trying to juggle those adapters inside a mapper might end up quite complicated.
That said, depending on how complicated the persistence logic actually ends up, you might benefit from looking up repositories as approach to streamline the API, that gets exposed to where your "application logic" is actually done.

PHP inheriting or compositing from multiple storage interfaces/objects

I have a situation where I need to abstract with storage functions, and to have multiple database adapters.
However I'm relying on external vendors who also have multiple database adapters for their libraries.
I'd like to create a single adapter be it MySQL that inherits the functions of the corresponding MySQL adapters from the external vendors. I can dependency inject this adapter into my own libraries and the external libraries that depend upon adapters to function.
Of course PHP doesn't have multiple inheritance, so I did some research and came up on composition.
Would compositing multiple database adapters into a single database adapter be a good practice? Furthermore would this composed object work, if it implemented an interface that extends from the corresponding interfaces of the external vendors?
For example imagine having:
External1\StorageInterface
External1\MySQLAdapter
External2\StorageInterface
External2\MySQLAdapter
Internal\StorageInterface
Internal\MySQLAdapter
Now: Internal\StorageInterface extends External1\StorageInterface, External2\StorageInterface
Then: Internal\MySQLAdapter implements Internal\StorageInterface
Then: Internal\MySQLAdapter compositions External1\MySQLAdapter and External2\MySQLAdapter
On a side note, how should the compositing take place? Via __call or reimplementing the function names, and simply calling the child objects? Which one satisfies the interface constraints?
One more question would be, how does one deal if in the case that different adapters have the same function name creating conflict? Would the adapter pattern work?

Globally available database connection without using Global/Singleton

I'm creating a new PHP application and want to make sure I get the ground work right to save any future problems. I know my application will have more than one class that will need a database connection (PDO) and after a long time scouring the internet i can't find a definitive solution.
I like the singleton design pattern personally, but there are a lot of people out there that say singletons in general should be avoided at all costs. These people, however, don't give a specific solution to this problem.
I understand that an application may need more than one database connection but could i not create a singleton that contained each required DB connection (i.e. DB::getInst('conn1')->query(); )?
Is it a case of having to pass round the PDO (or PDO wrapper) object to every class that may need it? I've done this before found it annoying keeping track of it.
I personally thing a singleton (or a multiton, if you need several DB connections) is fine for such an usage.
But if you do not want to use it, you should then take a look at the Registry pattern.
This way, you can have your database class instance(s) available for all your application's classes, without having to pass an additional parameter each time (which is very ugly, IMHO).
but could i not create a singleton that contained each required DB connection (i.e. DB::getInst('conn1')->query(); )?
you can, it's called multiton pattern

Creating a Simple "ORM/ActiveRecord" Pattern

I am not sure what I'm doing is called ORM or Active Record Pattern.
I have an Entity base class that entities/database tables will inherit. These classes will have methods like
find
findBy
findAllBy
insert
update
delete
Getters & Setters for column data (eg. name, title, etc) via magic methods
Problem now is how do I create a database connection?
Dependency Injection - sounds complicated ...
Use a global variable, that these classes will expect to be set? - Doesnt sound right
Have a base class that Entity inherit that contain all database connection info? - doesnt sound right either
Maybe I am doing it wrong? I am open to any ideas, preferably simple for a start. I am wanting to create a simple framework for a start (not using Doctrine for example), it will give me a foundation on how such framework works. Also if its a small project, using a big framework may over-complicates things
There isnt really much thats simple about what youre attempting. Its complex thing :-)
You need to have some kind of basic entity manager and/or table class which usually holds the reference to the DB connection (or some sort of object that wraps it). All the Entity's then pass themselves to the manager when their save or delete methods are called and the manager will work out the query needed to modify the db.
You can either inject this manager, or make it a singleton and have your classes fetch it when instantiated for example.
If i were you i would check out PHP Objects Patterns and Practices by Matt Zandstra. It goes into all these patterns with some basic implementation examples.

Categories