Creating full text index for several columns without query builder in Laravel migration - laravel-9

Experienced a need of creating full text index for several columns without using query builder in Laravel 9.0 to make decision clearer, however all answers or tips were either for one/two columns or with query builder.
Tips and tutorials didn't work for me as I had 6 columns to create this index and that led to an error :
SQLSTATE[42000]: Syntax error or access violation: 1059 Identifier name 'table_column1,column2,column3,col...' is too long
So my code was:
class AddFulltextIndexes extends Migration
{
private array $fields = [
'column1',
'column2',
'column3',
'column4',
'column5',
'column6'
];
public function up()
{
Schema::table('invoice_cds', function (Blueprint $table) {
$table->fullText($this->fields);
});
}
}

For those who found themselves in similar situation there is an exit:
Laravel allows to create indexes passing the index name as a second parameter, so I changed one line and migration started to work:
$table->fullText($this->fields, 'table_full_test_indexes');

Related

Laravel adding new comment to column of an existing table

I want to create a new migration to update the comment of a column. For the migration I think the command $table->tinyInteger('role')->default(2)->after('ID')->comment("new comment")->change(); in up() and $table->tinyInteger('role')->default(2)->after('ID')->comment("old comment")->change(); in down() function respectively. But I am getting an error Unknown column type "tinyInteger" requested. I can update the comment in my DB directly but it defeats the purpose of migration if I do this. Also, if I update the local, I also need to update the staging and production.
How should I proceed?
only need to do it in up method
public function up()
{
Schema::table('users', function (Blueprint $table) {
$table->tinyInteger('role')->default(2)->after('ID')->comment("new comment")->change();
});
}

Stored procedures in HQL

How can I write stored procedure or function in HQL? Is it possible? I haven't found any information about it.
The problem is that my app works with several Databases(Oracle, MSSQL, PostgreSQL) and I need to count Levenshtein distance in my query. Can I do it without writing 3 native SQL functions and queries for each database?
You can try to encapsulate discrepancy between Levenshtein function names in different databases in hibernate dialect. Below I will provide an example for Oracle and PostgreSQL. (I did not work with MSSQL)
The extended Oracle dialect:
public class MyOracleDialect extends Oracle12cDialect
{
public MyOracleDialect()
{
super();
registerFunction( "levenshtein", new SQLFunctionTemplate( StandardBasicTypes.INTEGER, "UTL_MATCH.EDIT_DISTANCE(?1,?2)" ) );
}
}
The extended PostgreSQL dialect:
public class MyPostgreSQLDialect extends PostgreSQL95Dialect
{
public MyPostgreSQLDialect()
{
super();
registerFunction( "levenshtein", new SQLFunctionTemplate(StandardBasicTypes.INTEGER, "levenshtein(?1, ?2)"));
}
}
And now you can use the levenshtein function in your HQL.
List<Integer> result = session.createQuery(
"select levenshtein(word1, word2) from TestEntity",
Integer.class
).getResultList();
P.S. I have faced with the following problem for PostgreSQL:
If the extension fuzzystrmatch was installed for the particular schema TEST_SCHEMA:
SQL> create extension fuzzystrmatch;
then you should specify this schema in the connection url:
<property name="hibernate.connection.url">jdbc:postgresql://localhost:5432/postgres?currentSchema=TEST_SCHEMA</property>
otherwise you will get an exception:
org.postgresql.util.PSQLException: ERROR: function levenshtein(character varying, character varying) does not exist. No function matches the given name and argument types. You might need to add explicit type casts.

beego QueryTable table name: `cpes` not exists

I have this pice of code in beego:
o := orm.NewOrm()
qs := o.QueryTable("cpes")
and I now that beego connects well with the database, and the database have the 'cpes' table, but I keep getting an error becouse beego don't find the table.
¿How can I debug this further?
You must define model Cpes and register model 'cpes'.
Like:
type Cpes struct {
Id int
}
func (u *Cpes) TableName() string {
// db table name
return "cpes"
}
func init() {
orm.RegisterModel(new(Cpes))
}
I had the same problem. In my case, it was because I didn't register the model.
orm.RegisterModel(new(Member), new(Bank), new(Queue), new(Payment))
Make sure you registered all your models with beego.
The error message should have been more explicit though
I had the same problem a few weeks ago. The answer is in how Beego is translating the table name in the ORM.
The quick fix is to use
qs := o.QueryTable(new(cpes))
Where cpes is the model struct.
If you want to see this in action or this solution does not work for you try using the bee generate api command on your database. This will give you the models in a pre-made fashion as well as a bunch of code examples on how to use them.
Best of luck!

Search related data in different data base

I use yii2 to build one app which need to connect some tables. I can join them simply and search for data in related fields. I am doing it by adding the connection like this>
public function getNextTab()
{
return $this->hasOne(NextTab::className(),['id' =>'id_nexttab']);
}
and ask for the data in search model using like this ->
->where ('id'='ok') ->
->joinWith('nextTab')
->joinWith('nextTab.nextTab1')
->joinWith('nextTab.nextTab1.nextTab2');
My problem is when I try to do this with tables from different database. The query is give me error like
SQLSTATE[42S02]: Base table or view not found:
any tips how to pass it? or how to do other way of connection to have the data.
Joining tables from different databases may not be supported by your RDBMS (PostgreSQL for example). But if supported (MSSQL, MySQL) then table names should be prefixed with database name (and schema if needed). You can achieve this in Yii2 using {{%TableName}} syntax in tableName() function.
public static function tableName()
{
return '{{%table_name}}';
}
But be careful with joining tables from different databases if they are located on different servers -- this can be very slow.
If you just want to get related data (joined tables are not used in WHERE) then use with() instead of joinWith(). This will be executed as separate query with IN statement. In most cases this way has a better performance and no problems with different sources (and even different DBMS).
->with('nextTab', 'nextTab.nextTab1', 'nextTab.nextTab1.nextTab2')
Configure your second database component in the application's config.
Override the getDB() function in your ActiveRecord Model to return the second DB component.
This will attach your Model to the secondary DB and allow you to query from the table in secondary DB.
Config sample:
'components' => [
'db2' => [
'class' => 'yii\db\Connection',
'dsn' => 'mysql:host=localhost;dbname=db2',
'username' => 'hello',
'password' => 'world',
],
],
getDB() function override sample:
class Tab extends ActiveRecord
{
public static function getDb()
{
// use the "db2" component
return \Yii::$app->db2;
}
}
Good Luck!

Laravel dynamic route from MySQL

I am trying to generate routes from one template "tuning.blade.php"
I have a DB with 250 rows I would like to dynamically create 250 routes with one route or one controller.
I want to be able to use these URLs
laravel.dev/tuning/(field from DB row 1)
laravel.dev/tuning/(field from DB row 2 and so on)
I want to put the DB requests in tuning.blade.php so that this template can display all 250 rows using 250 different URLS
I have tried to use the first example from Laravel Docs
class UserController extends BaseController {
/**
* Show the profile for the given user.
*/
public function showProfile($id)
{
$user = User::find($id);
return View::make('user.profile', array('user' => $user));
}
}
Route::get('user/{id}', 'UserController#showProfile');
I also got some interesting search results from http://forumsarchive.laravel.io/viewtopic.php?id=9010
But alsas I always end up with a notfound exception
But I am unsure what to put in my tuning template to display anything at all. my Tuning template reside in app/views/home/tuning.blade.php
Currently I have got the error "Symfony \ Component \ HttpKernel \ Exception \ NotFoundHttpException"
Can anyone put me in the right direction of where I can find a resource to help me understand?
You said you want to be able to use these URLs:
laravel.dev/tuning/(field from DB row 1)
laravel.dev/tuning/(field from DB row 2 and so on)
You can do this by declaring a route like this:
Route::any('/tuning/{field}', 'TuningController#someMethod'); you may get/post
You shouldn't run sql queries from your view and if you want to really declare some dynamic routes for each fields from your database then you may do id right from your routes.php file, for example, assume that you have a table named tunings and that table contains some fields including id, name and some others. Now, to declare routes individually for each routes dynamically using the tuning field of table tunings you may create a method in your TuningController, something like this:
class TuningController extends baseController {
// other methods...
public function registerTuningRoutes()
{
$tunings = Tuning::all(); // Assume that you have a model Tuning
// Or you may use this instead
$tunings = DB::table('tuning')->get();
// Now loop all tunings and declare routes
foreach($tunings as $tuning) {
$url = '/tuning/' . $tuning->name;
$route_name = 'tuning.' . $tuning->name;
Route::any($url, $route_name); // You may use get/post
}
}
public function TuningMethod($tuning = null)
{
// $tuning will contain the current tuning name, check
dd($tuning);
}
}
Now in your routes.php file use something like this:
Registers route for each tuning name in database
App::make('TuningController')->registerTuningRoutes();
From your terminal/command prompt check the routes by running following command:
php artisan routes
But, I think, you don't need to do this, only one route is enough as I mentioned earlier in my answer.