I have override a node.tpl and need some results from db using a query generated by views.
Here is the code which i used:
<?php $res = db_query("SELECT node.nid AS nid, node.title AS node_title FROM node node LEFT JOIN content_field_is_popular node_data_field_is_popular ON node.vid
= node_data_field_is_popular.vid WHERE (node.type in ('article_thisweekend')) AND (UPPER(node_data_field_is_popular.field_is_popular_value)
= UPPER('yes'));");
foreach($res as $reco){
print ($reco->nid);
}
?>
But I am not getting any results.
What I am missing?
Thanks
Matt V. has good advice in that you should try to separate the view templates from the sql query logic.
For this specific example though, you need to use db_fetch_object since $res just contains the
database query result resource
Instead of
foreach($res as $reco){
print ($reco->nid);
}
Do
while ($reco = db_fetch_object($res)){
print ($reco->nid);
}
It's generally best to avoid putting queries directly in your template files. It's best to separate logic and presentation.
Instead, use a module to generate the content you need and pass that along to the theme layer. In this case, if you're already using the Views module to generate the query, let Views run it for you and pass off the data to a page or block display.
Otherwise, to debug the query, try running the query independent of the code, through something like phpMyAdmin or "drush sqlq".
Related
I want to execute some query in Views/login.php
I have created database connection in Controller, but i need to execute some sort of queries in Views.
Not able to access it by $this->db->query("") in views, What is the good solution?
Note as DFriend mentionned in the comment of this question, this is a bad practice in an MVC pattern. Queries should always be runned in Models that passed data to the Controller which displays those data in Views.
However if you really want to execute a query into one view you have to initiate your database object before running queries.
$this->db does not exist in your case because your view does not extend a class that has a parameter callled $db
<?php
$db = db_connect();
$query = $db->query('YOUR QUERY');
//you get result as an array in here but fetch your result however you feel to
$result = $query->getResultArray();
?>
Here you create a database connection, then you run your query with the db object your created.
You can use the query builder from within a view or any other function by first creating an instance of the database connection by loading the class first $this->load->database() which will give you access to build your queries using the database object as $this->db->query("YOUR RAW QUERY"). Therefore you might do something like
<?php $this->load->database();
$q = $this->db->query("SELECT * FROM users");
$r = $q->result(); // returns an object by default
?>
Note: it is not good practice to execute outside your models so only do if you must.
I'm able to generate query for multi inserts or update thanks to pg-promise helpers but I was wondering if I could follow the advice of the author and put all queries outside of my javascript code (See here https://github.com/vitaly-t/pg-promise/wiki/SQL-Files and here : https://github.com/vitaly-t/pg-promise-demo).
When I use the insert helpers, the return query looks like :
INSERT INTO "education"("candidate_id","title","content","degree","school_name","start_date","still_in","end_date","picture_url") VALUES('6','My degree','Business bachelor','Bachelor +','USC','2018-05-15T02:00:00.000+02:00'::date,false,null::date,null),('6','Another degree','Engineering','Master degree','City University','2018-05-15T02:00:00.000+02:00'::date,false,null::date,null)
The idea is that I don't know how many inserts I want to do at the same time, so it has to be dynamic.
The following code doesn't work as I'm passing an array of object instead of an object :
db.none(`INSERT INTO "education"("candidate_id","title","content","degree","school_name","start_date","still_in","end_date","picture_url")
VALUES($<candidate_id>, $<title>, $<content>, $<degree>, $<school_name>, $<start_date>, $<still_in>, $<end_date>, $<picture_url>)`, data)
This code spreads the object but is still not correct to make a proper query :
db.none(`INSERT INTO "education"("candidate_id","title","content","degree","school_name","start_date","still_in","end_date","picture_url")
VALUES($1:list)`,
[data])
Any idea ? Is it at least possible or in the case where I don't know how many records I want to insert in advance I have to call pgp.helpers everytime ?
You confuse static and dynamic SQL. SQL files are there for SQL queries that are mainly static, i.e. you still can inject dynamically a lot, but when most of the query is dynamic, there is no longer any point putting it into an SQL file.
And the helpers namespace is there for dynamic queries only. So you are asking about two separate things, to join things that do not need to be joined.
I am a newbie in ModX, trying to insert to database but always failed. This is my insert script :
<?php
define('MODX_CORE_PATH', '/aocore/');
define('MODX_CONFIG_KEY','config');
require_once MODX_CORE_PATH . 'model/modx/modx.class.php';
$host = 'localhost';
$username = 'asdsadsada';
$password = 'dsadsadsada';
$dbname = 'sadsadsadsadas';
$port = 3306;
$charset = 'utf8';
$dsn = "mysql:host=$host;dbname=$dbname;port=$port;charset=$charset";
$xpdo = new xPDO($dsn, $username, $password);
echo $o = ($xpdo->connect()) ? 'Connected' : 'Not Connected';
$results = $xpdo->query("insert into table_name (name,email) VALUES ('".$_POST['name'].",".$_POST['email']."')");
$stmt = $modx->prepare($results);
$stmt->execute();
?>
Please help, totally stuck here.
Thanks
Without seeing much of your database structure let alone any error log info it's very hard to debug/test your code because we can't reproduce anything.
By the looks of it you are not using objects. You may want to concider using your own schema and inserting the given records as objects in the DB. Have a look at this guide for more information on creating custom database tables in MODX.
Please make sure you're sanitizing the input that is being saved into the database with functions such as strip_tags() and htmlspecialchars() in order to prevent XSS and other injection attacks. Also make sure you are using prepared statements.
By looking at the code however i can see that you are executing the query() function which is meant for querying the database (retreiving database records). If you want to execute SQL statements such as "INSERT" you will need to use the exec() function.
Example:
$xpdo->exec("INSERT INTO `table_name` (`name`,`email`) VALUES ('".htmlspecialchars(strip_tags($_POST['name'])).",".htmlspecialchars(strip_tags($_POST['email']))."')");
If you are not going to be using MODX objects you may find it easier to use PHP's PDO interface with prepared statements.
Well, if it is not too late. You didn't share the exact problem but I see something strange in your code:
...VALUES ('".$_POST['name'].",".$_POST['email']."')");
If the values from POST array get into the string, you have
...VALUES ('John,mail#mail.com')");
John,mail#mail.com' is a single value where as there should be two values for name and email. So, try to put ' inside your query like
...VALUES ('".$_POST['name']."','".$_POST['email']."')");
I wrote a transformation in xquery which unquotes an XML-String and inserts a element with its content. This works fine.
I need to create a collection dependant on the root element of this element as well. I can't do this on new documents as xdmp:document-add-collections() is not working. How do I add the collection to new Documents in transformations?
Here my ServerSide xQuery Code:
xquery version "1.0-ml";
module namespace transform = "http://marklogic.com/rest-api/transform/smtextdocuments";
import module namespace mem = "http://xqdev.com/in-mem-update" at '/MarkLogic/appservices/utils/in-mem-update.xqy';
declare function transform(
$context as map:map,
$params as map:map,
$content as document-node()
) as document-node()
{
let $uri := base-uri($content)
let $doccont := $content/smtextdocuments/documentcontent
let $newcont := xdmp:unquote($doccont)
let $contname := node-name($newcont/*)
let $result := if ( exists($content/smtextdocuments/content))
then mem:node-replace($content/smtextdocuments/content, <content>11{$newcont}</content>)
else mem:node-insert-after($doccont, <content>{$newcont}</content>)
let $log := xdmp:log($content)
return (
$result,
xdmp:document-add-collections($uri, fn:string($contname)),
xdmp:document-remove-collections($uri, "raw")
)
};
The script ist running with the java api (4.0.4) create methode via parameter ServerTransform transform. As per documentation the transformation script is running before the document is stored in the Database.
Its a new document; I need to transform the content and then create the collection.
I can see the document after the create, the content is available. Just the collection is missing. I can try xdmp:document-insert method but is it correct writing the document while create is running?.
The transform mechanism of the Java API / REST API takes responsibility for the document write. At present, there's no way for the transform to supply collections to the writer. That would be a reasonable request for enhancement.
The transform shouldn't attempt to write the document, because the writer would also attempt to write the same document.
One alternative would be to transform the document in Java before writing it and specify the collection as part of the write request.
Another alternative would be to rewrite the transform as a resource service extension, implement the write within the resource service extension, and modify the Java client to send the document to the resource service extension.
Depending on the model, a final alternative might be to use a range index on an element within the document to collect documents into sets instead of using a collection on the document.
Hoping that helps,
What do you mean by "new documents"? Is the document already inserted into the MarkLogic database at the time you are adjusting the collections of it? If not, you may want to modify your return to ($result, xdmp:document-insert($uri, $result, xdmp:default-permissions(), fn:string($contname)) ) for that case.
Otherwise, can you edit your question to share the error or problem more specifically you are facing?
It is a pity that REST transforms do not allow this, like MLCP transforms do. Until changed you have the options drawn by ehennum, or you can consider delaying adding of collections to a pre- or post-commit trigger. It takes some overhead, but it sometimes makes perfect sense to do something like that in a trigger, since it makes sure it is always enforced, and a good place to do content validation, audit logging, and things like that as well.
HTH!
I am using Linq to NHibernate.
I have a following test case :
[TestMethod]
[DeploymentItem("hibernate.cfg.xml")]
public void Category_Should_GetAllByLinq()
{
// Arrange
IRepository<Category> repo = new CategoryRepository();
//Act
IList<Category> list = repo.GetListByLinq();
//Assert
Assert.IsTrue(list.Count > 0);
}
and also I have following code in CategoryRepository class :
public IList<Category> GetListByLinq()
{
ISession session = NHibernateHelper.OpenSession();
// When following statement is executed, How to check converted real sql query?
var query = from c in session.Linq<Category>()
select c;
return query.ToList();
}
My question is that once linq to nhibernate statement is executed, How to check real converted sql query? any method?
I know I can use SQL profiler, However I'd like to use Mock object in test case so I don't want see it in any Database related method.
You can use the NHibernate Profiler to do so, see this post for details on how to setup programmatic integration:
http://ayende.com/Blog/archive/2009/12/13/uumlberprof-new-feature-programmatic-integration.aspx
Another option, slightly more complicated, is to listen to the NHibernate.SQL logger and process its results. It gives you the information, but you would need a bit of parsing and it won't give you the sessions information
Good question.
I think the best way to assert the SQL generated would be to use IInterceptor and hook into OnPrepareStatement.
Or if it is ok for you to just see the SQL statements in the Output window during debugging you can just enable show_sql option.
Have you tried NHiberate Profiler? It should be what you are looking for.