Database cleaning in Symfony2 tests - symfony

Is there a standard way of cleaning your database before (or after) each test when you're testing with Symfony2/PHPUnit? There seems to be a standard, obvious way to do this in Rails but I haven't found an analog in the Symfony community.

You can either purge the tables with Doctrine's data purger or rebuild the schema before every test.
Purger is part of data-fixtures package: https://github.com/doctrine/data-fixtures
I once wrote a KernelAwareTest which rebuilds the schema before every test: https://gist.github.com/1319290

If you are using the LiipFunctionalTestBundle, database is purged on each loading of fixtures. If you don't need any fixtures loaded, you can still call $this->loadFixtures(array()); ("load no fixtures") to have database purged.

Related

Equivalent of Laravel Seeders on Symfony?

I'm developing a web site with Symfony. I'm new on this framework. Before i used Laravel 5.0 and I need to have a database with rows.
I create my db with command prompt but now I don't find how to seed it.
There is a equivalent of Laravel seeders on Symfony?
No. Seeding was a feature added by Laravel. You’ll need to use a third-party package to load seeds/fixtures into your application: http://www.sitepoint.com/data-fixtures-symfony2/
All the answers here are a bit outdated and this question is the first result on google so for future readers:
Since Symfony 3 there is an official bundle for this very purpose
Installation: composer require --dev doctrine/doctrine-fixtures-bundle
Then write your fixtures in src/DataFixtures and run php bin/console doctrine:fixtures:load
Try this package https://packagist.org/packages/evotodi/seed-bundle. Looks like it's what you need.
Their readme
Symfony/Doctrine Seed Bundle
Used to load/unload seed data from the database. Example would be to load a table with a list of states and abbreviations, or populate the users table with initial admin user(s). Unlike the DoctrineFixturesBundle which is mainly for development this bundle is for seeding the database before the initial push to production.

How a bundle can provide "default data" i.e. pre-filled tables in Symfony 2?

I think I've a good understanding of Symfony and how bundle works.
However I've never found how to solve a simple problem: make a reusable bundle that provides data like tables/Doctrine entities pre-filled with (i.e.) all country names in the world, all provinces of Italy, tax rates history in England and so on.
Of course the purpose is to provide forms, services and controllers relying on this data source, without the need to copy and paste tables and entities across projects.
How would you do that?
Data fixtures IMHO are not an option because an obvious reason: you are going to purge your database while it's running.
A custom command reading from a static data-source (json, YAML) and performing inserts/updates?
First step is declaring a Doctrine entity in your Bundle. I think you should create DataFixtures to populate your datas into db.
You maybe should consider to use Seeds instead of Fixtures.
Fixtures are fake datas, used to test your application
Seeds are the minimal datas required for your application to work.
Technically, these are exactly the same thing, you declare it under the "DataFixtures/" folder and you import them with the "doctrine:fixtures:load" command.
You can create a folder "Fixtures/", and a folder "Seeds/" under the folder "DataFixtures", then load your seeds with the command
php app/console doctrine:fixtures:load --fixtures=/path/to/seeds/folder --append
It was suggested in the comments that it may be safer, especially in production environment, to create a custom Symfony2 command to force the "--append" mode. Without this mode, your database will be purged, and you could loose your production data.
This answer assumes you're using composer to install your bundles (and you really exclude fixtures as an option).
What you can do, is make an SQL export of the data you want, and make sure it uses INSERT IGNORE INTO, and get the correct unique constraints.
Then you save that file somewhere in your bundle, in a "data" or "fixtures" folder.
so your path to that file will be like:
"vendor/company/epicbundle/data/countries.sql"
What you then can do, is add post-insert and post-update commands in your composer.json, that looks like this:
"post-install-cmd": [
"php app/console doctrine:query:sql \"$(cat vendor/company/epicbundle/data/countries.sql)\""
]
If you only want it to run on install, you only add it there, if you sometimes update the sql file, you also add it to the post-update-cmd.
Please note that this solution only works if people don't temper with the table names, otherwise the queries will fail.
If you want a more save/stable solution, you can write your own post-install script in Symfony that uses the entity manager, and there you can use, for example, a csv file, and insert/update it row by row.
Basically, anything you could implement would surely rely on persistence mechanisms used in your ORM/ODM/whatever. So, you'll end up implementing a typical fixture loading mechanism, at least partially: you'd execute code that saves some provided data; if it's serialized you'd do XML/JSON/YAML parsing (but this is just a technicality) and persist the results into the database.
Thus, it's not bad to stick with Doctrine Fixtures. They are programmable and extensible (you can even fetch your data from the web upon loading).
As stated in #paul-andrieux's answer, if you are worried about data loss (e.g. your bundle's seeds are loaded when the end user's DB is already up), you should use doctrine:fixtures:load --append and let the constraints do their job (like, in a country names table you'd have a unique constraint on country name or even a 'slug') so that inserting duplicate rows silently fails inserting a single entity, in case if your bundle has updated the country list, and the end user had a previous version.
If you really worry about your end users' data you could write a wrapper for the doctrine:fixtures:load command that would have the --append flag always on and register it as a separate command. (You could run needed migrations there, too)
#lxg's hard-coded IDs problem is solvable, too. Try using natural keys where applicable (e.g. the countries table would have a slug primary key that would be great-britain for Grean Britain). This way your searches would be pretty easy: $em->find('\MyBundle\Country', 'great-britain');. If you cannot come up with a natural key, then maybe the entity is not really needed for the end user.
UPD. Here's an article that could be useful: http://www.craftitonline.com/2014/09/doctrine-migrations-with-schema-api-without-symfony-symfony-cmf-seobundle-sylius-example/
Generally speaking, the bundle embedded the entities that will be loaded via the ORM/ODM using their built-in commands (like doctrine:schema:update, doctrine:migration:diff, ...) and provides a custom command that load the required fixtures using the ODM/ORM
This command can read the fixtures in multiple way (parsing yaml, xml, raw sql, dql, ...), it is just a matter of taste. Tones of bundles, parser, ... exist for those tasks.
In your documentation, you just have to state in a clear way that the developer must run this command after your bundle installation and schema update.

Is there any way to programmatically handle data fixtures with schema migrations?

I'm learning Symfony2 and have just learnt about doctrine:migrations. It sounds like a great way of 'versioning' the database schema and deploying new schemas in production.
I've also been reading about data fixtures for development. Is there any way to version these in a similar fashion as the schema migrations, or should I just use GIT?
Migrations' versions have to be kept under version control. If GIT is your SCM, then it's fine.

How to find the use of default tables available in drupal

How can I able to find the usage of default tables available in drupal.
Is there any documentation available?
For example: there is a table called node. I need to know what is the usage of it and how it acts.
Any suggestions or answers will be helpful and grateful.
Your question is not very clear (the term "usage" is quite ambiguous), but you could install the Devel module. After setting it up it will show, for every page loaded (home page included), which SQL queries are run.
Every module can add tables to the database. A default Drupal install uses core modules, either required ones or those installed as dependencies of the default installation profile. These modules install their own tables.
Each module declares its tables in its implementation of hook_schema. The Schema module use the information from the implementations of this hook to provide a schema documentation.
Most of the time, you shouldn't directly access the database but use the API provided by the modules managing the data. Tables are usually considered private for their modules. New release of a module may change its schema in an incompatible way. Using API is much safer. Unfortunately, sometimes database access is the only option. In these cases, implementation of a data access layer between your code and the database is advised.

How to get a compile time error when the database schema changes?

What method do you use to get a compile time error when the database schema changes occur in an ASP.NET project?
For example, if you have a GridView bound to a DataSource, I can only get runtime errors when a schema change occurs, not a compile time error. Intellisense works fine on the code behind using datasets, LINQ, etc, but I cant seem to get a compile time error on an ASP.NET page when I change the schema.
Any advice?
Create a unit test that verifies the correctness of you data access layer, and make sure it covers all your DB-related code. Not everything can be caught at compile time...
One way I can think of easily achieving this behavior would be to databind to a dynamic DAL. There are some tools that can help do this DAL generation, I'd recommend taking a look at SubSonic.
Once you have something like SubSonic in place you can bind to the resulting business objects. These business objects will automatically change in the case of a schema change in the database and this will break your binding code which will result in a compile time error.
Update
Assaf's recommendation to use Unit Tests is also a good idea. It doesn't solve your stated problem but it is definitely something that should be in place and is a great tool for flagging these type of problems.
We use a modest system (xml to c++) to create schemas from an independent description, this system also creates names for tables and columns that we use inside the code, when there is a change in the schema the names change, as the names we originally used are not there anymore and the compiler will flag an error.
You could probably configure a lot of the DAO generation tools to do something similar.
One solution would be to version your database and map an application build to a specific version (maybe in a properties file). In the entry point of your app, you can compare the expected version to the actual version and handle the error accordingly.
I'm not sure whats the equivalent in ASP.net of Migrations in Rails or dbdeploy in Java for versioning your database. But any DB versioning tool that makes schema changes incremental and versioned and tracks the version in a Version table will suit the purpose.
But if you want a compile time error while building your app, you might as well upgrade your schema to the latest version as part of your build process, avoiding the possibility of schema changes in the first place.

Resources