Location>code7788 >text

ThinkPHP6 supports Kingbase to solve the problem of not being able to use model queries

Popularity:505 ℃/2024-08-01 17:45:05

Referring to many previous articles, finally only support Db::query native query, do not support thinkphp data model method, which is hard to accept in the actual project, specially share out the solution.

First, follow the process configuration as follows:

1. Preparation

First of all, make sure that PHP supports the Gold Warehouse database extension, you can go to the official website of Gold Warehouse to download and install the configuration (detailed configuration omitted ......).

Just check with the php -m command and show that there is a pdo_kdb. Note here that the version has to be >=10, otherwise an error will be reported.

2, the new gold warehouse database connenter class

Go into the ThinkPHP project directory under vendor\topthink\think-orm\src\db\connector\, copy as (based on pgsql modification), and modify the class name in the file to Kingbase.

/**
 * Kingbasedatabase driver
 */
class Kingbase extends PDOConnection

Find the protected function parseDsn(array $config): string method and modify the code under that method:

$dsn = 'pgsql:dbname=' . $config['database'] . ';host=' . $config['hostname'];
// Modify to:
$dsn = 'kdb:host=' . $config['hostname'] . ';dbname=' . $config['database'];

3. Add a new gold warehouse database builder class.

Go into the ThinkPHP project directory under the vendor\topthink\think-orm\src\db\builder\, copy as, and likewise modify the class name Kingbase in the file.

/**
 * Kingbasedatabase driver
 */
class Kingbase extends Builder

No other code changes are required.

 

configuration file

In all three places mysql is modified to kingbase:

return [
    // The database connection configuration used by default
    'default' => env('', 'kingbase'),

......

// Database connection configuration information
    'connections' => [
        'kingbase' => [
            // Database type
            'type' => env('', 'kingbase'), [ // database type => env('', 'kingbase'), [ // server address
            // Server address
            'hostname' => env('', 'localhost'), [ // database type 'type' => env('', 'kingbase'), // server address
            // database name
            'database' => env('', 'TEST'), // user name
            // User name
            'username' => env('', 'SYSTEM'), // password
            // Password
            'password' => env('', '123456'), // password
            // Port
            'hostport' => env('', '54321'), // database connection parameters
            // Database connection parameters
            'params' => [], // database connection parameters.
            // The database encoding is utf8 by default.
            'charset' => env('', 'utf8'), // Database table prefix.
            // Database table prefix
            'prefix' => env('', ''), // Database table prefix.

......

        // More database configuration information
    ], .
];

Here, and other articles about the program are the same, and now introduces the focus, the focus is on the execution of this sql statement, this statement is executed many times are unsuccessful, either prompted table_msg function does not exist, or some other error, and later in KStudio to create a separate function, in order to rule out the problem is solved.
Now we are sharing the creation statement of 3 functions, you need to go to the corresponding schema and create a new query for importing:

CREATE OR REPLACE FUNCTION public .pgsql_type(a_type  varchar )  RETURNS varchar AS
DECLARE
v_type  varchar ;
BEGIN
     IF a_type= 'int8' THEN
          v_type:= 'bigint' ;
     ELSIF a_type= 'int4' THEN
          v_type:= 'integer' ;
     ELSIF a_type= 'int2' THEN
          v_type:= 'smallint' ;
     ELSIF a_type= 'bpchar' THEN
          v_type:= 'char' ;
ELSE
          v_type:=a_type;
END IF;
RETURN v_type;
END

 

CREATE OR REPLACE FUNCTION public .table_msg(a_schema_name  varchar , a_table_name  varchar )  RETURNS SETOF tablestruct  AS
DECLARE
v_ret  public .tablestruct;

v_oid oid;

v_sql text;

v_rec RECORD;

v_key  varchar ;

BEGIN
    SELECT
    pg_class.oid  INTO v_oid
    FROM
    pg_class
INNER JOIN pg_namespace  ON
    (
        pg_class.relnamespace = pg_namespace.oid
            AND lower (pg_namespace.nspname) = a_schema_name
    )
    WHERE
    pg_class.relname = a_table_name;

IF  NOT FOUND  THEN
         RETURN ;
END IF;

v_sql =  '
     SELECT
           sys_attribute.attname AS fields_name,
           sys_attribute.attnum AS fields_index,
           pgsql_type(sys_type.typname::varchar) AS fields_type,
           sys_attribute.atttypmod-4 as fields_length,
           CASE WHEN sys_attribute.attnotnull THEN ' 'not null' '
           ELSE ' '' '
           END AS fields_not_null,
           sys_attrdef.adbin AS fields_default,
           sys_description.description AS fields_comment 
     FROM
           sys_attribute 
           INNER JOIN sys_class ON sys_attribute.attrelid = sys_class.oid 
           INNER JOIN sys_type ON sys_attribute.atttypid = sys_type.oid 
           LEFT OUTER JOIN sys_attrdef ON sys_attrdef.adrelid = sys_class.oid AND sys_attrdef.adnum = sys_attribute.attnum 
           LEFT OUTER JOIN sys_description ON sys_description.objoid = sys_class.oid AND sys_description.objsubid = sys_attribute.attnum
     WHERE
           sys_attribute.attnum > 0 
           AND attisdropped <> ATTISLOCAL 
ORDER BY sys_attribute.attnum' ;

FOR v_rec  IN EXECUTE v_sql LOOP
         v_ret.fields_name = v_rec.fields_name;

v_ret.fields_type = v_rec.fields_type;

IF v_rec.fields_length > 0  THEN
            v_ret.fields_length := v_rec.fields_length;
ELSE
            v_ret.fields_length :=  NULL ;
END IF;

v_ret.fields_not_null = v_rec.fields_not_null;

v_ret.fields_default = v_rec.fields_default;

v_ret.fields_comment = v_rec.fields_comment;

SELECT
    constraint_name  INTO v_key
FROM
    information_schema.key_column_usage
WHERE
    table_schema = a_schema_name
    AND table_name = a_table_name
    AND column_name = v_rec.fields_name;

IF FOUND  THEN
            v_ret.fields_key_name = v_key;
ELSE
            v_ret.fields_key_name =  '' ;
END IF;

RETURN NEXT v_ret;
END LOOP;

RETURN ;
END

CREATE OR REPLACE FUNCTION public .table_msg(a_table_name  varchar )  RETURNS SETOF tablestruct  AS
DECLARE
v_ret tablestruct;
BEGIN
FOR v_ret  IN SELECT *  FROM table_msg( 'public' ,a_table_name) LOOP
    RETURN NEXT v_ret;
END LOOP;
    RETURN ;
END

 

After successfully importing 3 functions, 3 functions will appear under Functions as shown:

After completing this step: you can execute the following code test in the Controller controller:

 

try {
            $data =\app\home\model\User::select();
            dump( $data );
        } catch (\Exception  $e ) {
            dump( $e ->getMessage());
        }


        \app\home\model\User::create([ "user_name" => "123456" ,
            "user_pwd" => "123456" ,
            "mobile" => "abc" ,
            "full_name" => "abc" ,
        ]);