{"id":39903130,"url":"https://github.com/xjustloveux/jgo","last_synced_at":"2026-01-18T15:32:14.995Z","repository":{"id":37404616,"uuid":"491367315","full_name":"xjustloveux/jgo","owner":"xjustloveux","description":"JGo provides an easier configuration for writing sql, log, and cron jobs.","archived":false,"fork":false,"pushed_at":"2023-12-11T03:24:19.000Z","size":226,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2023-12-12T03:23:50.147Z","etag":null,"topics":["config","cron","go","golang","jgo","jgoc","log","logger","mssql","mysql","oracle","postgresql","schedule","sql-server"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/xjustloveux.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2022-05-12T04:48:01.000Z","updated_at":"2022-12-15T00:17:15.000Z","dependencies_parsed_at":"2023-12-11T03:23:47.590Z","dependency_job_id":"1c4a417c-9aa0-464b-82a3-d7f5bdbc35e6","html_url":"https://github.com/xjustloveux/jgo","commit_stats":null,"previous_names":[],"tags_count":59,"template":null,"template_full_name":null,"purl":"pkg:github/xjustloveux/jgo","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xjustloveux%2Fjgo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xjustloveux%2Fjgo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xjustloveux%2Fjgo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xjustloveux%2Fjgo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/xjustloveux","download_url":"https://codeload.github.com/xjustloveux/jgo/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xjustloveux%2Fjgo/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28539228,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-18T14:59:57.589Z","status":"ssl_error","status_checked_at":"2026-01-18T14:59:46.540Z","response_time":98,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["config","cron","go","golang","jgo","jgoc","log","logger","mssql","mysql","oracle","postgresql","schedule","sql-server"],"created_at":"2026-01-18T15:32:14.933Z","updated_at":"2026-01-18T15:32:14.987Z","avatar_url":"https://github.com/xjustloveux.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![JGo Web](https://jgo.dev/assets/images/logo_300.svg)](https://jgo.dev/)\n\n[![JGo release](https://img.shields.io/github/v/release/xjustloveux/jgo)](https://github.com/xjustloveux/jgo/releases)\n[![codecov](https://codecov.io/gh/xjustloveux/jgo/branch/master/graph/badge.svg?token=RCO5VO2YU6)](https://codecov.io/gh/xjustloveux/jgo)\n[![Build Status](https://github.com/xjustloveux/jgo/actions/workflows/go.yml/badge.svg)](https://github.com/xjustloveux/jgo/actions/workflows/go.yml)\n[![Go Report Card](https://goreportcard.com/badge/github.com/xjustloveux/jgo)](https://goreportcard.com/report/github.com/xjustloveux/jgo)\n[![PkgGoDev](https://pkg.go.dev/badge/mod/github.com/xjustloveux/jgo)](https://pkg.go.dev/mod/github.com/xjustloveux/jgo)\n[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://github.com/xjustloveux/jgo/blob/master/LICENSE)\n\n---\n\n* [Overview](#Overview)\n* [Middlewares](#Middlewares)\n* [Installation](#Installation)\n* [Example](#Example)\n    * [jsql](#jsql)\n    * [jcron](#jcron)\n    * [jlog](#jlog)\n    * [jfile](#jfile)\n    * [jtime](#jtime)\n* [Environment](#Environment)\n* [API](#API)\n\n# Overview\n\n---\n\nJGo provides an easier configuration for writing sql, log, and cron jobs.\n\nJGo Web：~~[https://jgo.dev](https://jgo.dev)~~\n\nJGo Web Project：[https://github.com/xjustloveux/jgo.web](https://github.com/xjustloveux/jgo.web)\n\n# Middlewares\n\n---\n\n**JGo minimizes dependencies on third-party middleware to avoid conflicts.**\n\njlog only import [logrus](https://github.com/sirupsen/logrus) middleware.\n\njsql only import [govaluate](https://github.com/Knetic/govaluate) middleware, but it is designed on the basis\nof [mysql](https://github.com/go-sql-driver/mysql), [go-mssqldb](https://github.com/denisenkom/go-mssqldb), [godror](https://github.com/godror/godror) and [pq](https://github.com/lib/pq).\n\n# Installation\n\n---\n\n```shell\ngo get github.com/xjustloveux/jgo\n```\n\n# Example\n\n---\n\n## jsql\n\n### Configuration\n\nConfiguration file default `json` format, you can use `jsql.SetFormat` to set you want, but you must be used\n[jfile.RegisterCodec](#RegisterCodec) register codec.\n\n| Property Name                      | Required | Type                   | Default Value | Comment                                                                                                                                                                                                                                                                                                                                                |\n|------------------------------------|----------|------------------------|---------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| DaoPath                            | true     | string                 | empty         | It your xml files folder path.                                                                                                                                                                                                                                                                                                                         |\n| Default                            | true     | string                 | empty         | It your default DataSource name.                                                                                                                                                                                                                                                                                                                       |\n| DataSource                         | true     | map[string]interface{} | empty         |                                                                                                                                                                                                                                                                                                                                                        |\n| DataSource.Type                    | true     | string                 | empty         | You can set `MySql`, `MSSql`, `Oracle` or `PostgreSql`, others as long as the sql parameter supports '?'.                                                                                                                                                                                                                                              |\n| DataSource.DSN                     | true     | string                 | empty         | DataSourceName. If you have information security considerations, you can encrypt the DataSource into a string, and set the decryption function.                                                                                                                                                                                                        |\n| DataSource.DN                      | false    | string                 | empty         | DriverName. If your type is `MySql`, `MSSql`, `Oracle` or `PostgreSql`, the DriverName default use [mysql](https://github.com/go-sql-driver/mysql), [go-mssqldb](https://github.com/denisenkom/go-mssqldb), [godror](https://github.com/godror/godror) and [pq](https://github.com/lib/pq) driver. You also can set this value to use your DriverName. |\n| DataSource.DbName                  | false    | string                 | empty         | It your db name.                                                                                                                                                                                                                                                                                                                                       |\n| DataSource.ConnMaxLifetime         | false    | time.Duration          | 120           |                                                                                                                                                                                                                                                                                                                                                        |\n| DataSource.ConnMaxLifetimeDuration | false    | string                 | Second        | Nanosecond, Microsecond, Millisecond, Second, Minute, Hour, Day                                                                                                                                                                                                                                                                                        |\n| DataSource.ConnMaxIdleTime         | false    | time.Duration          | 0             |                                                                                                                                                                                                                                                                                                                                                        |\n| DataSource.ConnMaxIdleTimeDuration | false    | string                 | Hour          | Nanosecond, Microsecond, Millisecond, Second, Minute, Hour, Day                                                                                                                                                                                                                                                                                        |\n| DataSource.MaxOpenConns            | false    | int                    | 0             |                                                                                                                                                                                                                                                                                                                                                        |\n| DataSource.MaxIdleConns            | false    | int                    | 0             |                                                                                                                                                                                                                                                                                                                                                        |\n| DataSource.EncodeData              | false    | string                 | empty         | If you have information security considerations, you can encrypt the DataSource into a string, and set the decryption Format and function.                                                                                                                                                                                                             |\n| DataSource.Format                  | false    | jfile.Format           | jfile.Json    | `DataSource.EncodeData` format. If you want use other format, you must be use [jfile.RegisterCodec](#RegisterCodec) register codec.                                                                                                                                                                                                                    |\n\n### Usage\n\n#### config.json\n\n```json\n{\n  \"db\": {\n    \"daoPath\": \"dao/\",\n    \"default\": \"exampleMySql\",\n    \"dataSource\": {\n      \"exampleMySql\": {\n        \"type\": \"MySql\",\n        \"dsn\": \"user:password@tcp(192.168.1.1:3306)/DBName?checkConnLiveness=false\u0026maxAllowedPacket=0\u0026charset=utf8mb4\u0026parseTime=true\",\n        \"dbName\": \"DBName\"\n      },\n      \"exampleMSSql\": {\n        \"type\": \"MSSql\",\n        \"dsn\": \"Data Source=192.168.1.1,1433;Initial Catalog=DBName;Integrated Security=False;User ID=user;Password=password;Connection Timeout=120;MultipleActiveResultSets=True\",\n        \"dbName\": \"DBName\"\n      },\n      \"exampleOracle\": {\n        \"type\": \"Oracle\",\n        \"dsn\": \"user/password@192.168.1.1:1521/ORCLCDB\",\n        \"dbName\": \"DBName\"\n      },\n      \"examplePostgreSql\": {\n        \"type\": \"PostgreSql\",\n        \"dsn\": \"postgresql://user:password@192.168.1.1:5432/DBName?sslmode=disable\",\n        \"dbName\": \"DBName\"\n      }\n    }\n  }\n}\n```\n\n#### dao/example.xml\n\nFor details, please refer to [XmlTag](#XmlTag).\n\n⚠️**The tags ${} and #{} will directly become SQL statements at the end, which may cause SQL injection problems. Please\nuse them with caution.**\n\n```xml\n\u003c?xml version=\"1.0\" encoding=\"UTF-8\"?\u003e\n\u003cdao\u003e\n    \u003cselect id=\"example1\"\u003e\n        SELECT * FROM TABLE1\n    \u003c/select\u003e\n    \u003cselect id=\"example2\"\u003e\n        SELECT * FROM TABLE2\n        \u003cwhere\u003e\n            COL1 = @{COL1}\n            \u003cif test=\"!nil(COL2) and COL2 != ''\"\u003e\n                AND COL2 = @{COL2}\n            \u003c/if\u003e\n        \u003c/where\u003e\n    \u003c/select\u003e\n    \u003cselect id=\"example3\"\u003e\n        SELECT ${COL1}, ${COL2} FROM TABLE3\n        \u003corderBy last=\"true\"\u003e\n            ${SORT} DESC\n        \u003c/orderBy\u003e\n    \u003c/select\u003e\n    \u003cselect id=\"example4\"\u003e\n        SELECT\n        \u003cforeach params=\"list\" open=\"\" separator=\",\" close=\"\"\u003e\n            #{val}\n        \u003c/foreach\u003e\n        FROM TABLE4\n    \u003c/select\u003e\n    \u003cinsert id=\"insertExample\"\u003e\n        INSERT INTO ${TABLE}\n        \u003cforeach params=\"list\" open=\"(\" separator=\",\" close=\")\"\u003e\n            #{val}\n        \u003c/foreach\u003e\n        VALUES\n        \u003cforeach params=\"list\" open=\"(\" separator=\",\" close=\")\"\u003e\n            @{#{val}}\n        \u003c/foreach\u003e\n    \u003c/insert\u003e\n\u003c/dao\u003e\n```\n\n#### main.go\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t_ \"github.com/denisenkom/go-mssqldb\"\n\t_ \"github.com/go-sql-driver/mysql\"\n\t_ \"github.com/godror/godror\"\n\t_ \"github.com/lib/pq\"\n\t\"github.com/xjustloveux/jgo/jsql\"\n)\n\nfunc main() {\n\tif err := jsql.Init(); err != nil {\n\t\tfmt.Println(err)\n\t\treturn\n\t}\n}\n```\n\n#### example1\n\n```go\npackage main\n\nfunc example1() {\n\t// SELECT * FROM TABLE1\n\tif agent, err := jsql.GetAgent(); err != nil {\n\t\tfmt.Println(err)\n\t} else {\n\t\tvar res jsql.Result\n\t\tif res, err = agent.Query(\"example1\"); err != nil {\n\t\t\tfmt.Println(err)\n\t\t} else {\n\t\t\tfor _, item := range res.Rows() {\n\t\t\t\tfmt.Println(item)\n\t\t\t}\n\t\t}\n\t}\n}\n```\n\n#### example2\n\n```go\npackage main\n\nfunc example2() {\n\t// SELECT * FROM TABLE2 WHERE COL1 = ? AND COL2 = ?\n\tparam := make(map[string]interface{})\n\tparam[\"COL1\"] = \"VAL1\"\n\tparam[\"COL2\"] = \"VAL2\"\n\tif agent, err := jsql.GetAgent(); err != nil {\n\t\tfmt.Println(err)\n\t} else {\n\t\tvar res jsql.Result\n\t\tif res, err = agent.QueryPage(\"example2\", 6, 10, param); err != nil {\n\t\t\tfmt.Println(err)\n\t\t} else {\n\t\t\tfmt.Println(res.TotalRecord())\n\t\t\tfor _, item := range res.Rows() {\n\t\t\t\tfmt.Println(item)\n\t\t\t}\n\t\t}\n\t}\n}\n```\n\n#### example3\n\n```go\npackage main\n\nfunc example3() {\n\t// SELECT COL_NAME1, COL_NAME2 FROM TABLE3 ORDER BY SORT_COL_NAME DESC\n\tparam := make(map[string]interface{})\n\tparam[\"COL1\"] = \"COL_NAME1\"\n\tparam[\"COL2\"] = \"COL_NAME2\"\n\tparam[\"SORT\"] = \"SORT_COL_NAME\"\n\tif agent, err := jsql.GetAgent(\"exampleMSSql\"); err != nil {\n\t\tfmt.Println(err)\n\t} else {\n\t\tvar res jsql.Result\n\t\tif res, err = agent.QueryPage(\"example3\", 6, 10, param); err != nil {\n\t\t\tfmt.Println(err)\n\t\t} else {\n\t\t\tfmt.Println(res.TotalRecord())\n\t\t\tfor _, item := range res.Rows() {\n\t\t\t\tfmt.Println(item)\n\t\t\t}\n\t\t}\n\t}\n\n\t// you also can use struct\n\ttype Param struct {\n\t\tCOL1 string\n\t\tCOL2 string\n\t\tSORT string\n\t}\n\tparam2 := Param{\n\t\tCOL1: \"COL_NAME1\",\n\t\tCOL2: \"COL_NAME2\",\n\t\tSORT: \"SORT_COL_NAME\",\n\t}\n\ttype Data struct {\n\t\tCOL_NAME1 string\n\t\tCOL_NAME2 string\n\t}\n\ttype List struct {\n\t\tRows []Data\n\t}\n\tvar list List\n\tif agent, err := jsql.GetAgent(\"exampleMSSql\"); err != nil {\n\t\tfmt.Println(err)\n\t} else {\n\t\tif _, err = agent.QueryPage(\"example3\", 6, 10, param2, \u0026list); err != nil {\n\t\t\tfmt.Println(err)\n\t\t} else {\n\t\t\tfmt.Println(list)\n\t\t}\n\t}\n}\n```\n\n#### example4\n\n```go\npackage main\n\nfunc example4() {\n\t// SELECT COL_NAME1, COL_NAME2 FROM TABLE4\n\tparam := make(map[string]interface{})\n\tlist := []string{\"COL_NAME1\", \"COL_NAME2\"}\n\tparam[\"list\"] = list\n\tif agent, err := jsql.GetAgent(\"exampleOracle\"); err != nil {\n\t\tfmt.Println(err)\n\t} else {\n\t\tvar res jsql.Result\n\t\tif res, err = agent.QueryPage(\"example4\", 6, 10, param); err != nil {\n\t\t\tfmt.Println(err)\n\t\t} else {\n\t\t\tfmt.Println(res.TotalRecord())\n\t\t\tfor _, item := range res.Rows() {\n\t\t\t\tfmt.Println(item)\n\t\t\t}\n\t\t}\n\t}\n}\n```\n\n#### example5\n\n```go\npackage main\n\nfunc example5() {\n\t// INSERT INTO TABLE5 (COL_NAME1, COL_NAME2, COL_NAME3) VALUES (?, ?, ?)\n\tlist := []string{\"COL_NAME1\", \"COL_NAME2\", \"COL_NAME3\"}\n\tparam := make(map[string]interface{})\n\tparam[\"list\"] = list\n\tparam[\"TABLE\"] = \"TABLE5\"\n\tparam[\"COL_NAME1\"] = 123\n\tparam[\"COL_NAME2\"] = \"Test\"\n\tparam[\"COL_NAME3\"] = time.Now()\n\tif agent, err := jsql.GetAgent(); err != nil {\n\t\tfmt.Println(err)\n\t} else {\n\t\tif _, err = agent.Insert(\"insertExample\", param); err != nil {\n\t\t\tfmt.Println(err)\n\t\t}\n\t}\n}\n```\n\n#### example6\n\n```go\npackage main\n\nfunc example6() {\n\t// INSERT INTO TABLE5 (COL_NAME1, COL_NAME2, COL_NAME3) VALUES (?, ?, ?)\n\tlist := []string{\"COL_NAME1\", \"COL_NAME2\", \"COL_NAME3\"}\n\tparam := make(map[string]interface{})\n\tparam[\"list\"] = list\n\tparam[\"TABLE\"] = \"TABLE5\"\n\tparam[\"COL_NAME1\"] = 123\n\tparam[\"COL_NAME2\"] = \"Test1\"\n\tparam[\"COL_NAME3\"] = time.Now()\n\tif agent, err := jsql.GetAgent(); err != nil {\n\t\tfmt.Println(err)\n\t} else {\n\t\t// or you can use agent.UseTx easier\n\t\tif _, err = agent.Begin(); err != nil {\n\t\t\tfmt.Println(err)\n\t\t} else {\n\t\t\tdefer func() {\n\t\t\t\tif err != nil {\n\t\t\t\t\tif e := agent.Rollback(); e != nil {\n\t\t\t\t\t\tfmt.Println(e)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}()\n\t\t\tif _, err = agent.InsertTx(\"insertExample\", param); err != nil {\n\t\t\t\tfmt.Println(err)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tparam[\"COL_NAME1\"] = 456\n\t\t\tparam[\"COL_NAME2\"] = \"Test2\"\n\t\t\tparam[\"COL_NAME3\"] = time.Now()\n\t\t\tif _, err = agent.InsertTx(\"insertExample\", param); err != nil {\n\t\t\t\tfmt.Println(err)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif err = agent.Commit(); err != nil {\n\t\t\t\tfmt.Println(err)\n\t\t\t}\n\t\t}\n\t}\n}\n```\n\n#### example7\n\n```go\npackage main\n\nfunc example7() {\n\t// SELECT * FROM TABLE6 WHERE COL1 = ?\n\tvar res jsql.Result\n\tta := \u0026jsql.TableAgent{Table: \"TABLE6\"}\n\tta.Equal(\"COL1\", \"VAL1\")\n\tif res, err = ta.QueryPage(6, 10); err != nil {\n\t\tfmt.Println(err)\n\t} else {\n\t\tfmt.Println(res.TotalRecord())\n\t\tfor _, item := range res.Rows() {\n\t\t\tfmt.Println(item)\n\t\t}\n\t}\n}\n```\n\n### XmlTag\n\n| Tag Name | Layer | Attr Name | Required | Type   | Comment                                                                                                  |\n|----------|-------|-----------|----------|--------|----------------------------------------------------------------------------------------------------------|\n| dao      | 1     |           | true     |        |                                                                                                          |\n| select   | 2     |           |          |        |                                                                                                          |\n|          |       | id        | true     | string |                                                                                                          |\n| insert   | 2     |           |          |        |                                                                                                          |\n|          |       | id        | true     | string |                                                                                                          |\n| update   | 2     |           |          |        |                                                                                                          |\n|          |       | id        | true     | string |                                                                                                          |\n| delete   | 2     |           |          | string |                                                                                                          |\n|          |       | id        | true     | string |                                                                                                          |\n| other    | 2     |           |          | string |                                                                                                          |\n|          |       | id        | true     | string |                                                                                                          |\n| if       | 3 up  |           |          |        |                                                                                                          |\n|          |       | test      | true     | string | expression, support nil check use nil()\u003cbr/\u003emiddleware: [govaluate](https://github.com/Knetic/govaluate) |\n| foreach  | 3 up  |           |          |        |                                                                                                          |\n|          |       | params    | true     | string | param key, param type can be map or slice                                                                |\n|          |       | open      | false    | string |                                                                                                          |\n|          |       | separator | false    | string |                                                                                                          |\n|          |       | close     | false    | string |                                                                                                          |\n| where    | 3 up  |           |          |        |                                                                                                          |\n| orderBy  | 3 up  |           |          |        |                                                                                                          |\n|          |       | last      | false    | bool   | for QueryPage                                                                                            |\n\n## jcron\n\n### Configuration\n\nConfiguration file default `json` format, you can use `jcron.SetFormat` to set you want, but you must be used\n[jfile.RegisterCodec](#RegisterCodec) register codec.\n\n| Property Name    | Required | Type                   | Default Value | Comment                            |\n|------------------|----------|------------------------|---------------|------------------------------------|\n| Location         | false    | string                 | empty         | time location                      |\n| Schedule         | true     | []*SchInfo             | empty         |                                    |\n| Schedule.Name    | true     | string                 | empty         | schedule name.                     |\n| Schedule.Cron    | true     | string                 | empty         | [CronExpression](#CronExpression). |\n| Schedule.JobName | true     | string                 | empty         | schedule job name.                 |\n| Schedule.JobData | false    | map[string]interface{} | empty         | schedule job data.                 |\n| Schedule.Desc    | false    | string                 | empty         | schedule job description.          |\n| Schedule.Status  | false    | string                 | run           | schedule status.                   |\n\n### Usage\n\n#### config.json\n\n```json\n{\n  \"cron\": {\n    \"schedule\": [\n      {\n        \"Name\": \"Sch01\",\n        \"Cron\": \"7-43/13 * * * * ? *\",\n        \"JobName\": \"Job01\",\n        \"JobData\": {\n          \"data\": \"val\"\n        },\n        \"Desc\": \"this is schedule 01-----------\"\n      },\n      {\n        \"Name\": \"Sch02\",\n        \"Cron\": \"3,7,11,32-57/7 * * * * ? *\",\n        \"JobName\": \"Job02\",\n        \"JobData\": {},\n        \"Desc\": \"this is schedule 02-----------\"\n      }\n    ]\n  }\n}\n```\n\n#### main.go\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"github.com/xjustloveux/jgo/jcron\"\n\t\"github.com/xjustloveux/jgo/jtime\"\n\t\"time\"\n)\n\nfunc main() {\n\tif err := jcron.Init(); err != nil {\n\t\tfmt.Println(err)\n\t\treturn\n\t}\n\tif err := jcron.AddJobFunc(\"Job01\", Job01); err != nil {\n\t\tfmt.Println(err)\n\t\treturn\n\t}\n\tif err := jcron.AddJobFunc(\"Job02\", Job02); err != nil {\n\t\tfmt.Println(err)\n\t\treturn\n\t}\n\tjcron.Start()\n\tselect {\n\tcase \u003c-time.After(3 * jtime.Minute):\n\t}\n\tjcron.Wait()\n}\n\nfunc Job01(data map[string]interface{}) {\n\t// do something\n}\n\nfunc Job02(data map[string]interface{}) {\n\t// do something\n}\n```\n\n### CronExpression\n\n| Name         | Required | Allowed Values                      | Allowed Special Characters |\n|--------------|----------|-------------------------------------|----------------------------|\n| Seconds      | true     | 0-59                                | ,-*/                       |\n| Minutes      | true     | 0-59                                | ,-*/                       |\n| Hours        | true     | 0-23                                | ,-*/                       |\n| Day of month | true     | 1-31                                | ,-*/?                      |\n| Month        | true     | 1-12 or January-December or JAN-DEC | ,-*/                       |\n| Day of week  | true     | 0-6 or Sunday-Saturday or SUN-SAT   | ,-*/?                      |\n| Year         | false    | 2020-2080                           | ,-*/                       |\n\n## jlog\n\n### Configuration\n\nConfiguration file default `json` format, you can use `jlog.SetFormat` to set you want, but you must be used\n[jfile.RegisterCodec](#RegisterCodec) register codec.\n\n| Property Name                        | Required | Type                   | Default Value                                          | Comment                                                                                                              |\n|--------------------------------------|----------|------------------------|--------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------|\n| Params                               | false    | map[string]interface{} | empty                                                  | `Appender.Output.P` and `Appender.Output.LinkName` replace params                                                    |\n| Default                              | false    | []string               | empty                                                  | Appender name                                                                                                        |\n| Appender                             | true     | map[string]interface{} | empty                                                  |                                                                                                                      |\n| Appender.Level                       | false    | string                 | info                                                   | `logrus.Level`                                                                                                       |\n| Appender.ReportCaller                | false    | bool                   | true                                                   | `logrus.ReportCaller`                                                                                                |\n| Appender.Formatter                   | false    | *formatter             | default formatter                                      |                                                                                                                      |\n| Appender.Formatter.Type              | false    | string                 | TEXT                                                   | `TEXT`, `JSON`                                                                                                       |\n| Appender.Formatter.Location          | false    | string                 | empty                                                  | time location                                                                                                        |\n| Appender.Formatter.Text              | false    | *logrus.TextFormatter  | \u0026logrus.TextFormatter{TimestampFormat: jtime.DateTime} |                                                                                                                      |\n| Appender.Formatter.Json              | false    | *logrus.JSONFormatter  | \u0026logrus.JSONFormatter{TimestampFormat: jtime.DateTime} |                                                                                                                      |\n| Appender.Output                      | true     | *output                | default output                                         |                                                                                                                      |\n| Appender.Output.Name                 | false    | string                 | empty                                                  | writer name. you can use `.AddWriter` add writer before `.Init`                                                      |\n| Appender.Output.P                    | true     | string                 | empty                                                  | log file path. default `${Program}` tag replace program name. time format refer to [FormatString](#FormatString)     |\n| Appender.Output.Clock                | false    | string                 | Local                                                  | `*time.Location` string, use for file path time format.                                                              |\n| Appender.Output.LinkName             | false    | string                 | empty                                                  | symlink file path. default `${Program}` tag replace program name. time format refer to [FormatString](#FormatString) |\n| Appender.Output.MaxAge               | false    | time.Duration          | 365                                                    | MaxAge number                                                                                                        |\n| Appender.Output.MaxAgeDuration       | false    | string                 | Day                                                    | Nanosecond, Microsecond, Millisecond, Second, Minute, Hour, Day                                                      |\n| Appender.Output.RotationTime         | false    | time.Duration          | 24                                                     | RotationTime number                                                                                                  |\n| Appender.Output.RotationTimeDuration | false    | string                 | Hour                                                   | Nanosecond, Microsecond, Millisecond, Second, Minute, Hour, Day                                                      |\n| Appender.Output.RotationSize         | false    | int64                  | 10                                                     | RotationSize number                                                                                                  |\n| Appender.Output.RotationSizeUnit     | false    | string                 | MB                                                     | Byte, Kb, KB, Mb, MB, Gb, GB, Tb, TB, Pb, PB, Eb, EB                                                                 |\n| Appender.Output.RotationCount        | false    | int                    | 0                                                      | RotationCount number                                                                                                 |\n| Appender.Output.Handler              | false    | string                 | empty                                                  | handler name. you can use `.AddHandler` add handler before `.Init`                                                   |\n| Logs                                 | true     | []*logs                | empty                                                  |                                                                                                                      |\n| Logs.Program                         | true     | []string               | empty                                                  | go program name. ex: `main` or `main.go` or `pkg:sample`                                                             |\n| Logs.Appender                        | true     | []string               | empty                                                  | Appender name.                                                                                                       |\n\n***Note:* `jlog.Init` default create 'default' program name and 'console' appender name.**\n\n### Usage\n\n#### config.json\n\n```json\n{\n  \"log\": {\n    \"params\": {\n      \"path\": \"/log\"\n    },\n    \"appender\": {\n      \"sys\": {\n        \"level\": \"Error\",\n        \"formatter\": {\n          \"type\": \"JSON\"\n        },\n        \"output\": {\n          \"p\": \"${path}/sys/%yyyy-%MM-%dd/system.log\",\n          \"utc\": false,\n          \"linkName\": \"${path}/sys/system\",\n          \"rotationSize\": 100,\n          \"rotationSizeUnit\": \"KB\"\n        }\n      },\n      \"web\": {\n        \"formatter\": {\n          \"text\": {\n            \"timestampFormat\": \"2006-01-02\"\n          }\n        },\n        \"output\": {\n          \"p\": \"${path}/web/%yyyy-%MM-%dd/website.log\",\n          \"linkName\": \"${path}/web/website\"\n        }\n      }\n    },\n    \"logs\": [\n      {\n        \"program\": [\n          \"program1\",\n          \"main\"\n        ],\n        \"appender\": [\n          \"sys\"\n        ]\n      },\n      {\n        \"program\": [\n          \"program2\"\n        ],\n        \"appender\": [\n          \"console\",\n          \"web\"\n        ]\n      },\n      {\n        \"program\": [\n          \"pkg:packageName\"\n        ],\n        \"appender\": [\n          \"console\",\n          \"sys\"\n        ]\n      }\n    ]\n  }\n}\n```\n\n#### main.go\n\nsys appender log\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"github.com/xjustloveux/jgo/jlog\"\n\t\"time\"\n)\n\nfunc main() {\n\tif err := jlog.Init(); err != nil {\n\t\tfmt.Println(err)\n\t\treturn\n\t}\n\tjlog.Info(\"info message\")\n\tjlog.Warn(time.Now())\n\tjlog.Error(fmt.Errorf(\"error message\"))\n}\n```\n\n#### program2.go\n\nconsole and web appender log\n\n```go\npackage main\n\nfunc example() {\n\tjlog.Info(\"this is program2\")\n}\n```\n\n## jfile\n\n### Convert\n\n```go\ntype Example struct{\nstr string\n}\n\nm := make(map[string]interface{})\nm[\"str\"] = \"example\"\nex := Example{}\n\njfile.Convert(m, \u0026ex)\n```\n\n### RegisterCodec\n\n```go\npackage main\n\nimport (\n\t\"encoding/json\"\n\t\"github.com/xjustloveux/jgo/jfile\"\n)\n\ntype jsonCodec struct{}\n\nfunc (jsonCodec) Encode(m map[string]interface{}) ([]byte, error) {\n\treturn json.MarshalIndent(m, \"\", \"  \")\n}\n\nfunc (jsonCodec) Decode(b []byte, m map[string]interface{}) error {\n\treturn json.Unmarshal(b, \u0026m)\n}\n\nfunc main() {\n\tjfile.RegisterCodec(jfile.Json.String(), jsonCodec{})\n}\n```\n\n## jtime\n\n### FormatString\n\nE.g. 2022-06-20 14:44:55.012345678 -0700 MST IN America/Phoenix Location\n\n| Pattern | Description                                | E.g.            |\n|---------|--------------------------------------------|-----------------|\n| %d      | day in month, 1-31                         | 20              |\n| %dd     | day in month, 01-31                        | 20              |\n| %ddd    | day in week, Sun-Mon                       | Mon             |\n| %dddd   | day in week, Sunday-Monday                 | Monday          |\n| %D      | day in year, 1-366                         | 171             |\n| %DD     | day in year, 01-366                        | 171             |\n| %DDD    | day in year, 001-366                       | 171             |\n| %f      | nanosecond, 0-9999                         | 0               |\n| %ff     | nanosecond, 00-9999                        | 01              |\n| %fff    | nanosecond, 000-9999                       | 012             |\n| %ffff   | nanosecond, 0000-9999                      | 0123            |\n| %F      | nanosecond, -9999                          |                 |\n| %FF     | nanosecond, -9999                          | 01              |\n| %FFF    | nanosecond, -9999                          | 012             |\n| %FFFF   | nanosecond, -9999                          | 0123            |\n| %g      | Era designator, A.D. or B.C.               | A.D.            |\n| %h      | hour in day, 0-11                          | 2               |\n| %hh     | hour in day, 00-11                         | 02              |\n| %H      | hour in day, 0-23                          | 14              |\n| %HH     | hour in day, 00-23                         | 14              |\n| %k      | hour in day, 1-12                          | 2               |\n| %kk     | hour in day, 01-12                         | 02              |\n| %K      | hour in day, 1-24                          | 14              |\n| %KK     | hour in day, 01-24                         | 14              |\n| %l      | time zone name                             | America/Phoenix |\n| %m      | minute in hour, 0-59                       | 44              |\n| %mm     | minute in hour, 00-59                      | 44              |\n| %M      | month in year, 1-12                        | 6               |\n| %MM     | month in year, 01-12                       | 06              |\n| %MMM    | month in year, Jan-Dec                     | Jun             |\n| %MMMM   | month in year, January-December            | June            |\n| %s      | second in minute, 0-59                     | 55              |\n| %ss     | second in minute, 00-59                    | 55              |\n| %t      | AM/PM marker                               | P               |\n| %tt     | AM/PM marker                               | PM              |\n| %w      | week in year, 1-53                         | 25              |\n| %W      | day in week, 0-6                           | 1               |\n| %y      | year                                       | 22              |\n| %yy     | year                                       | 22              |\n| %yyy    | year                                       | 2022            |\n| %yyyy   | year                                       | 2022            |\n| %z      | time zone offset from UTC, hour            | -7              |\n| %zz     | time zone offset from UTC, hour            | -07             |\n| %zzz    | time zone offset from UTC, hour and minute | -07:00          |\n| %zzzz   | time zone offset from UTC, second          | -25200          |\n| %Z      | time zone name                             | MST             |\n\n# Environment\n\n---\n\njsql, jlog, jcron, jconf support environment variables.\n\nConfig required to be set file name, this file will be basic setting.\n\njsql, jlog, jcron default file name is 'config.json'.\n\nYou can override the basic setting by setting the env file name, env val or env key.\n\n### Example1\n\n#### default.json\n\n```json\n{\n  \"val\": 123,\n  \"type\": \"default\"\n}\n```\n\n#### override.json\n\n```json\n{\n  \"type\": \"override\",\n  \"name\": \"test\"\n}\n```\n\n#### main.go\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"github.com/xjustloveux/jgo/jconf\"\n)\n\nfunc main() {\n\tconf := jconf.New()\n\tconf.SetFileName(\"default.json\")\n\tconf.SetEnvFileName(\"override.json\")\n\tif err := conf.Load(); err != nil {\n\t\tfmt.Println(err)\n\t}\n}\n```\n\n#### last json data\n\n```json\n{\n  \"val\": 123,\n  \"type\": \"override\",\n  \"name\": \"test\"\n}\n```\n\n### Example2\n\n#### main.go\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"github.com/xjustloveux/jgo/jconf\"\n)\n\nfunc main() {\n\tconf := jconf.New()\n\tconf.SetFileName(\"default.json\")\n\tconf.SetEnvVal(\"dev\")\n\t// Override file name is 'default-dev.json'.\n\tif err := conf.Load(); err != nil {\n\t\tfmt.Println(err)\n\t}\n}\n```\n\n### Example3\n\n#### main.go\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"github.com/xjustloveux/jgo/jconf\"\n)\n\nfunc main() {\n\tconf := jconf.New()\n\tconf.SetFileName(\"default.json\")\n\tconf.SetEnvKey(\"goEnv\")\n\t// If the 'default.json' file or os have 'goEnv' environment variables.\n\t// Override file name is 'default-$goEnv.json'.\n\t// E.g. goEnv value is 'dev', then the override file name is 'default-dev.json'.\n\tif err := conf.Load(); err != nil {\n\t\tfmt.Println(err)\n\t}\n}\n```\n\n### Example4\n\n#### main.go\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"github.com/xjustloveux/jgo/jconf\"\n)\n\nfunc main() {\n\tconf := jconf.New()\n\tconf.SetFileName(\"default.json\")\n\t// If the 'default.json' file or os have 'jEnv' environment variables.\n\t// Override file name is 'default-$jEnv.json'.\n\t// E.g. jEnv value is 'dev', then the override file name is 'default-dev.json'.\n\tif err := conf.Load(); err != nil {\n\t\tfmt.Println(err)\n\t}\n}\n```\n\n# API\n\n---\n\n[jcast](https://pkg.go.dev/github.com/xjustloveux/jgo/jcast) ,\n[jconf](https://pkg.go.dev/github.com/xjustloveux/jgo/jconf) ,\n[jcron](https://pkg.go.dev/github.com/xjustloveux/jgo/jcron) ,\n[jevent](https://pkg.go.dev/github.com/xjustloveux/jgo/jevent) ,\n[jfile](https://pkg.go.dev/github.com/xjustloveux/jgo/jfile) ,\n[jlog](https://pkg.go.dev/github.com/xjustloveux/jgo/jlog) ,\n[jruntime](https://pkg.go.dev/github.com/xjustloveux/jgo/jruntime) ,\n[jslice](https://pkg.go.dev/github.com/xjustloveux/jgo/jslice) ,\n[jsql](https://pkg.go.dev/github.com/xjustloveux/jgo/jsql) ,\n[jtime](https://pkg.go.dev/github.com/xjustloveux/jgo/jtime)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxjustloveux%2Fjgo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fxjustloveux%2Fjgo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxjustloveux%2Fjgo/lists"}