How to get all the columns name of a DB table in SilverStripe - silverstripe

I am new to SilverStripe and I want to perform a simple query using SilverStripe functions (I don't want to use raw SQL). I want to get all the columns' names of the product table.
So far, I didn't find anything useful in the SilverStripe documentation. I appreciate any suggestion.

You have to understand that the Silverstripe $db (Data Model / ORM) and database columns are not always in sync. If you delete a $db attribute, the column will still exist in your database, but no longer in your ORM. Source
Assuming you want the current ORM-attributes, you can simply use, for a Dataobject $record:
$attributes = $record->toMap();
Even more attributes (even inherited attributes) can be collected by using the schema:
$schema = \SilverStripe\ORM\DataObject::getSchema();
$allFields = $schema->fieldSpecs($record);
$columns = array_keys($allFields);

Related

How to create a new table using Doctrine Query Language (DQL)?

I'm trying to create a importing system by using Symfony2.
A new table must be automatically created when a user imports a new dataset.
For example, if the user imports 3 datasets, we will have DataA, DataB, and DataC tables.
I have been searching on "How to create and insert data in DQL", However, it's written that DQL doesn't have Create and Insert queries - Only Select, Update, and Delete are allowed.
So, what is the good practice to achieve this approach? I have only an idea in my head which is to create a plain SQL query, I don't know if this is a good way in Symfony2 and Doctrine.
I think that it should be better if we could achieve this by using Object Relation Mapping, ORM. Is it possible?
Try to use next code in controller:
$conn = $this->get('database_connection');
$sql = "CREATE TABLE __tablename__";
$stmt = $conn->prepare($sql);
$stmt->execute();

Doctrine extension :: search entity by other field than ID

Using doctrine extension, when locale changes, searching an entity with, say ID=1, returns proper values for the current locale (stored in translations table), which is a great thing, but what if I need to search for entities by another field, like name or something..
Is there any way to get proper results using other entity field/property that ID?
Try use:
$query = $em->createQuery("SELECT pc FROM MyDomain\Model\ProductCategory pc WHERE pc.webName LIKE :name")
$query->setParameter("name", $name);
$query->getResult();

How do you join two tables in Doctrine2 using Query Builder if the table relationships are not setup?

I am currently using Symfony2 and Doctrine2 and am trying to join two tables together using query builder.
The problem I have is that all my annotated entities do not have the table relationships setup. I will at some point address this, but in the mean time I need to try and work round this.
Basically I have two tables: a product table and a product_description table. The product table stores the basic information and then I have a product_description table that stores the description information. A product can have one or more descriptions due to language.
I want to use query builder, so I can retrieve both the product and product_description results as objects.
At the moment I am using the following code:
// Get the query builder
$qb = $em->createQueryBuilder();
// Build the query
$qb->select(array('p, pd'));
$qb->from('MyCompanyMyBundle:Product', 'p');
$qb->innerJoin('pd', 'MyCompanyMyBundle:ProductDescription', 'pd', 'ON', $qb->expr()->eq('p.id', 'pd.departmentId'));
$query = $qb->getQuery();
$products = $query->getResult();
This gives me the following error:
[Syntax Error] line 0, col 71: Error: Expected Doctrine\ORM\Query\Lexer::T_DOT, got 'MyCompanyMyBundle:ProductDescription'
Can anyone point me in the right direction? I am up for doing it differently if there is an alternative.
Without having the relationships defined, I don't think you can join the tables. This is because when you use DQL, you're querying an object rather than a table, and if the objects are unaware of each other, you can't join them.
I think you should look at using a NativeQuery. From the docs:
A NativeQuery lets you execute native SELECT SQL statements, mapping the results according to your specifications. Such a specification that describes how an SQL result set is mapped to a Doctrine result is represented by a ResultSetMapping. It describes how each column of the database result should be mapped by Doctrine in terms of the object graph. This allows you to map arbitrary SQL code to objects, such as highly vendor-optimized SQL or stored-procedures.
Basically, you write raw SQL, but tell Doctrine how to map the results to your existing entities.
Hope this helps.

Join a Flat Table to an EAV Table with Magento?

I am trying to manke an Adminhtml Grid which joins a table that I made called "facility" to "customer_entity" and all of its attribtues.
I'm noticing that since my table is flat, and the model inherits fomr Mage_Core_Model_Mysql4_Collection_Abstract, I'm not able to use all the class_methods that I've seen as examples on the backend.
I've successfully been able to join my table to the customer_entity table doing the following:
$collection = Mage::getModel('facility/facility')->getCollection()
->join('customer/entity', 'customer_id = entity_id');
However, what I really need is just to get the customer name. Any help?
Customer names are not stored in one field, they are a combination of first, middle and last name; and depending on settings, a prefix and suffix too. The customer classes have methods for combining these for you.
$collection = Mage::getModel('customer/customer')->getCollection()
->addNameToSelect()
->joinTable('facility/facility', 'entity_id=customer_id', array('*'));
The joinTable method is part of EAV collections which is why you won't see it in the core MySQL4 based collections. The first parameter is not a literal table name but an entity table as described in your config.xml.
Generally I agree with the previous answer just some corrections to the syntax
$collection = Mage::getModel('customer/customer')->getCollection()
->addNameToSelect()
->joinTable('facility/facility', 'customer_id=entity_id', array('*'), null, 'right');
null part is a WHERE clause and the 'right' is the type of the join
Or maybe a better decision is:
$collection = Mage::getModel("facility/facility")->getCollection()->getSelect()->join('customer_entity', 'entity_id=customer_id', array('*'));

Importing legacy table to Drupal database

I have legacy database and tables that I would like to try to import in Drupal. Here's an example table structure :
Table : Projects
ProjectID
ProjectName
CountryID
TypeID
ProjectID is primary key, CountryID and TypeID are foreign keys which point to Countries and Type tables , respectively.
I think I would make a Projects content-type first, reflect the fields present in the legacy tables using CCK.. my only problem is to import the data.. Is there anyway to automate this?
Thanks!
If you can get the data into CSV/TSV format, Node Import should do the trick, and is geared towards site maintainers rather than developers.
The Migrate module handles importing from tables. Migrate has hooks for doing more complex imports, but you should be able to get your data simple enough that you don't need those hooks (which aren't very well documented) by creating a new table from a join of your existing tables. Something like this (untested):
CREATE TABLE combined SELECT * FROM Projects p
LEFT JOIN Country c ON c.CountryID = p.CountryID
LEFT JOIN Type t ON t.TypeID = p.TypeID
If you do decide you want to keep things more separated, with countries and types in separate content types, a coworker of mine wrote a pretty good tutorial on using migrate hooks.
Node import is fairly good if you just export the data as csv and import the foreign keys first. It works with complex fields like node references.
Otherwise you can write a basic module which goes through the database row by row and inserts the records into nodes. Some really basic pseudo code:
$node->title = $row['projectName'];
$node->type = 'project';
$node->country_field[0]['value'] = $row['country_name'];
if(save_node($node)) {
set_message('Imported node');
}
Drupal has database switching so you can switch between the databases.

Resources