Dotrine 1.2 中的用户定义例程?

发布于 2024-11-14 12:49:54 字数 249 浏览 3 评论 0原文

我必须为我的 MySQL 数据库编写一个用户定义的例程(计算距离函数)。

  1. 是否可以在 yaml 架构文件中定义它?

在终端 mysql-client 中定义例程后,一切正常,直到“doctrine build-all-reload” - 函数被删除,这是可以理解的;

  1. 如何附加每次运行“build-all-reload”时执行的 sql 脚本?

对不起我的英语。 汤姆

I have to write an user-defined routine for my MySQL database (calculating distance function).

  1. Is it possible to define it in yaml schema file?

After defining routine in terminal mysql-client everything is ok until 'doctrine build-all-reload' - function is dropped, which is understandable;

  1. How can I attach a sql script which will be executed everytime I run 'build-all-reload'?

Sorry for my English.
Tom

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

原野 2024-11-21 12:49:54

我找到了一个解决方案(在某种程度上与您的解决方案类似),方法是将以下几行添加到我的doctrine.php文件中:

$q = file_get_contents('../configs/sql/routines.sql');
$conn = Doctrine_Manager::connection();
$conn->execute($q);

现在,每次我执行 ./doctrine build-all-reload 都会执行以下脚本:

DROP FUNCTION IF EXISTS DIST;
CREATE FUNCTION DIST (fi11 DOUBLE, ksi11 DOUBLE, fi22 DOUBLE, ksi22 DOUBLE)
  RETURNS DOUBLE
   DETERMINISTIC
    BEGIN
     DECLARE d DOUBLE;
     DECLARE fi1 DOUBLE;
     DECLARE fi2 DOUBLE;
     DECLARE ksi1 DOUBLE;
     DECLARE ksi2 DOUBLE;
     SET fi1 = PI()*(fi11)/180;
     SET fi2 = PI()*(fi22)/180;
     SET ksi1 = PI()*(ksi11)/180;
     SET ksi2 =PI()*(ksi22)/180;
     SET d = ACOS((SIN(fi1)*SIN(fi2))+(COS(fi1)*COS(fi2)*COS((ksi1-ksi2))))*6371.0;
     RETURN d;
    END;

这个解决方案可能并不优雅,但是对我有用:)
我不打算从 MySQL 更改数据库。

之后,我可以在 Doctrine 查询中使用 DIST 函数,它的工作速度比使用标准内置函数实现快几倍,而且更短。

$q->where('DIST(a.lan, a.lon, b.lan, b.lon) < ?', array(2.0));

而不是

$q->where('ACOS((SIN(...)... ... wrrrr ;-P ))*6371.0 < ?', array(2.0));

感谢您的帮助。

I found a solution (similar to yours in some way) by adding following lines to my doctrine.php file:

$q = file_get_contents('../configs/sql/routines.sql');
$conn = Doctrine_Manager::connection();
$conn->execute($q);

Now, everytime I execute ./doctrine build-all-reload a following script is executed:

DROP FUNCTION IF EXISTS DIST;
CREATE FUNCTION DIST (fi11 DOUBLE, ksi11 DOUBLE, fi22 DOUBLE, ksi22 DOUBLE)
  RETURNS DOUBLE
   DETERMINISTIC
    BEGIN
     DECLARE d DOUBLE;
     DECLARE fi1 DOUBLE;
     DECLARE fi2 DOUBLE;
     DECLARE ksi1 DOUBLE;
     DECLARE ksi2 DOUBLE;
     SET fi1 = PI()*(fi11)/180;
     SET fi2 = PI()*(fi22)/180;
     SET ksi1 = PI()*(ksi11)/180;
     SET ksi2 =PI()*(ksi22)/180;
     SET d = ACOS((SIN(fi1)*SIN(fi2))+(COS(fi1)*COS(fi2)*COS((ksi1-ksi2))))*6371.0;
     RETURN d;
    END;

This solution is maybe not elegant, but works for me:)
I am not planning to change database from MySQL.

After that i can use DIST function in Doctrine Queries and it works several times faster than using standard build-in-function implementation, and is much shorter.

$q->where('DIST(a.lan, a.lon, b.lan, b.lon) < ?', array(2.0));

istead of

$q->where('ACOS((SIN(...)... ... wrrrr ;-P ))*6371.0 < ?', array(2.0));

Thanks for your help.

兔小萌 2024-11-21 12:49:54

我认为这可以通过教义行为来完成。

遵循我自己的博客文章 http://darrendev.blogspot。 com/2010/03/creating-doctrine-custom-behaviour-part.html,但使用 setUp() 而不是 setTableDefinition(),您可以使用此创建一个文件代码:

class DarrenTestable extends Doctrine_Template{
    public function setUp(){
        ...
    }
}

... 是您可以影响表创建的地方。您可以在 yaml 文件中附加此行为:

ActsAs:
    DarrenTestable

可能有一种简洁的学说方式可以在“...”部分中完成您需要的操作,但是在浏览了一下源代码之后,我不确定,所以,这在你的应用程序的生命周期中只完成一次,我个人会在 Doctrine 之外完成这一切:

  1. 连接到 MySQL
  2. 发送 SQL 来创建你的
  3. Disconnect

函数 另一种方法是用 PHP 编写距离计算函数作为教义行为(扩展 Doctrine_Record_Listener);作为奖励,您可以获得数据库可移植性。但它将代码与 Doctrine 联系在一起,因此其他应用程序无法像使用 mysql 例程那样使用该函数。

I think this can be done with Doctrine behaviours.

Following my own blog post http://darrendev.blogspot.com/2010/03/creating-doctrine-custom-behaviour-part.html, but using setUp() instead of setTableDefinition(), you create a file with this code:

class DarrenTestable extends Doctrine_Template{
    public function setUp(){
        ...
    }
}

The ... is where you can influence table creation. You attach this behaviour in the yaml file with:

ActsAs:
    DarrenTestable

There may be a neat doctrine-way to do what you need in the "..." part, but after poking around the source code a bit I'm not sure and so, as this is only done once in the lifetime of your application, I'd personally do it all outside Doctrine:

  1. Connect to MySQL
  2. Send the SQL to create your function
  3. Disconnect

P.S. Another approach is to write your distance-calculating function in PHP as a doctrine behaviour (extend Doctrine_Record_Listener); as a bonus you get database portability. But it ties the code to Doctrine, so other applications cannot use the function the way they can with an mysql routine.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文