Page d'accueil>Code source PHP>Autres catégories
 korm . DocsUrl = "docs" // default endpoint '/docs' 
korm . BASIC_AUTH_USER = "test"
korm . BASIC_AUTH_PASS = "pass"
korm . WithDocs ( generate , dirPath , korm . BasicAuth )
korm . WithDocs ( true , "" , korm . BasicAuth ) // dirPath default to 'assets/static/docs'
korm . WithEmbededDocs ( embeded embed . FS , dirPath , korm . BasicAuth )
// dirPath default to 'assets/static/docs' if empty

Coque interactive

Commands :  
[databases, use, tables, columns, migrate, createsuperuser, createuser, query, getall, get, drop, delete, clear/cls, q/quit/exit, help/commands]
  ' databases ' :
	  list all connected databases

  ' use ' :
	  use a specific database

  ' tables ' :
	  list all tables in database

  ' columns ' :
	  list all columns of a table
	  (accept but not required extra param like : ' columns ' or ' columns users ' )

  ' migrate ' :
	  migrate or execute sql file

  ' createsuperuser ' : (only with dashboard)
	  create a admin user
  
  ' createuser ' : (only with dashboard)
	  create a regular user

  ' query ' : 
	  query data from database 
	  (accept but not required extra param like : ' query ' or ' query select * from users where ... ' )


  ' getall ' : 
	  get all rows given a table name
	  (accept but not required extra param like : ' getall ' or ' getall users ' )

  ' get ' :
	  get single row 
	  (accept but not required extra param like : ' get ' or ' get users email like "%anything%" ' )

  ' delete ' :
	  delete rows where field equal_to
	  (accept but not required extra param like : ' delete ' or ' delete users email="[email protected]" ' )

  ' drop ' :
	  drop a table given table name
	  (accept but not required extra param like : ' drop ' or ' drop users ' )

  ' clear / cls ' :
	  clear shell console

  ' q / quit / exit / q! ' :
	  exit shell

  ' help ' :
	  show this help message

Exemple, non obligatoire, charger la configuration depuis env directement vers struct à l'aide de Kenv

 import "github.com/kamalshkeir/kenv"

type EmbedS struct {
	Static    bool `kenv:"EMBED_STATIC|false"`
	Templates bool `kenv:"EMBED_TEMPLATES|false"`
}

type GlobalConfig struct {
	Host       string `kenv:"HOST|localhost"` // DEFAULT to 'localhost': if HOST not found in env
	Port       string `kenv:"PORT|9313"`
	Embed 	   EmbedS
	Db struct {
		Name     string `kenv:"DB_NAME|db"` // NOT REQUIRED: if DB_NAME not found, defaulted to 'db'
		Type     string `kenv:"DB_TYPE"` // REEQUIRED: this env var is required, you will have error if empty
		DSN      string `kenv:"DB_DSN|"` // NOT REQUIRED: if DB_DSN not found it's not required, it's ok to stay empty
	}
	Smtp struct {
		Email string `kenv:"SMTP_EMAIL|"`
		Pass  string `kenv:"SMTP_PASS|"`
		Host  string `kenv:"SMTP_HOST|"`
		Port  string `kenv:"SMTP_PORT|"`
	}
	Profiler   bool   `kenv:"PROFILER|false"`
	Docs       bool   `kenv:"DOCS|false"`
	Logs       bool   `kenv:"LOGS|false"`
	Monitoring bool   `kenv:"MONITORING|false"`
}


kenv . Load ( ".env" ) // load env file

// Fill struct from env loaded before:
Config := & GlobalConfig {}
err := kenv . Fill ( Config ) // fill struct with env vars loaded before

Exemples de structures imbriquées ou intégrées

 package main

import (
	"fmt"
	"time"

	"github.com/kamalshkeir/lg"
	"github.com/kamalshkeir/korm"
	"github.com/kamalshkeir/sqlitedriver"
)

type Class struct {
	Id       uint `korm:"pk"`
	Name     string
	Students [] Student
}

type Student struct {
	Id      uint `korm:"pk"`
	Name    string
	Class   uint `korm:"fk:classes.id:cascade:cascade"`
	Classes Class
}

func main () {
	err := korm . New ( korm . SQLITE , "db" , sqlitedriver . Use ())
	if lg . CheckError ( err ) {
		return
	}
	defer korm . Shutdown ()

	server := korm . WithDashboard ( "localhost:9313" )
	korm . WithShell ()

	err = korm. AutoMigrate [ Class ]( "classes" )
	lg . CheckError ( err )

	err = korm. AutoMigrate [ Student ]( "students" )
	lg . CheckError ( err )

	// go run main.go shell to createsuperuser
	// connect to admin and create some data to query

	// nested structs with joins, scan the result to the channel directly after each row
	// so instead of receiving a slice, you will receive data on the channel[0] of the passed slice
	studentsChan := [] chan Student { make ( chan Student )}
	go func () {
		for s := range studentsChan [ 0 ] {
			fmt . Println ( "chan students:" , s )
		}
	}()
	err = korm . To ( & studentsChan ). Query ( "select students.*,classes.id as 'classes.id',classes.name as 'classes.name'  from students join classes where classes.id = students.class" )
	lg . CheckError ( err )
	fmt . Println ()

	// nested (second argument of 'Scan') filled automatically from join, support nested slices and structs
	classes := [] Class {}
	err = korm . To ( & classes , true ). Query ( "select classes.*, students.id as 'students.id',students.name as 'students.name' from classes join students on students.class = classes.id order by classes.id" )
	lg . CheckError ( err )
	for _ , s := range classes {
		fmt . Println ( "class:" , s )
	}
	fmt . Println ()

	// // not nested, only remove second arg true from Scan method
	students := [] Student {}
	err = korm . To ( & students , true ). Query ( "select students.*,classes.id as 'classes.id',classes.name as 'classes.name'  from students join classes where classes.id = students.class" )
	lg . CheckError ( err )
	for _ , s := range students {
		fmt . Println ( "student:" , s )
	}
	fmt . Println ()

	maps := [] map [ string ] any {}
	err = korm . To ( & maps ). Query ( "select * from students" )
	lg . CheckError ( err )
	fmt . Println ( "maps =" , maps )
	fmt . Println ()

	names := [] * string {}
	err = korm . To ( & names ). Query ( "select name from students" )
	lg . CheckError ( err )
	fmt . Println ( "names =" , names )
	fmt . Println ()

	ids := [] int {}
	err = korm . To ( & ids ). Query ( "select id from students" )
	lg . CheckError ( err )
	fmt . Println ( "ids =" , ids )
	fmt . Println ()

	bools := [] bool {}
	err = korm . To ( & bools ). Query ( "select is_admin from users" )
	lg . CheckError ( err )
	fmt . Println ( "bools =" , bools )
	fmt . Println ()

	times := []time. Time {}
	err = korm . To ( & times ). Query ( "select created_at from users" )
	lg . CheckError ( err )
	fmt . Println ( "times =" , times )

	server . Run ()
}

// OUTPUT
// chan students: {1 student-1 1 {1 Math []}}
// chan students: {2 student-2 2 {2 French []}}
// chan students: {3 student-3 1 {1 Math []}}
// chan students: {4 student-4 2 {2 French []}}

// class: {1 Math [{1 student-1 0 {0  []}} {3 student-3 0 {0  []}}]}
// class: {2 French [{2 student-2 0 {0  []}} {4 student-4 0 {0  []}}]}

// student: &{1 student-1 1 {1 Math []}}
// student: &{2 student-2 2 {2 French []}}
// student: &{3 student-3 1 {1 Math []}}
// student: &{4 student-4 2 {2 French []}}

// maps = [map[class:1 id:1 name:student-1] map[class:2 id:2 name:student-2] map[class:1 id:3 name:student-3] map[class:2 id:4 name:student-4]]

// names = [student-1 student-2 student-3 student-4]

// ids = [1 2 3 4]

// bools = [true]

// times = [2023-04-30 19:19:32 +0200 CEST]

Benchmark contre Tarantool, Pgx, Gorm

https://github.com/kamalshkeir/korm-vs-gorm-vs-tarantool-vs-pgx

Benchmarks et Gorm

goos: windows
goarch: amd64
pkg: github.com/kamalshkeir/korm/benchmarks
cpu: Intel(R) Core(TM) i5-7300HQ CPU @ 2.50GHz

Pour exécuter ces benchmarks sur votre machine, très simple :

 type TestTable struct {
	Id        uint `korm:"pk"`
	Email     string
	Content   string
	Password  string
	IsAdmin   bool
	CreatedAt time. Time `korm:"now"`
	UpdatedAt time. Time `korm:"update"`
}

type TestTableGorm struct {
	Id        uint `gorm:"primarykey"`
	Email     string
	Content   string
	Password  string
	IsAdmin   bool
	CreatedAt time. Time
	UpdatedAt time. Time
}
////////////////////////////////////////////  query 7000 rows  //////////////////////////////////////////////
BenchmarkGetAllS_GORM - 4                       19          56049832 ns / op        12163316 B / op     328790 allocs / op
BenchmarkGetAllS - 4                       2708934               395.3 ns / op           224 B / op          1 allocs / op
BenchmarkGetAllM_GORM - 4                       18          62989567 ns / op        13212278 B / op     468632 allocs / op
BenchmarkGetAllM - 4                       4219461               273.5 ns / op           224 B / op          1 allocs / op
BenchmarkGetRowS_GORM - 4                    12188             96988 ns / op            5930 B / op        142 allocs / op
BenchmarkGetRowS - 4                       1473164               805.1 ns / op           336 B / op          7 allocs / op
BenchmarkGetRowM_GORM - 4                    11402            101638 ns / op            7408 B / op        203 allocs / op
BenchmarkGetRowM - 4                       1752652               671.9 ns / op           336 B / op          7 allocs / op
BenchmarkPagination10_GORM - 4                7714            153304 ns / op           19357 B / op        549 allocs / op
BenchmarkPagination10 - 4                  1285722               934.5 ns / op           400 B / op          7 allocs / op
BenchmarkPagination100_GORM - 4               1364            738934 ns / op          165423 B / op       4704 allocs / op
BenchmarkPagination100 - 4                 1278724               956.5 ns / op           400 B / op          7 allocs / op
BenchmarkQueryS - 4                        5781499               207.7 ns / op             4 B / op          1 allocs / op
BenchmarkQueryM - 4                        4643155               227.2 ns / op             4 B / op          1 allocs / op
BenchmarkGetAllTables - 4                 47465865                25.48 ns / op            0 B / op          0 allocs / op
BenchmarkGetAllColumns - 4                23657019                42.82 ns / op            0 B / op          0 allocs / op
////////////////////////////////////////////  query 5000 rows  //////////////////////////////////////////////
BenchmarkGetAllS_GORM - 4                       24          43247546 ns / op         8796840 B / op     234784 allocs / op
BenchmarkGetAllS - 4                       2854401               426.8 ns / op           224 B / op          1 allocs / op
BenchmarkGetAllM_GORM - 4                       24          46329242 ns / op         9433050 B / op     334631 allocs / op
BenchmarkGetAllM - 4                       4076317               283.4 ns / op           224 B / op          1 allocs / op
BenchmarkGetRowS_GORM - 4                    11445            101107 ns / op            5962 B / op        142 allocs / op
BenchmarkGetRowS - 4                       1344831               848.4 ns / op           336 B / op          7 allocs / op
BenchmarkGetRowM_GORM - 4                    10000            100969 ns / op            7440 B / op        203 allocs / op
BenchmarkGetRowM - 4                       1721742               688.5 ns / op           336 B / op          7 allocs / op
BenchmarkPagination10_GORM - 4                7500            156208 ns / op           19423 B / op        549 allocs / op
BenchmarkPagination10 - 4                  1253757               952.3 ns / op           400 B / op          7 allocs / op
BenchmarkPagination100_GORM - 4               1564            749408 ns / op          165766 B / op       4704 allocs / op
BenchmarkPagination100 - 4                 1236270               957.5 ns / op           400 B / op          7 allocs / op
BenchmarkGetAllTables - 4                 44399386                25.43 ns / op            0 B / op          0 allocs / op
BenchmarkGetAllColumns - 4                27906392                41.45 ns / op            0 B / op          0 allocs / op
////////////////////////////////////////////  query 1000 rows  //////////////////////////////////////////////
BenchmarkGetAllS_GORM - 4                      163           6766871 ns / op         1683919 B / op      46735 allocs / op
BenchmarkGetAllS - 4                       2882660               399.0 ns / op           224 B / op          1 allocs / op
BenchmarkGetAllM_GORM - 4                      140           8344988 ns / op         1886922 B / op      66626 allocs / op
BenchmarkGetAllM - 4                       3826730               296.5 ns / op           224 B / op          1 allocs / op
BenchmarkGetRowS_GORM - 4                    11940             97725 ns / op            5935 B / op        142 allocs / op
BenchmarkGetRowS - 4                       1333258               903.0 ns / op           336 B / op          7 allocs / op
BenchmarkGetRowM_GORM - 4                    10000            106079 ns / op            7408 B / op        203 allocs / op
BenchmarkGetRowM - 4                       1601274               748.2 ns / op           336 B / op          7 allocs / op
BenchmarkPagination10_GORM - 4                7534            159991 ns / op           19409 B / op        549 allocs / op
BenchmarkPagination10 - 4                  1153982              1022 ns / op             400 B / op          7 allocs / op
BenchmarkPagination100_GORM - 4               1468            766269 ns / op          165876 B / op       4705 allocs / op
BenchmarkPagination100 - 4                 1000000              1016 ns / op             400 B / op          7 allocs / op
BenchmarkGetAllTables - 4                 56200297                25.36 ns / op            0 B / op          0 allocs / op
BenchmarkGetAllColumns - 4                25478679                41.30 ns / op            0 B / op          0 allocs / op
////////////////////////////////////////////  query 300 rows  //////////////////////////////////////////////
BenchmarkGetAllS_GORM - 4                      558           2046830 ns / op          458475 B / op      13823 allocs / op
BenchmarkGetAllS - 4                       2798872               411.5 ns / op           224 B / op          1 allocs / op
BenchmarkGetAllM_GORM - 4                      428           2605646 ns / op          567011 B / op      19721 allocs / op
BenchmarkGetAllM - 4                       4093662               287.9 ns / op           224 B / op          1 allocs / op
BenchmarkGetRowS_GORM - 4                    12182             97764 ns / op            5966 B / op        142 allocs / op
BenchmarkGetRowS - 4                       1347084               886.4 ns / op           336 B / op          7 allocs / op
BenchmarkGetRowM_GORM - 4                    10000            105311 ns / op            7440 B / op        203 allocs / op
BenchmarkGetRowM - 4                       1390363               780.0 ns / op           336 B / op          7 allocs / op
BenchmarkPagination10_GORM - 4                7502            155949 ns / op           19437 B / op        549 allocs / op
BenchmarkPagination10 - 4                  1000000              1046 ns / op             400 B / op          7 allocs / op
BenchmarkPagination100_GORM - 4               1479            779700 ns / op          165679 B / op       4705 allocs / op
BenchmarkPagination100 - 4                 1000000              1054 ns / op             400 B / op          7 allocs / op
BenchmarkGetAllTables - 4                 52255704                26.00 ns / op            0 B / op          0 allocs / op
BenchmarkGetAllColumns - 4                29292368                42.09 ns / op            0 B / op          0 allocs / op
////////////////////////////////////////////    MONGO       //////////////////////////////////////////////
BenchmarkGetAllS - 4               3121384               385.6 ns / op           224 B / op          1 allocs / op
BenchmarkGetAllM - 4               4570059               264.2 ns / op           224 B / op          1 allocs / op
BenchmarkGetRowS - 4               1404399               866.6 ns / op           336 B / op          7 allocs / op
BenchmarkGetRowM - 4               1691026               722.6 ns / op           336 B / op          7 allocs / op
BenchmarkGetAllTables - 4         47424489                25.34 ns / op            0 B / op          0 allocs / op
BenchmarkGetAllColumns - 4        27039632                42.22 ns / op            0 B / op          0 allocs / op
//////////////////////////////////////////////////////////////////////////////////////////////////////////

Balises disponibles par type de champ de structure :

Champ de chaîne :

Sans paramètre Avec paramètre
 *  	text (create column as TEXT not VARCHAR)
*  	notnull
*  	unique
*   iunique // insensitive unique
*  	index, +index, index+ (INDEX ascending)
*  	index-, -index (INDEX descending)
*  	default (DEFAULT '')
 * 	default:'any' (DEFAULT 'any')
*	mindex:...
* 	uindex:username,Iemail // CREATE UNIQUE INDEX ON users (username,LOWER(email)) 
	// 	email is lower because of 'I' meaning Insensitive for email
* 	fk:...
* 	size:50  (VARCHAR(50))
* 	check:...

Int, Uint, Int64, Uint64 Champs :

Sans paramètre
 *   -  			 (To Ignore a field)
*   autoinc, pk  (PRIMARY KEY)
*   notnull      (NOT NULL)
*  	index, +index, index+ (CREATE INDEX ON COLUMN)
*  	index-, -index(CREATE INDEX DESC ON COLUMN)     
*   unique 		 (CREATE UNIQUE INDEX ON COLUMN) 
*   default		 (DEFAULT 0)
Avec paramètre
 Available 'on_delete' and 'on_update' options: cascade,(donothing,noaction),(setnull,null),(setdefault,default)

*   fk:{table}.{column}:{on_delete}:{on_update} 
*   check: len(to_check) > 10 ; check: is_used=true (You can chain checks or keep it in the same CHECK separated by AND)
*   mindex: first_name, last_name (CREATE MULTI INDEX ON COLUMN + first_name + last_name)
*   uindex: first_name, last_name (CREATE MULTI UNIQUE INDEX ON COLUMN + first_name + last_name) 
*   default:5 (DEFAULT 5)

Bool : bool est INTEGER NOT NULL vérifié entre 0 et 1 (afin d'être cohérent entre les dialectes SQL)

Sans paramètre Avec paramètre
 *  	index, +index, index+ (CREATE INDEX ON COLUMN)
*  	index-, -index(CREATE INDEX DESC ON COLUMN)  
*   default (DEFAULT 0)
 *   default:1 (DEFAULT 1)
*   mindex:...
*   fk:...

time.Time :

Sans paramètre Avec paramètre
 *  	index, +index, index+ (CREATE INDEX ON COLUMN)
*  	index-, -index(CREATE INDEX DESC ON COLUMN)  
*   unique
*   now (NOT NULL and defaulted to current unix timestamp)
*   update (NOT NULL DEFAULT UNIX_TIMESTAMP ON UPDATE UNIX_TIMESTAMP)
 *   fk:...
*   check:...
*   uindex:...

Flotteur64 :

Sans paramètre Avec paramètre
 *   notnull
*  	index, +index, index+ (CREATE INDEX ON COLUMN)
*  	index-, -index(CREATE INDEX DESC ON COLUMN)  
*   unique
*   default
 *   default:...
*   fk:...
*   mindex:...
*   uindex:...
*   check:...

JSON

 type JsonOption struct {
	As       string
	Dialect  string
	Database string
	Params   [] any
}
func JSON_EXTRACT ( dataJson string , opt ... JsonOption ) string
func JSON_REMOVE ( dataJson string , opt ... JsonOption ) string
func JSON_SET ( dataJson string , opt ... JsonOption ) string
func JSON_ARRAY ( values [] any , as string , dialect ... string ) string
func JSON_OBJECT ( values [] any , as string , dialect ... string ) string
func JSON_CAST ( value string , as string , dialect ... string ) string

// create query json
q := korm . JSON_EXTRACT ( `{"a": {"c": 3}, "b": 2}` , korm. JsonOption {
	As :     "data" ,
	Params : [] any { "a.c" , "b" },
})
fmt . Println ( "q ==" , q ) // q == JSON_EXTRACT('{"a": {"c": 3}, "b": 2}','$.a.c','$.b') AS data

var data [] map [ string ] any
err := korm . To ( & data ). Query ( "SELECT " + q )
lg . CheckError ( err )

fmt . Println ( "data=" , data ) // data= [map[data:[3,2]]]

? Links


Licence

Licence BSD-3

Développer
Informations supplémentaires