mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-26 12:27:06 +00:00 
			
		
		
		
	upgrade to use testfixtures v3 (#11904)
* upgrade to use testfixtures v3 * simplify logic * make vendor * update per @lunny * Update templates/repo/empty.tmpl * Update templates/repo/empty.tmpl Co-authored-by: Lauris BH <lauris@nix.lv>
This commit is contained in:
		| @@ -37,7 +37,6 @@ import ( | |||||||
| 	"github.com/go-git/go-git/v5/plumbing" | 	"github.com/go-git/go-git/v5/plumbing" | ||||||
| 	context2 "github.com/gorilla/context" | 	context2 "github.com/gorilla/context" | ||||||
| 	"github.com/unknwon/com" | 	"github.com/unknwon/com" | ||||||
| 	"gopkg.in/testfixtures.v2" |  | ||||||
| 	"xorm.io/xorm" | 	"xorm.io/xorm" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| @@ -96,14 +95,12 @@ func runPR() { | |||||||
| 	setting.Database.LogSQL = true | 	setting.Database.LogSQL = true | ||||||
| 	//x, err = xorm.NewEngine("sqlite3", "file::memory:?cache=shared") | 	//x, err = xorm.NewEngine("sqlite3", "file::memory:?cache=shared") | ||||||
|  |  | ||||||
| 	var helper testfixtures.Helper = &testfixtures.SQLite{} |  | ||||||
| 	models.NewEngine(context.Background(), func(_ *xorm.Engine) error { | 	models.NewEngine(context.Background(), func(_ *xorm.Engine) error { | ||||||
| 		return nil | 		return nil | ||||||
| 	}) | 	}) | ||||||
| 	models.HasEngine = true | 	models.HasEngine = true | ||||||
| 	//x.ShowSQL(true) | 	//x.ShowSQL(true) | ||||||
| 	err = models.InitFixtures( | 	err = models.InitFixtures( | ||||||
| 		helper, |  | ||||||
| 		path.Join(curDir, "models/fixtures/"), | 		path.Join(curDir, "models/fixtures/"), | ||||||
| 	) | 	) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
|   | |||||||
							
								
								
									
										8
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										8
									
								
								go.mod
									
									
									
									
									
								
							| @@ -44,6 +44,7 @@ require ( | |||||||
| 	github.com/go-redis/redis v6.15.2+incompatible | 	github.com/go-redis/redis v6.15.2+incompatible | ||||||
| 	github.com/go-sql-driver/mysql v1.4.1 | 	github.com/go-sql-driver/mysql v1.4.1 | ||||||
| 	github.com/go-swagger/go-swagger v0.21.0 | 	github.com/go-swagger/go-swagger v0.21.0 | ||||||
|  | 	github.com/go-testfixtures/testfixtures/v3 v3.2.0 | ||||||
| 	github.com/gobwas/glob v0.2.3 | 	github.com/gobwas/glob v0.2.3 | ||||||
| 	github.com/gogs/chardet v0.0.0-20191104214054-4b6791f73a28 | 	github.com/gogs/chardet v0.0.0-20191104214054-4b6791f73a28 | ||||||
| 	github.com/gogs/cron v0.0.0-20171120032916-9f6c956d3e14 | 	github.com/gogs/cron v0.0.0-20171120032916-9f6c956d3e14 | ||||||
| @@ -56,7 +57,6 @@ require ( | |||||||
| 	github.com/issue9/identicon v1.0.1 | 	github.com/issue9/identicon v1.0.1 | ||||||
| 	github.com/jaytaylor/html2text v0.0.0-20160923191438-8fb95d837f7d | 	github.com/jaytaylor/html2text v0.0.0-20160923191438-8fb95d837f7d | ||||||
| 	github.com/jmhodges/levigo v1.0.0 // indirect | 	github.com/jmhodges/levigo v1.0.0 // indirect | ||||||
| 	github.com/joho/godotenv v1.3.0 // indirect |  | ||||||
| 	github.com/kballard/go-shellquote v0.0.0-20170619183022-cd60e84ee657 | 	github.com/kballard/go-shellquote v0.0.0-20170619183022-cd60e84ee657 | ||||||
| 	github.com/keybase/go-crypto v0.0.0-20200123153347-de78d2cb44f4 | 	github.com/keybase/go-crypto v0.0.0-20200123153347-de78d2cb44f4 | ||||||
| 	github.com/klauspost/compress v1.10.2 | 	github.com/klauspost/compress v1.10.2 | ||||||
| @@ -66,8 +66,7 @@ require ( | |||||||
| 	github.com/mailru/easyjson v0.7.0 // indirect | 	github.com/mailru/easyjson v0.7.0 // indirect | ||||||
| 	github.com/markbates/goth v1.61.2 | 	github.com/markbates/goth v1.61.2 | ||||||
| 	github.com/mattn/go-isatty v0.0.11 | 	github.com/mattn/go-isatty v0.0.11 | ||||||
| 	github.com/mattn/go-oci8 v0.0.0-20190320171441-14ba190cf52d // indirect | 	github.com/mattn/go-sqlite3 v2.0.2+incompatible | ||||||
| 	github.com/mattn/go-sqlite3 v1.11.0 |  | ||||||
| 	github.com/mcuadros/go-version v0.0.0-20190308113854-92cdf37c5b75 | 	github.com/mcuadros/go-version v0.0.0-20190308113854-92cdf37c5b75 | ||||||
| 	github.com/mgechev/dots v0.0.0-20190921121421-c36f7dcfbb81 | 	github.com/mgechev/dots v0.0.0-20190921121421-c36f7dcfbb81 | ||||||
| 	github.com/mgechev/revive v1.0.2 | 	github.com/mgechev/revive v1.0.2 | ||||||
| @@ -115,8 +114,7 @@ require ( | |||||||
| 	gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df | 	gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df | ||||||
| 	gopkg.in/ini.v1 v1.52.0 | 	gopkg.in/ini.v1 v1.52.0 | ||||||
| 	gopkg.in/ldap.v3 v3.0.2 | 	gopkg.in/ldap.v3 v3.0.2 | ||||||
| 	gopkg.in/testfixtures.v2 v2.5.0 | 	gopkg.in/yaml.v2 v2.3.0 | ||||||
| 	gopkg.in/yaml.v2 v2.2.8 |  | ||||||
| 	mvdan.cc/xurls/v2 v2.1.0 | 	mvdan.cc/xurls/v2 v2.1.0 | ||||||
| 	strk.kbt.io/projects/go/libravatar v0.0.0-20191008002943-06d1c002b251 | 	strk.kbt.io/projects/go/libravatar v0.0.0-20191008002943-06d1c002b251 | ||||||
| 	xorm.io/builder v0.3.7 | 	xorm.io/builder v0.3.7 | ||||||
|   | |||||||
							
								
								
									
										15
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								go.sum
									
									
									
									
									
								
							| @@ -149,6 +149,7 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs | |||||||
| github.com/denisenkom/go-mssqldb v0.0.0-20190707035753-2be1aa521ff4/go.mod h1:zAg7JM8CkOJ43xKXIj7eRO9kmWm/TW578qo+oDO6tuM= | github.com/denisenkom/go-mssqldb v0.0.0-20190707035753-2be1aa521ff4/go.mod h1:zAg7JM8CkOJ43xKXIj7eRO9kmWm/TW578qo+oDO6tuM= | ||||||
| github.com/denisenkom/go-mssqldb v0.0.0-20190924004331-208c0a498538 h1:bpWCJ5MddHsv4Xtl3azkK89mZzd/vvut32mvAnKbyUA= | github.com/denisenkom/go-mssqldb v0.0.0-20190924004331-208c0a498538 h1:bpWCJ5MddHsv4Xtl3azkK89mZzd/vvut32mvAnKbyUA= | ||||||
| github.com/denisenkom/go-mssqldb v0.0.0-20190924004331-208c0a498538/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= | github.com/denisenkom/go-mssqldb v0.0.0-20190924004331-208c0a498538/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= | ||||||
|  | github.com/denisenkom/go-mssqldb v0.0.0-20191128021309-1d7a30a10f73/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= | ||||||
| github.com/denisenkom/go-mssqldb v0.0.0-20200428022330-06a60b6afbbc h1:VRRKCwnzqk8QCaRC4os14xoKDdbHqqlJtJA0oc1ZAjg= | github.com/denisenkom/go-mssqldb v0.0.0-20200428022330-06a60b6afbbc h1:VRRKCwnzqk8QCaRC4os14xoKDdbHqqlJtJA0oc1ZAjg= | ||||||
| github.com/denisenkom/go-mssqldb v0.0.0-20200428022330-06a60b6afbbc/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= | github.com/denisenkom/go-mssqldb v0.0.0-20200428022330-06a60b6afbbc/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= | ||||||
| github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= | github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= | ||||||
| @@ -278,6 +279,8 @@ github.com/go-swagger/go-swagger v0.21.0 h1:AX9mdfzp6eJtUe92nFrWmbK7ocRgkCDPJs0F | |||||||
| github.com/go-swagger/go-swagger v0.21.0/go.mod h1:tDb8PdDVFcaE8EPXkMOsuxpL3UEPiwu1UDZar9Z/1RY= | github.com/go-swagger/go-swagger v0.21.0/go.mod h1:tDb8PdDVFcaE8EPXkMOsuxpL3UEPiwu1UDZar9Z/1RY= | ||||||
| github.com/go-swagger/scan-repo-boundary v0.0.0-20180623220736-973b3573c013 h1:l9rI6sNaZgNC0LnF3MiE+qTmyBA/tZAg1rtyrGbUMK0= | github.com/go-swagger/scan-repo-boundary v0.0.0-20180623220736-973b3573c013 h1:l9rI6sNaZgNC0LnF3MiE+qTmyBA/tZAg1rtyrGbUMK0= | ||||||
| github.com/go-swagger/scan-repo-boundary v0.0.0-20180623220736-973b3573c013/go.mod h1:b65mBPzqzZWxOZGxSWrqs4GInLIn+u99Q9q7p+GKni0= | github.com/go-swagger/scan-repo-boundary v0.0.0-20180623220736-973b3573c013/go.mod h1:b65mBPzqzZWxOZGxSWrqs4GInLIn+u99Q9q7p+GKni0= | ||||||
|  | github.com/go-testfixtures/testfixtures/v3 v3.2.0 h1:FGAW3z5UzmrZGjR/dZp1u3Tbld0SDmirLO4RrR5++7Q= | ||||||
|  | github.com/go-testfixtures/testfixtures/v3 v3.2.0/go.mod h1:RZctY24ixituGC73XlAV1gkCwYMVwiSwPm26MNlQIhE= | ||||||
| github.com/go-xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:9wScpmSP5A3Bk8V3XHWUcJmYTh+ZnlHVyc+A4oZYS3Y= | github.com/go-xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:9wScpmSP5A3Bk8V3XHWUcJmYTh+ZnlHVyc+A4oZYS3Y= | ||||||
| github.com/go-xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:56xuuqnHyryaerycW3BfssRdxQstACi0Epw/yC5E2xM= | github.com/go-xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:56xuuqnHyryaerycW3BfssRdxQstACi0Epw/yC5E2xM= | ||||||
| github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= | github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= | ||||||
| @@ -437,6 +440,7 @@ github.com/lestrrat-go/jwx v0.9.0/go.mod h1:iEoxlYfZjvoGpuWwxUz+eR5e6KTJGsaRcy/Y | |||||||
| github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= | github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= | ||||||
| github.com/lib/pq v1.2.0 h1:LXpIM/LZ5xGFhOpXAQUIMM1HdyqzVYM13zNdjCEEcA0= | github.com/lib/pq v1.2.0 h1:LXpIM/LZ5xGFhOpXAQUIMM1HdyqzVYM13zNdjCEEcA0= | ||||||
| github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= | github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= | ||||||
|  | github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= | ||||||
| github.com/lib/pq v1.7.0 h1:h93mCPfUSkaul3Ka/VG8uZdmW1uMHDGxzu0NWHuJmHY= | github.com/lib/pq v1.7.0 h1:h93mCPfUSkaul3Ka/VG8uZdmW1uMHDGxzu0NWHuJmHY= | ||||||
| github.com/lib/pq v1.7.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= | github.com/lib/pq v1.7.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= | ||||||
| github.com/lunny/dingtalk_webhook v0.0.0-20171025031554-e3534c89ef96 h1:uNwtsDp7ci48vBTTxDuwcoTXz4lwtDTe7TjCQ0noaWY= | github.com/lunny/dingtalk_webhook v0.0.0-20171025031554-e3534c89ef96 h1:uNwtsDp7ci48vBTTxDuwcoTXz4lwtDTe7TjCQ0noaWY= | ||||||
| @@ -462,13 +466,13 @@ github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVc | |||||||
| github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= | github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= | ||||||
| github.com/mattn/go-isatty v0.0.11 h1:FxPOTFNqGkuDUGi3H/qkUbQO4ZiBa2brKq5r0l8TGeM= | github.com/mattn/go-isatty v0.0.11 h1:FxPOTFNqGkuDUGi3H/qkUbQO4ZiBa2brKq5r0l8TGeM= | ||||||
| github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= | github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= | ||||||
| github.com/mattn/go-oci8 v0.0.0-20190320171441-14ba190cf52d h1:m+dSK37rFf2fqppZhg15yI2IwC9BtucBiRwSDm9VL8g= |  | ||||||
| github.com/mattn/go-oci8 v0.0.0-20190320171441-14ba190cf52d/go.mod h1:/M9VLO+lUPmxvoOK2PfWRZ8mTtB4q1Hy9lEGijv9Nr8= |  | ||||||
| github.com/mattn/go-runewidth v0.0.7 h1:Ei8KR0497xHyKJPAv59M1dkC+rOZCMBJ+t3fZ+twI54= | github.com/mattn/go-runewidth v0.0.7 h1:Ei8KR0497xHyKJPAv59M1dkC+rOZCMBJ+t3fZ+twI54= | ||||||
| github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= | github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= | ||||||
| github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= | github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= | ||||||
| github.com/mattn/go-sqlite3 v1.11.0 h1:LDdKkqtYlom37fkvqs8rMPFKAMe8+SgjbwZ6ex1/A/Q= | github.com/mattn/go-sqlite3 v1.11.0 h1:LDdKkqtYlom37fkvqs8rMPFKAMe8+SgjbwZ6ex1/A/Q= | ||||||
| github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= | github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= | ||||||
|  | github.com/mattn/go-sqlite3 v2.0.2+incompatible h1:qzw9c2GNT8UFrgWNDhCTqRqYUSmu/Dav/9Z58LGpk7U= | ||||||
|  | github.com/mattn/go-sqlite3 v2.0.2+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= | ||||||
| github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= | github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= | ||||||
| github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= | github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= | ||||||
| github.com/mcuadros/go-version v0.0.0-20190308113854-92cdf37c5b75 h1:Pijfgr7ZuvX7QIQiEwLdRVr3RoMG+i0SbBO1Qu+7yVk= | github.com/mcuadros/go-version v0.0.0-20190308113854-92cdf37c5b75 h1:Pijfgr7ZuvX7QIQiEwLdRVr3RoMG+i0SbBO1Qu+7yVk= | ||||||
| @@ -610,6 +614,8 @@ github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmq | |||||||
| github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= | github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= | ||||||
| github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg= | github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg= | ||||||
| github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= | github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= | ||||||
|  | github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= | ||||||
|  | github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= | ||||||
| github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= | github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= | ||||||
| github.com/spf13/viper v1.4.0 h1:yXHLWeravcrgGyFSyCgdYpXQ9dR9c/WED3pg1RhxqEU= | github.com/spf13/viper v1.4.0 h1:yXHLWeravcrgGyFSyCgdYpXQ9dR9c/WED3pg1RhxqEU= | ||||||
| github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= | github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= | ||||||
| @@ -890,8 +896,6 @@ gopkg.in/ldap.v3 v3.0.2 h1:R6RBtabK6e1GO0eQKtkyOFbAHO73QesLzI2w2DZ6b9w= | |||||||
| gopkg.in/ldap.v3 v3.0.2/go.mod h1:oxD7NyBuxchC+SgJDE1Q5Od05eGt29SDQVBmV+HYbzw= | gopkg.in/ldap.v3 v3.0.2/go.mod h1:oxD7NyBuxchC+SgJDE1Q5Od05eGt29SDQVBmV+HYbzw= | ||||||
| gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= | gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= | ||||||
| gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= | gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= | ||||||
| gopkg.in/testfixtures.v2 v2.5.0 h1:N08B7l2GzFQenyYbzqthDnKAA+cmb17iAZhhFxr7JHw= |  | ||||||
| gopkg.in/testfixtures.v2 v2.5.0/go.mod h1:vyAq+MYCgNpR29qitQdLZhdbLFf4mR/2MFJRFoQZZ2M= |  | ||||||
| gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= | gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= | ||||||
| gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= | gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= | ||||||
| gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= | gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= | ||||||
| @@ -902,8 +906,11 @@ gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= | |||||||
| gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= | ||||||
| gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I= | gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I= | ||||||
| gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= | gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= | ||||||
|  | gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= | ||||||
| gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= | gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= | ||||||
| gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= | gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= | ||||||
|  | gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= | ||||||
|  | gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= | ||||||
| honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= | honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= | ||||||
| honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= | honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= | ||||||
| honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= | honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= | ||||||
|   | |||||||
| @@ -36,7 +36,6 @@ import ( | |||||||
| 	"github.com/PuerkitoBio/goquery" | 	"github.com/PuerkitoBio/goquery" | ||||||
| 	"github.com/stretchr/testify/assert" | 	"github.com/stretchr/testify/assert" | ||||||
| 	"github.com/unknwon/com" | 	"github.com/unknwon/com" | ||||||
| 	"gopkg.in/testfixtures.v2" |  | ||||||
| ) | ) | ||||||
|  |  | ||||||
| var mac *macaron.Macaron | var mac *macaron.Macaron | ||||||
| @@ -88,22 +87,7 @@ func TestMain(m *testing.M) { | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	var helper testfixtures.Helper |  | ||||||
| 	if setting.Database.UseMySQL { |  | ||||||
| 		helper = &testfixtures.MySQL{} |  | ||||||
| 	} else if setting.Database.UsePostgreSQL { |  | ||||||
| 		helper = &testfixtures.PostgreSQL{} |  | ||||||
| 	} else if setting.Database.UseSQLite3 { |  | ||||||
| 		helper = &testfixtures.SQLite{} |  | ||||||
| 	} else if setting.Database.UseMSSQL { |  | ||||||
| 		helper = &testfixtures.SQLServer{} |  | ||||||
| 	} else { |  | ||||||
| 		fmt.Println("Unsupported RDBMS for integration tests") |  | ||||||
| 		os.Exit(1) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	err := models.InitFixtures( | 	err := models.InitFixtures( | ||||||
| 		helper, |  | ||||||
| 		path.Join(filepath.Dir(setting.AppPath), "models/fixtures/"), | 		path.Join(filepath.Dir(setting.AppPath), "models/fixtures/"), | ||||||
| 	) | 	) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
|   | |||||||
| @@ -6,18 +6,48 @@ package models | |||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"fmt" | 	"fmt" | ||||||
|  | 	"os" | ||||||
| 	"time" | 	"time" | ||||||
|  |  | ||||||
| 	"gopkg.in/testfixtures.v2" | 	"github.com/go-testfixtures/testfixtures/v3" | ||||||
| 	"xorm.io/xorm/schemas" | 	"xorm.io/xorm/schemas" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| var fixtures *testfixtures.Context | var fixtures *testfixtures.Loader | ||||||
|  |  | ||||||
| // InitFixtures initialize test fixtures for a test database | // InitFixtures initialize test fixtures for a test database | ||||||
| func InitFixtures(helper testfixtures.Helper, dir string) (err error) { | func InitFixtures(dir string) (err error) { | ||||||
| 	testfixtures.SkipDatabaseNameCheck(true) | 	testfiles := testfixtures.Directory(dir) | ||||||
| 	fixtures, err = testfixtures.NewFolder(x.DB().DB, helper, dir) | 	dialect := "unknown" | ||||||
|  | 	switch x.Dialect().URI().DBType { | ||||||
|  | 	case schemas.POSTGRES: | ||||||
|  | 		dialect = "postgres" | ||||||
|  | 	case schemas.MYSQL: | ||||||
|  | 		dialect = "mysql" | ||||||
|  | 	case schemas.MSSQL: | ||||||
|  | 		dialect = "mssql" | ||||||
|  | 	case schemas.SQLITE: | ||||||
|  | 		dialect = "sqlite3" | ||||||
|  | 	default: | ||||||
|  | 		fmt.Println("Unsupported RDBMS for integration tests") | ||||||
|  | 		os.Exit(1) | ||||||
|  | 	} | ||||||
|  | 	loaderOptions := []func(loader *testfixtures.Loader) error{ | ||||||
|  | 		testfixtures.Database(x.DB().DB), | ||||||
|  | 		testfixtures.Dialect(dialect), | ||||||
|  | 		testfixtures.DangerousSkipTestDatabaseCheck(), | ||||||
|  | 		testfiles, | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if x.Dialect().URI().DBType == schemas.POSTGRES { | ||||||
|  | 		loaderOptions = append(loaderOptions, testfixtures.SkipResetSequences()) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	fixtures, err = testfixtures.New(loaderOptions...) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	return err | 	return err | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -19,7 +19,6 @@ import ( | |||||||
|  |  | ||||||
| 	"github.com/stretchr/testify/assert" | 	"github.com/stretchr/testify/assert" | ||||||
| 	"github.com/unknwon/com" | 	"github.com/unknwon/com" | ||||||
| 	"gopkg.in/testfixtures.v2" |  | ||||||
| 	"xorm.io/xorm" | 	"xorm.io/xorm" | ||||||
| 	"xorm.io/xorm/names" | 	"xorm.io/xorm/names" | ||||||
| ) | ) | ||||||
| @@ -101,7 +100,7 @@ func CreateTestEngine(fixturesDir string) error { | |||||||
| 		x.ShowSQL(true) | 		x.ShowSQL(true) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return InitFixtures(&testfixtures.SQLite{}, fixturesDir) | 	return InitFixtures(fixturesDir) | ||||||
| } | } | ||||||
|  |  | ||||||
| func removeAllWithRetry(dir string) error { | func removeAllWithRetry(dir string) error { | ||||||
|   | |||||||
| @@ -23,7 +23,7 @@ _testmain.go | |||||||
| *.test | *.test | ||||||
| *.prof | *.prof | ||||||
| 
 | 
 | ||||||
| # SQLite databases |  | ||||||
| *.sqlite3 | *.sqlite3 | ||||||
| 
 |  | ||||||
| .env | .env | ||||||
|  | /testfixtures | ||||||
|  | /dist | ||||||
							
								
								
									
										41
									
								
								vendor/github.com/go-testfixtures/testfixtures/v3/.goreleaser.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								vendor/github.com/go-testfixtures/testfixtures/v3/.goreleaser.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,41 @@ | |||||||
|  | build: | ||||||
|  |   binary: testfixtures | ||||||
|  |   main: ./cmd/testfixtures | ||||||
|  |   goos: | ||||||
|  |     - windows | ||||||
|  |     - darwin | ||||||
|  |     - linux | ||||||
|  |   goarch: | ||||||
|  |     - 386 | ||||||
|  |     - amd64 | ||||||
|  |   ignore: | ||||||
|  |     - goos: darwin | ||||||
|  |       goarch: 386 | ||||||
|  |   flags: | ||||||
|  |     - -tags=sqlite | ||||||
|  |  | ||||||
|  | archives: | ||||||
|  |   - name_template: "{{.Binary}}_{{.Os}}_{{.Arch}}" | ||||||
|  |     format_overrides: | ||||||
|  |       - goos: windows | ||||||
|  |         format: zip | ||||||
|  |  | ||||||
|  | release: | ||||||
|  |   draft: true | ||||||
|  |  | ||||||
|  | snapshot: | ||||||
|  |   name_template: "{{.Tag}}" | ||||||
|  |  | ||||||
|  | checksum: | ||||||
|  |   name_template: "testfixtures_checksums.txt" | ||||||
|  |  | ||||||
|  | nfpms: | ||||||
|  |   - vendor: testfixtures | ||||||
|  |     homepage: https://github.com/go-testfixtures/testfixtures | ||||||
|  |     maintainer: Andrey Nering <andrey.nering@gmail.com> | ||||||
|  |     description: Ruby on Rails like test fixtures for Go. | ||||||
|  |     license: MIT | ||||||
|  |     formats: | ||||||
|  |       - deb | ||||||
|  |       - rpm | ||||||
|  |     file_name_template: "{{.ProjectName}}_{{.Os}}_{{.Arch}}" | ||||||
| @@ -2,4 +2,3 @@ PG_CONN_STRING="user=postgres dbname=testfixtures_test sslmode=disable" | |||||||
| MYSQL_CONN_STRING="root:@/testfixtures_test?multiStatements=true" | MYSQL_CONN_STRING="root:@/testfixtures_test?multiStatements=true" | ||||||
| SQLITE_CONN_STRING="testdb.sqlite3" | SQLITE_CONN_STRING="testdb.sqlite3" | ||||||
| SQLSERVER_CONN_STRING="server=localhost\SQLExpress;database=testfixtures_test;user id=sa;password=sqlserver;encrypt=disable" | SQLSERVER_CONN_STRING="server=localhost\SQLExpress;database=testfixtures_test;user id=sa;password=sqlserver;encrypt=disable" | ||||||
| ORACLE_CONN_STRING="testfixtures/testfixtures@localhost/XE" |  | ||||||
							
								
								
									
										93
									
								
								vendor/github.com/go-testfixtures/testfixtures/v3/CHANGELOG.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										93
									
								
								vendor/github.com/go-testfixtures/testfixtures/v3/CHANGELOG.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,93 @@ | |||||||
|  | # Changelog | ||||||
|  |  | ||||||
|  | ## v3.2.0 - 2020-05-10 | ||||||
|  |  | ||||||
|  | - Add support for loading multiple files and directories | ||||||
|  |   ([#65](https://github.com/go-testfixtures/testfixtures/pull/65)). | ||||||
|  |  | ||||||
|  | ## v3.1.2 - 2020-04-26 | ||||||
|  |  | ||||||
|  | - Dump: Fix column order in generated YAML files | ||||||
|  |   ([#62](https://github.com/go-testfixtures/testfixtures/pull/62)). | ||||||
|  |  | ||||||
|  | ## v3.1.1 - 2020-01-11 | ||||||
|  |  | ||||||
|  | - testfixtures now work with both `mssql` and `sqlserver` drivers. | ||||||
|  |   Note that [the `mssql` one is deprecated](https://github.com/denisenkom/go-mssqldb#deprecated), | ||||||
|  |   though. So try to migrate to `sqlserver` once possible. | ||||||
|  |  | ||||||
|  | ## v3.1.0 - 2020-01-09 | ||||||
|  |  | ||||||
|  | - Using `sqlserver` driver instead of the deprecated `mssql` | ||||||
|  |   ([#58](https://github.com/go-testfixtures/testfixtures/pull/58)). | ||||||
|  |  | ||||||
|  | ## v3.0.0 - 2019-12-26 | ||||||
|  |  | ||||||
|  | ### Breaking changes | ||||||
|  |  | ||||||
|  | - The import path changed from `gopkg.in/testfixtures.v2` to | ||||||
|  |   `github.com/go-testfixtures/testfixtures/v3`. | ||||||
|  | - This package no longer support Oracle databases. This decision was | ||||||
|  |   taken because too few people actually used this package with Oracle and it | ||||||
|  |   was the most difficult to test (we didn't run on CI due the lack of an | ||||||
|  |   official Docker image, etc). | ||||||
|  | - The public API was totally rewritten to be more flexible and ideomatic. | ||||||
|  |   It now uses functional options. It differs from v2, but should be easy | ||||||
|  |   enough to upgrade. | ||||||
|  | - Some deprecated APIs from v2 were removed as well. | ||||||
|  | - This now requires Go >= 1.13. | ||||||
|  |  | ||||||
|  | ### New features | ||||||
|  |  | ||||||
|  | - We now have a CLI so you can easily use testfixtures to load a sample | ||||||
|  |   database from fixtures if you want. | ||||||
|  | - Templating via [text/template](https://golang.org/pkg/text/template/) | ||||||
|  |   is now available. This allows some fancier use cases like generating data | ||||||
|  |   or specific columns dynamically. | ||||||
|  | - It's now possible to choose which time zone to use when parsing timestamps | ||||||
|  |   from fixtures. The default is the same as before, whatever is set on | ||||||
|  |   `time.Local`. | ||||||
|  | - Errors now use the new `%w` verb only available on Go >= 1.13. | ||||||
|  |  | ||||||
|  | ### MISC | ||||||
|  |  | ||||||
|  | - Travis and AppVeyor are gone. We're using GitHub Actions exclusively now. | ||||||
|  |   The whole suite is ran inside Docker (with help of Docker Compose), so it's | ||||||
|  |   easy to run tests locally as well. | ||||||
|  |  | ||||||
|  | Check the new README for some examples! | ||||||
|  |  | ||||||
|  | ## v2.6.0 - 2019-10-24 | ||||||
|  |  | ||||||
|  | - Add support for TimescaleDB | ||||||
|  |   ([#53](https://github.com/go-testfixtures/testfixtures/pull/53)). | ||||||
|  |  | ||||||
|  | ## v2.5.3 - 2018-12-15 | ||||||
|  |  | ||||||
|  | - Fixes related to use of foreign key pragmas on MySQL (#43). | ||||||
|  |  | ||||||
|  | ## v2.5.2 - 2018-11-25 | ||||||
|  |  | ||||||
|  | - This library now supports [Go Modules](https://github.com/golang/go/wiki/Modules); | ||||||
|  | - Also allow `.yaml` (as an alternative to `.yml`) as the file extension (#42). | ||||||
|  |  | ||||||
|  | ## v2.5.1 - 2018-11-04 | ||||||
|  |  | ||||||
|  | - Allowing disabling reset of PostgreSQL sequences (#38). | ||||||
|  |  | ||||||
|  | ## v2.5.0 - 2018-09-07 | ||||||
|  |  | ||||||
|  | - Add public function DetectTestDatabase (#35, #36). | ||||||
|  |  | ||||||
|  | ## v2.4.5 - 2018-07-07 | ||||||
|  |  | ||||||
|  | - Fix for MySQL/MariaDB: ignoring views on operations that should be run only on tables (#33). | ||||||
|  |  | ||||||
|  | ## v2.4.4 - 2018-07-02 | ||||||
|  |  | ||||||
|  | - Fix for multiple schemas on Microsoft SQL Server (#29 and #30); | ||||||
|  | - Configuring AppVeyor CI to also test for Microsoft SQL Server. | ||||||
|  |  | ||||||
|  | --- | ||||||
|  |  | ||||||
|  | Sorry, we don't have changelog for older releases 😢. | ||||||
							
								
								
									
										9
									
								
								vendor/github.com/go-testfixtures/testfixtures/v3/Dockerfile
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								vendor/github.com/go-testfixtures/testfixtures/v3/Dockerfile
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | |||||||
|  | FROM golang:1.14-alpine | ||||||
|  |  | ||||||
|  | RUN apk update | ||||||
|  | RUN apk add alpine-sdk | ||||||
|  |  | ||||||
|  | WORKDIR /testfixtures | ||||||
|  | COPY . . | ||||||
|  |  | ||||||
|  | RUN go mod download | ||||||
							
								
								
									
										483
									
								
								vendor/github.com/go-testfixtures/testfixtures/v3/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										483
									
								
								vendor/github.com/go-testfixtures/testfixtures/v3/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,483 @@ | |||||||
|  | # testfixtures | ||||||
|  |  | ||||||
|  | [][doc] | ||||||
|  |  | ||||||
|  | > ***Warning***: this package will wipe the database data before loading the | ||||||
|  | fixtures! It is supposed to be used on a test database. Please, double check | ||||||
|  | if you are running it against the correct database. | ||||||
|  |  | ||||||
|  | > **TIP**: There are options not described in this README page. It's | ||||||
|  | > recommended that you also check [the documentation][doc]. | ||||||
|  |  | ||||||
|  | Writing tests is hard, even more when you have to deal with an SQL database. | ||||||
|  | This package aims to make writing functional tests for web apps written in | ||||||
|  | Go easier. | ||||||
|  |  | ||||||
|  | Basically this package mimics the ["Ruby on Rails' way"][railstests] of writing tests | ||||||
|  | for database applications, where sample data is kept in fixtures files. Before | ||||||
|  | the execution of every test, the test database is cleaned and the fixture data | ||||||
|  | is loaded into the database. | ||||||
|  |  | ||||||
|  | The idea is running tests against a real database, instead of relying in mocks, | ||||||
|  | which is boring to setup and may lead to production bugs not being caught in | ||||||
|  | the tests. | ||||||
|  |  | ||||||
|  | ## Installation | ||||||
|  |  | ||||||
|  | First, import it like this: | ||||||
|  |  | ||||||
|  | ```go | ||||||
|  | import ( | ||||||
|  |         "github.com/go-testfixtures/testfixtures/v3" | ||||||
|  | ) | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | ## Usage | ||||||
|  |  | ||||||
|  | Create a folder for the fixture files. Each file should contain data for a | ||||||
|  | single table and have the name `<table_name>.yml`: | ||||||
|  |  | ||||||
|  | ``` | ||||||
|  | myapp/ | ||||||
|  |   myapp.go | ||||||
|  |   myapp_test.go | ||||||
|  |   ... | ||||||
|  |   fixtures/ | ||||||
|  |     posts.yml | ||||||
|  |     comments.yml | ||||||
|  |     tags.yml | ||||||
|  |     posts_tags.yml | ||||||
|  |     ... | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | The file would look like this (it can have as many record you want): | ||||||
|  |  | ||||||
|  | ```yml | ||||||
|  | # comments.yml | ||||||
|  | - id: 1 | ||||||
|  |   post_id: 1 | ||||||
|  |   content: A comment... | ||||||
|  |   author_name: John Doe | ||||||
|  |   author_email: john@doe.com | ||||||
|  |   created_at: 2020-12-31 23:59:59 | ||||||
|  |   updated_at: 2020-12-31 23:59:59 | ||||||
|  |  | ||||||
|  | - id: 2 | ||||||
|  |   post_id: 2 | ||||||
|  |   content: Another comment... | ||||||
|  |   author_name: John Doe | ||||||
|  |   author_email: john@doe.com | ||||||
|  |   created_at: 2020-12-31 23:59:59 | ||||||
|  |   updated_at: 2020-12-31 23:59:59 | ||||||
|  |  | ||||||
|  | # ... | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | An YAML object or array will be converted to JSON. It will be stored on a native | ||||||
|  | JSON type like JSONB on PostgreSQL or as a TEXT or VARCHAR column on other | ||||||
|  | databases. | ||||||
|  |  | ||||||
|  | ```yml | ||||||
|  | - id: 1 | ||||||
|  |   post_attributes: | ||||||
|  |     author: John Due | ||||||
|  |     author_email: john@due.com | ||||||
|  |     title: "..." | ||||||
|  |     tags: | ||||||
|  |       - programming | ||||||
|  |       - go | ||||||
|  |       - testing | ||||||
|  |     post: "..." | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | If you need to write raw SQL, probably to call a function, prefix the value | ||||||
|  | of the column with `RAW=`: | ||||||
|  |  | ||||||
|  | ```yml | ||||||
|  | - id: 1 | ||||||
|  |   uuid_column: RAW=uuid_generate_v4() | ||||||
|  |   postgis_type_column: RAW=ST_GeomFromText('params...') | ||||||
|  |   created_at: RAW=NOW() | ||||||
|  |   updated_at: RAW=NOW() | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | Your tests would look like this: | ||||||
|  |  | ||||||
|  | ```go | ||||||
|  | package myapp | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  |         "database/sql" | ||||||
|  |  | ||||||
|  |         _ "github.com/lib/pq" | ||||||
|  |         "github.com/go-testfixtures/testfixtures/v3" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | var ( | ||||||
|  |         db *sql.DB | ||||||
|  |         fixtures *testfixtures.Loader | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | func TestMain(m *testing.M) { | ||||||
|  |         var err error | ||||||
|  |  | ||||||
|  |         // Open connection to the test database. | ||||||
|  |         // Do NOT import fixtures in a production database! | ||||||
|  |         // Existing data would be deleted. | ||||||
|  |         db, err = sql.Open("postgres", "dbname=myapp_test") | ||||||
|  |         if err != nil { | ||||||
|  |                 ... | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         fixtures, err := testfixtures.New( | ||||||
|  |                 testfixtures.Database(db), // You database connection | ||||||
|  |                 testfixtures.Dialect("postgres"), // Available: "postgresql", "timescaledb", "mysql", "mariadb", "sqlite" and "sqlserver" | ||||||
|  |                 testfixtures.Directory("testdata/fixtures"), // the directory containing the YAML files | ||||||
|  |         ) | ||||||
|  |         if err != nil { | ||||||
|  |                 ... | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         os.Exit(m.Run()) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func prepareTestDatabase() { | ||||||
|  |         if err := fixtures.Load(); err != nil { | ||||||
|  |                 ... | ||||||
|  |         } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func TestX(t *testing.T) { | ||||||
|  |         prepareTestDatabase() | ||||||
|  |  | ||||||
|  |         // Your test here ... | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func TestY(t *testing.T) { | ||||||
|  |         prepareTestDatabase() | ||||||
|  |  | ||||||
|  |         // Your test here ... | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func TestZ(t *testing.T) { | ||||||
|  |         prepareTestDatabase() | ||||||
|  |  | ||||||
|  |         // Your test here ... | ||||||
|  | } | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | Alternatively, you can use the `Files` option, to specify which | ||||||
|  | files you want to load into the database: | ||||||
|  |  | ||||||
|  | ```go | ||||||
|  | fixtures, err := testfixtures.New( | ||||||
|  |         testfixtures.Database(db), | ||||||
|  |         testfixtures.Dialect("postgres"), | ||||||
|  |         testfixtures.Files( | ||||||
|  |                 "fixtures/orders.yml", | ||||||
|  |                 "fixtures/customers.yml", | ||||||
|  |         ), | ||||||
|  | ) | ||||||
|  | if err != nil { | ||||||
|  |         ... | ||||||
|  | } | ||||||
|  |  | ||||||
|  | fixtures, err := testfixtures.NewFiles(db, &testfixtures.PostgreSQL{}, | ||||||
|  |         "fixtures/orders.yml", | ||||||
|  |         "fixtures/customers.yml", | ||||||
|  |         // add as many files you want | ||||||
|  | ) | ||||||
|  | if err != nil { | ||||||
|  |         ... | ||||||
|  | } | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | With `Paths` option, you can specify the paths that fixtures will load | ||||||
|  | from. Path can be directory or file. If directory, we will search YAML files | ||||||
|  | in it. | ||||||
|  |  | ||||||
|  | ```go | ||||||
|  | fixtures, err := testfixtures.New( | ||||||
|  |         testfixtures.Database(db), | ||||||
|  |         testfixtures.Dialect("postgres"), | ||||||
|  |         testfixtures.Paths( | ||||||
|  |                 "fixtures/orders.yml", | ||||||
|  |                 "fixtures/customers.yml", | ||||||
|  |                 "common_fixtures/users" | ||||||
|  |         ), | ||||||
|  | ) | ||||||
|  | if err != nil { | ||||||
|  |         ... | ||||||
|  | } | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | ## Security check | ||||||
|  |  | ||||||
|  | In order to prevent you from accidentally wiping the wrong database, this | ||||||
|  | package will refuse to load fixtures if the database name (or database | ||||||
|  | filename for SQLite) doesn't contains "test". If you want to disable this | ||||||
|  | check, use: | ||||||
|  |  | ||||||
|  | ```go | ||||||
|  | testfixtures.New( | ||||||
|  |         ... | ||||||
|  |         testfixtures.DangerousSkipTestDatabaseCheck(), | ||||||
|  | ) | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | ## Sequences | ||||||
|  |  | ||||||
|  | For PostgreSQL, this package also resets all sequences to a high | ||||||
|  | number to prevent duplicated primary keys while running the tests. | ||||||
|  | The default is 10000, but you can change that with: | ||||||
|  |  | ||||||
|  | ```go | ||||||
|  | testfixtures.New( | ||||||
|  |         ... | ||||||
|  |         testfixtures.ResetSequencesTo(10000), | ||||||
|  | ) | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | Or, if you want to skip the reset of sequences entirely: | ||||||
|  |  | ||||||
|  | ```go | ||||||
|  | testfixtures.New( | ||||||
|  |         ... | ||||||
|  |         testfixtures.SkipResetSequences(), | ||||||
|  | ) | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | ## Compatible databases | ||||||
|  |  | ||||||
|  | ### PostgreSQL / TimescaleDB | ||||||
|  |  | ||||||
|  | This package has two approaches to disable foreign keys while importing fixtures | ||||||
|  | for PostgreSQL databases: | ||||||
|  |  | ||||||
|  | #### With `DISABLE TRIGGER` | ||||||
|  |  | ||||||
|  | This is the default approach. For that use: | ||||||
|  |  | ||||||
|  | ```go | ||||||
|  | testfixtures.New( | ||||||
|  |         ... | ||||||
|  |         testfixtures.Dialect("postgres"), // or "timescaledb" | ||||||
|  | ) | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | With the above snippet this package will use `DISABLE TRIGGER` to temporarily | ||||||
|  | disabling foreign key constraints while loading fixtures. This work with any | ||||||
|  | version of PostgreSQL, but it is **required** to be connected in the database | ||||||
|  | as a SUPERUSER. You can make a PostgreSQL user a SUPERUSER with: | ||||||
|  |  | ||||||
|  | ```sql | ||||||
|  | ALTER USER your_user SUPERUSER; | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | #### With `ALTER CONSTRAINT` | ||||||
|  |  | ||||||
|  | This approach don't require to be connected as a SUPERUSER, but only work with | ||||||
|  | PostgreSQL versions >= 9.4. Try this if you are getting foreign key violation | ||||||
|  | errors with the previous approach. It is as simple as using: | ||||||
|  |  | ||||||
|  | ```go | ||||||
|  | testfixtures.New( | ||||||
|  |         ... | ||||||
|  |         testfixtures.Dialect("postgres"), | ||||||
|  |         testfixtures.UseAlterConstraint(), | ||||||
|  | ) | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | Tested using the [github.com/lib/pq](https://github.com/lib/pq) driver. | ||||||
|  |  | ||||||
|  | ### MySQL / MariaDB | ||||||
|  |  | ||||||
|  | Just make sure the connection string have | ||||||
|  | [the multistatement parameter](https://github.com/go-sql-driver/mysql#multistatements) | ||||||
|  | set to true, and use: | ||||||
|  |  | ||||||
|  | ```go | ||||||
|  | testfixtures.New( | ||||||
|  |         ... | ||||||
|  |         testfixtures.Dialect("mysql"), // or "mariadb" | ||||||
|  | ) | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | Tested using the [github.com/go-sql-driver/mysql](https://github.com/go-sql-driver/mysql) driver. | ||||||
|  |  | ||||||
|  | ### SQLite | ||||||
|  |  | ||||||
|  | SQLite is also supported. It is recommended to create foreign keys as | ||||||
|  | `DEFERRABLE` (the default) to prevent problems. See more | ||||||
|  | [on the SQLite documentation](https://www.sqlite.org/foreignkeys.html#fk_deferred). | ||||||
|  | (Foreign key constraints are no-op by default on SQLite, but enabling it is | ||||||
|  | recommended). | ||||||
|  |  | ||||||
|  | ```go | ||||||
|  | testfixtures.New( | ||||||
|  |         ... | ||||||
|  |         testfixtures.Dialect("sqlite"), | ||||||
|  | ) | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | Tested using the [github.com/mattn/go-sqlite3](https://github.com/mattn/go-sqlite3) driver. | ||||||
|  |  | ||||||
|  | ### Microsoft SQL Server | ||||||
|  |  | ||||||
|  | SQL Server support requires SQL Server >= 2008. Inserting on `IDENTITY` columns | ||||||
|  | are handled as well. Just make sure you are logged in with a user with | ||||||
|  | `ALTER TABLE` permission. | ||||||
|  |  | ||||||
|  | ```go | ||||||
|  | testfixtures.New( | ||||||
|  |         ... | ||||||
|  |         testfixtures.Dialect("sqlserver"), | ||||||
|  | ) | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | Tested using the `mssql` and `sqlserver` drivers from the | ||||||
|  | [github.com/denisenkom/go-mssqldb](https://github.com/denisenkom/go-mssqldb) lib. | ||||||
|  |  | ||||||
|  | ## Templating | ||||||
|  |  | ||||||
|  | Testfixtures supports templating, but it's disabled by default. Most people | ||||||
|  | won't need it, but it may be useful to dynamically generate data. | ||||||
|  |  | ||||||
|  | Enable it by doing: | ||||||
|  |  | ||||||
|  | ```go | ||||||
|  | testfixtures.New( | ||||||
|  |         ... | ||||||
|  |         testfixtures.Template(), | ||||||
|  |  | ||||||
|  |         // the above options are optional | ||||||
|  |         TemplateFuncs(...), | ||||||
|  |         TemplateDelims("{{", "}}"), | ||||||
|  |         TemplateOptions("missingkey=zero"), | ||||||
|  |         TemplateData(...), | ||||||
|  | ) | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | The YAML file could look like this: | ||||||
|  |  | ||||||
|  | ```yaml | ||||||
|  | # It's possible generate values... | ||||||
|  | - id: {{sha256 "my-awesome-post}} | ||||||
|  |   title: My Awesome Post | ||||||
|  |   text: {{randomText}} | ||||||
|  |  | ||||||
|  | # ... or records | ||||||
|  | {{range $post := $.Posts}} | ||||||
|  | - id: {{$post.Id}} | ||||||
|  |   title: {{$post.Title}} | ||||||
|  |   text: {{$post.Text}} | ||||||
|  | {{end}} | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | ## Generating fixtures for a existing database | ||||||
|  |  | ||||||
|  | The following code will generate a YAML file for each table of the database | ||||||
|  | into a given folder. It may be useful to boostrap a test scenario from a sample | ||||||
|  | database of your app. | ||||||
|  |  | ||||||
|  | ```go | ||||||
|  | dumper, err := testfixtures.NewDumper( | ||||||
|  |         testfixtures.DumpDatabase(db), | ||||||
|  |         testfixtures.DumpDialect("postgres"), // or your database of choice | ||||||
|  |         testfixtures.DumpDirectory("tmp/fixtures"), | ||||||
|  |         textfixtures.DumpTables( // optional, will dump all table if not given | ||||||
|  |           "posts", | ||||||
|  |           "comments", | ||||||
|  |           "tags", | ||||||
|  |         ) | ||||||
|  | ) | ||||||
|  | if err != nil { | ||||||
|  |         ... | ||||||
|  | } | ||||||
|  | if err := dumper.Dump(); err != nil { | ||||||
|  |         ... | ||||||
|  | } | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | > This was intended to run in small sample databases. It will likely break | ||||||
|  | if run in a production/big database. | ||||||
|  |  | ||||||
|  | ## Gotchas | ||||||
|  |  | ||||||
|  | ### Parallel testing | ||||||
|  |  | ||||||
|  | This library doesn't yet support running tests in parallel! Running tests | ||||||
|  | in parallel can result in random data being present in the database, which | ||||||
|  | will likely cause tests to randomly/intermittently fail. | ||||||
|  |  | ||||||
|  | This is specially tricky since it's not immediately clear that `go test ./...` | ||||||
|  | run tests for each package in parallel. If more than one package use this | ||||||
|  | library, you can face this issue. Please, use `go test -p 1 ./...` or run tests | ||||||
|  | for each package in separated commands to fix this issue. | ||||||
|  |  | ||||||
|  | If you're looking into being able to run tests in parallel you can try using | ||||||
|  | testfixtures together with the [txdb][gotxdb] package, which allows wrapping | ||||||
|  | each test run in a transaction. | ||||||
|  |  | ||||||
|  | ## CLI | ||||||
|  |  | ||||||
|  | We also have a CLI to load fixtures in a given database. | ||||||
|  | Grab it from the [releases page](https://github.com/go-testfixtures/testfixtures/releases) | ||||||
|  | and use it like: | ||||||
|  |  | ||||||
|  | ```bash | ||||||
|  | testfixtures -d postgres -c "postgres://user:password@localhost/database" -D testdata/fixtures | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | The connection string changes for each database driver. | ||||||
|  |  | ||||||
|  | Use `--help` for all flags. | ||||||
|  |  | ||||||
|  | ## Contributing | ||||||
|  |  | ||||||
|  | We recommend you to [install Task](https://taskfile.dev/#/installation) and | ||||||
|  | Docker before contributing to this package, since some stuff is automated | ||||||
|  | using these tools. | ||||||
|  |  | ||||||
|  | It's recommended to use Docker Compose to run tests, since it runs tests for | ||||||
|  | all supported databases once. To do that you just need to run: | ||||||
|  |  | ||||||
|  | ```bash | ||||||
|  | task docker | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | But if you want to run tests locally, copy the `.sample.env` file as `.env` | ||||||
|  | and edit it according to your database setup. You'll need to create a database | ||||||
|  | (likely names `testfixtures_test`) before continuing. Then run the command | ||||||
|  | for the database you want to run tests against: | ||||||
|  |  | ||||||
|  | ```bash | ||||||
|  | task test:pg # PostgreSQL | ||||||
|  | task test:mysql # MySQL | ||||||
|  | task test:sqlite # SQLite | ||||||
|  | task test:sqlserver # Microsoft SQL Server | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | GitHub Actions (CI) runs the same Docker setup available locally. | ||||||
|  |  | ||||||
|  | ## Alternatives | ||||||
|  |  | ||||||
|  | If you don't think using fixtures is a good idea, you can try one of these | ||||||
|  | packages instead: | ||||||
|  |  | ||||||
|  | - [factory-go][factorygo]: Factory for Go. Inspired by Python's Factory Boy | ||||||
|  | and Ruby's Factory Girl | ||||||
|  | - [go-txdb (Single transaction SQL driver for Go)][gotxdb]: Use a single | ||||||
|  | database transaction for each functional test, so you can rollback to | ||||||
|  | previous state between tests to have the same database state in all tests | ||||||
|  | - [go-sqlmock][gosqlmock]: A mock for the sql.DB interface. This allow you to | ||||||
|  | unit test database code without having to connect to a real database | ||||||
|  | - [dbcleaner][dbcleaner] - Clean database for testing, inspired by | ||||||
|  | database_cleaner for Ruby | ||||||
|  |  | ||||||
|  | [doc]: https://pkg.go.dev/github.com/go-testfixtures/testfixtures/v3?tab=doc | ||||||
|  | [railstests]: http://guides.rubyonrails.org/testing.html#the-test-database | ||||||
|  | [gotxdb]: https://github.com/DATA-DOG/go-txdb | ||||||
|  | [gosqlmock]: https://github.com/DATA-DOG/go-sqlmock | ||||||
|  | [factorygo]: https://github.com/bluele/factory-go | ||||||
|  | [dbcleaner]: https://github.com/khaiql/dbcleaner | ||||||
							
								
								
									
										59
									
								
								vendor/github.com/go-testfixtures/testfixtures/v3/Taskfile.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								vendor/github.com/go-testfixtures/testfixtures/v3/Taskfile.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,59 @@ | |||||||
|  | # https://taskfile.org | ||||||
|  |  | ||||||
|  | version: '2' | ||||||
|  |  | ||||||
|  | tasks: | ||||||
|  |   build: | ||||||
|  |     cmds: | ||||||
|  |       - go build -v -tags sqlite -o ./testfixtures{{exeExt}} ./cmd/testfixtures | ||||||
|  |  | ||||||
|  |   test-cli: | ||||||
|  |     cmds: | ||||||
|  |       - ./testfixtures -d sqlite -c testdb.sqlite3 -D testdata/fixtures | ||||||
|  |  | ||||||
|  |   test:pg: | ||||||
|  |     desc: Test PostgreSQL | ||||||
|  |     cmds: | ||||||
|  |       - task: test-db | ||||||
|  |         vars: {DATABASE: postgresql} | ||||||
|  |  | ||||||
|  |   test:mysql: | ||||||
|  |     desc: Test MySQL | ||||||
|  |     cmds: | ||||||
|  |       - task: test:db | ||||||
|  |         vars: {DATABASE: mysql} | ||||||
|  |  | ||||||
|  |   test:sqlite: | ||||||
|  |     desc: Test SQLite | ||||||
|  |     cmds: | ||||||
|  |       - task: test-db | ||||||
|  |         vars: {DATABASE: sqlite} | ||||||
|  |  | ||||||
|  |   test:sqlserver: | ||||||
|  |     desc: Test SQLServer | ||||||
|  |     cmds: | ||||||
|  |       - task: test-db | ||||||
|  |         vars: {DATABASE: sqlserver} | ||||||
|  |  | ||||||
|  |   test-db: | ||||||
|  |     cmds: | ||||||
|  |       - go test -v -tags {{.DATABASE}} | ||||||
|  |  | ||||||
|  |   goreleaser:test: | ||||||
|  |     desc: Tests release process without publishing | ||||||
|  |     cmds: | ||||||
|  |       - goreleaser --snapshot --rm-dist | ||||||
|  |  | ||||||
|  |   docker: | ||||||
|  |     cmds: | ||||||
|  |       - task: docker:build | ||||||
|  |       - task: docker:test | ||||||
|  |  | ||||||
|  |   docker:build: | ||||||
|  |     cmds: | ||||||
|  |       - docker build -t testfixtures . | ||||||
|  |  | ||||||
|  |   docker:test: | ||||||
|  |     cmds: | ||||||
|  |       - docker-compose down -v | ||||||
|  |       - docker-compose run testfixtures go test -v -tags 'postgresql sqlite mysql sqlserver' | ||||||
							
								
								
									
										37
									
								
								vendor/github.com/go-testfixtures/testfixtures/v3/docker-compose.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								vendor/github.com/go-testfixtures/testfixtures/v3/docker-compose.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,37 @@ | |||||||
|  | version: '3' | ||||||
|  |  | ||||||
|  | services: | ||||||
|  |   testfixtures: | ||||||
|  |     image: testfixtures | ||||||
|  |     depends_on: | ||||||
|  |       - postgresql | ||||||
|  |       - mysql | ||||||
|  |       - sqlserver | ||||||
|  |     environment: | ||||||
|  |       PGPASSWORD: postgres | ||||||
|  |       PG_CONN_STRING: host=postgresql user=postgres dbname=testfixtures_test port=5432 sslmode=disable | ||||||
|  |  | ||||||
|  |       MYSQL_CONN_STRING: root:mysql@tcp(mysql)/testfixtures_test?multiStatements=true | ||||||
|  |  | ||||||
|  |       SQLITE_CONN_STRING: testfixtures_test.sqlite3 | ||||||
|  |  | ||||||
|  |       SQLSERVER_CONN_STRING: server=sqlserver;database=master;user id=sa;password=SQL@1server;encrypt=disable | ||||||
|  |  | ||||||
|  |   postgresql: | ||||||
|  |     image: postgres:12.1-alpine | ||||||
|  |     environment: | ||||||
|  |       POSTGRES_DB: testfixtures_test | ||||||
|  |       POSTGRES_USER: postgres | ||||||
|  |       POSTGRES_PASSWORD: postgres | ||||||
|  |  | ||||||
|  |   mysql: | ||||||
|  |     image: mysql:8.0 | ||||||
|  |     environment: | ||||||
|  |       MYSQL_DATABASE: testfixtures_test | ||||||
|  |       MYSQL_ROOT_PASSWORD: mysql | ||||||
|  |  | ||||||
|  |   sqlserver: | ||||||
|  |     image: mcr.microsoft.com/mssql/server:2019-latest | ||||||
|  |     environment: | ||||||
|  |       ACCEPT_EULA: 'Y' | ||||||
|  |       SA_PASSWORD: SQL@1server | ||||||
							
								
								
									
										165
									
								
								vendor/github.com/go-testfixtures/testfixtures/v3/dump.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										165
									
								
								vendor/github.com/go-testfixtures/testfixtures/v3/dump.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,165 @@ | |||||||
|  | package testfixtures | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"database/sql" | ||||||
|  | 	"fmt" | ||||||
|  | 	"os" | ||||||
|  | 	"path/filepath" | ||||||
|  | 	"unicode/utf8" | ||||||
|  |  | ||||||
|  | 	"gopkg.in/yaml.v2" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // Dumper is resposible for dumping fixtures from the database into a | ||||||
|  | // directory. | ||||||
|  | type Dumper struct { | ||||||
|  | 	db     *sql.DB | ||||||
|  | 	helper helper | ||||||
|  | 	dir    string | ||||||
|  |  | ||||||
|  | 	tables []string | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // NewDumper creates a new dumper with the given options. | ||||||
|  | // | ||||||
|  | // The "DumpDatabase", "DumpDialect" and "DumpDirectory" options are required. | ||||||
|  | func NewDumper(options ...func(*Dumper) error) (*Dumper, error) { | ||||||
|  | 	d := &Dumper{} | ||||||
|  |  | ||||||
|  | 	for _, option := range options { | ||||||
|  | 		if err := option(d); err != nil { | ||||||
|  | 			return nil, err | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return d, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // DumpDatabase sets the database to be dumped. | ||||||
|  | func DumpDatabase(db *sql.DB) func(*Dumper) error { | ||||||
|  | 	return func(d *Dumper) error { | ||||||
|  | 		d.db = db | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // DumpDialect informs Loader about which database dialect you're using. | ||||||
|  | // | ||||||
|  | // Possible options are "postgresql", "timescaledb", "mysql", "mariadb", | ||||||
|  | // "sqlite" and "sqlserver". | ||||||
|  | func DumpDialect(dialect string) func(*Dumper) error { | ||||||
|  | 	return func(d *Dumper) error { | ||||||
|  | 		h, err := helperForDialect(dialect) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return err | ||||||
|  | 		} | ||||||
|  | 		d.helper = h | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // DumpDirectory sets the directory where the fixtures files will be created. | ||||||
|  | func DumpDirectory(dir string) func(*Dumper) error { | ||||||
|  | 	return func(d *Dumper) error { | ||||||
|  | 		d.dir = dir | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // DumpTables allows you to choose which tables you want to dump. | ||||||
|  | // | ||||||
|  | // If not informed, Dumper will dump all tables by default. | ||||||
|  | func DumpTables(tables ...string) func(*Dumper) error { | ||||||
|  | 	return func(d *Dumper) error { | ||||||
|  | 		d.tables = tables | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Dump dumps the databases as YAML fixtures. | ||||||
|  | func (d *Dumper) Dump() error { | ||||||
|  | 	tables := d.tables | ||||||
|  | 	if len(tables) == 0 { | ||||||
|  | 		var err error | ||||||
|  | 		tables, err = d.helper.tableNames(d.db) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return err | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	for _, table := range tables { | ||||||
|  | 		if err := d.dumpTable(table); err != nil { | ||||||
|  | 			return err | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (d *Dumper) dumpTable(table string) error { | ||||||
|  | 	query := fmt.Sprintf("SELECT * FROM %s", d.helper.quoteKeyword(table)) | ||||||
|  |  | ||||||
|  | 	stmt, err := d.db.Prepare(query) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	defer stmt.Close() | ||||||
|  |  | ||||||
|  | 	rows, err := stmt.Query() | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	defer rows.Close() | ||||||
|  |  | ||||||
|  | 	columns, err := rows.Columns() | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	fixtures := make([]yaml.MapSlice, 0, 10) | ||||||
|  | 	for rows.Next() { | ||||||
|  | 		entries := make([]interface{}, len(columns)) | ||||||
|  | 		entryPtrs := make([]interface{}, len(entries)) | ||||||
|  | 		for i := range entries { | ||||||
|  | 			entryPtrs[i] = &entries[i] | ||||||
|  | 		} | ||||||
|  | 		if err := rows.Scan(entryPtrs...); err != nil { | ||||||
|  | 			return err | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		entryMap := make([]yaml.MapItem, len(entries)) | ||||||
|  | 		for i, column := range columns { | ||||||
|  | 			entryMap[i] = yaml.MapItem{ | ||||||
|  | 				Key:   column, | ||||||
|  | 				Value: convertValue(entries[i]), | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		fixtures = append(fixtures, entryMap) | ||||||
|  | 	} | ||||||
|  | 	if err = rows.Err(); err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	filePath := filepath.Join(d.dir, table+".yml") | ||||||
|  | 	f, err := os.Create(filePath) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	defer f.Close() | ||||||
|  |  | ||||||
|  | 	data, err := yaml.Marshal(fixtures) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	_, err = f.Write(data) | ||||||
|  | 	return err | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func convertValue(value interface{}) interface{} { | ||||||
|  | 	switch v := value.(type) { | ||||||
|  | 	case []byte: | ||||||
|  | 		if utf8.Valid(v) { | ||||||
|  | 			return string(v) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return value | ||||||
|  | } | ||||||
							
								
								
									
										14
									
								
								vendor/github.com/go-testfixtures/testfixtures/v3/go.mod
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								vendor/github.com/go-testfixtures/testfixtures/v3/go.mod
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,14 @@ | |||||||
|  | module github.com/go-testfixtures/testfixtures/v3 | ||||||
|  |  | ||||||
|  | require ( | ||||||
|  | 	github.com/denisenkom/go-mssqldb v0.0.0-20191128021309-1d7a30a10f73 | ||||||
|  | 	github.com/go-sql-driver/mysql v1.4.1 | ||||||
|  | 	github.com/joho/godotenv v1.3.0 | ||||||
|  | 	github.com/lib/pq v1.3.0 | ||||||
|  | 	github.com/mattn/go-sqlite3 v2.0.2+incompatible | ||||||
|  | 	github.com/spf13/pflag v1.0.5 | ||||||
|  | 	google.golang.org/appengine v1.3.0 // indirect | ||||||
|  | 	gopkg.in/yaml.v2 v2.2.7 | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | go 1.13 | ||||||
							
								
								
									
										26
									
								
								vendor/github.com/go-testfixtures/testfixtures/v3/go.sum
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								vendor/github.com/go-testfixtures/testfixtures/v3/go.sum
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,26 @@ | |||||||
|  | github.com/denisenkom/go-mssqldb v0.0.0-20191128021309-1d7a30a10f73 h1:OGNva6WhsKst5OZf7eZOklDztV3hwtTHovdrLHV+MsA= | ||||||
|  | github.com/denisenkom/go-mssqldb v0.0.0-20191128021309-1d7a30a10f73/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= | ||||||
|  | github.com/go-sql-driver/mysql v1.4.1 h1:g24URVg0OFbNUTx9qqY1IRZ9D9z3iPyi5zKhQZpNwpA= | ||||||
|  | github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= | ||||||
|  | github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY= | ||||||
|  | github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= | ||||||
|  | github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= | ||||||
|  | github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc= | ||||||
|  | github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= | ||||||
|  | github.com/lib/pq v1.3.0 h1:/qkRGz8zljWiDcFvgpwUpwIAPu3r07TDvs3Rws+o/pU= | ||||||
|  | github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= | ||||||
|  | github.com/mattn/go-sqlite3 v2.0.2+incompatible h1:qzw9c2GNT8UFrgWNDhCTqRqYUSmu/Dav/9Z58LGpk7U= | ||||||
|  | github.com/mattn/go-sqlite3 v2.0.2+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= | ||||||
|  | github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= | ||||||
|  | github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= | ||||||
|  | golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c h1:Vj5n4GlwjmQteupaxJ9+0FNOmBrHfq7vN4btdGoDZgI= | ||||||
|  | golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= | ||||||
|  | golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= | ||||||
|  | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | ||||||
|  | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= | ||||||
|  | google.golang.org/appengine v1.3.0 h1:FBSsiFRMz3LBeXIomRnVzrQwSDj4ibvcRexLG0LZGQk= | ||||||
|  | google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= | ||||||
|  | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= | ||||||
|  | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||||||
|  | gopkg.in/yaml.v2 v2.2.7 h1:VUgggvou5XRW9mHwD/yXxIYSMtY0zoKQf/v226p2nyo= | ||||||
|  | gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= | ||||||
| @@ -8,13 +8,12 @@ import ( | |||||||
| const ( | const ( | ||||||
| 	paramTypeDollar = iota + 1 | 	paramTypeDollar = iota + 1 | ||||||
| 	paramTypeQuestion | 	paramTypeQuestion | ||||||
| 	paramTypeColon | 	paramTypeAtSign | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| type loadFunction func(tx *sql.Tx) error | type loadFunction func(tx *sql.Tx) error | ||||||
| 
 | 
 | ||||||
| // Helper is the generic interface for the database helper | type helper interface { | ||||||
| type Helper interface { |  | ||||||
| 	init(*sql.DB) error | 	init(*sql.DB) error | ||||||
| 	disableReferentialIntegrity(*sql.DB, loadFunction) error | 	disableReferentialIntegrity(*sql.DB, loadFunction) error | ||||||
| 	paramType() int | 	paramType() int | ||||||
| @@ -43,11 +42,10 @@ type batchSplitter interface { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| var ( | var ( | ||||||
| 	_ Helper = &MySQL{} | 	_ helper = &mySQL{} | ||||||
| 	_ Helper = &PostgreSQL{} | 	_ helper = &postgreSQL{} | ||||||
| 	_ Helper = &SQLite{} | 	_ helper = &sqlite{} | ||||||
| 	_ Helper = &Oracle{} | 	_ helper = &sqlserver{} | ||||||
| 	_ Helper = &SQLServer{} |  | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| type baseHelper struct{} | type baseHelper struct{} | ||||||
| @@ -5,14 +5,13 @@ import ( | |||||||
| 	"fmt" | 	"fmt" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // MySQL is the MySQL helper for this package | type mySQL struct { | ||||||
| type MySQL struct { |  | ||||||
| 	baseHelper | 	baseHelper | ||||||
| 	tables         []string | 	tables         []string | ||||||
| 	tablesChecksum map[string]int64 | 	tablesChecksum map[string]int64 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (h *MySQL) init(db *sql.DB) error { | func (h *mySQL) init(db *sql.DB) error { | ||||||
| 	var err error | 	var err error | ||||||
| 	h.tables, err = h.tableNames(db) | 	h.tables, err = h.tableNames(db) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| @@ -22,21 +21,21 @@ func (h *MySQL) init(db *sql.DB) error { | |||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (*MySQL) paramType() int { | func (*mySQL) paramType() int { | ||||||
| 	return paramTypeQuestion | 	return paramTypeQuestion | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (*MySQL) quoteKeyword(str string) string { | func (*mySQL) quoteKeyword(str string) string { | ||||||
| 	return fmt.Sprintf("`%s`", str) | 	return fmt.Sprintf("`%s`", str) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (*MySQL) databaseName(q queryable) (string, error) { | func (*mySQL) databaseName(q queryable) (string, error) { | ||||||
| 	var dbName string | 	var dbName string | ||||||
| 	err := q.QueryRow("SELECT DATABASE()").Scan(&dbName) | 	err := q.QueryRow("SELECT DATABASE()").Scan(&dbName) | ||||||
| 	return dbName, err | 	return dbName, err | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (h *MySQL) tableNames(q queryable) ([]string, error) { | func (h *mySQL) tableNames(q queryable) ([]string, error) { | ||||||
| 	query := ` | 	query := ` | ||||||
| 		SELECT table_name | 		SELECT table_name | ||||||
| 		FROM information_schema.tables | 		FROM information_schema.tables | ||||||
| @@ -69,14 +68,7 @@ func (h *MySQL) tableNames(q queryable) ([]string, error) { | |||||||
| 
 | 
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (h *MySQL) disableReferentialIntegrity(db *sql.DB, loadFn loadFunction) (err error) { | func (h *mySQL) disableReferentialIntegrity(db *sql.DB, loadFn loadFunction) (err error) { | ||||||
| 	// re-enable after load |  | ||||||
| 	defer func() { |  | ||||||
| 		if _, err2 := db.Exec("SET FOREIGN_KEY_CHECKS = 1"); err2 != nil && err == nil { |  | ||||||
| 			err = err2 |  | ||||||
| 		} |  | ||||||
| 	}() |  | ||||||
| 
 |  | ||||||
| 	tx, err := db.Begin() | 	tx, err := db.Begin() | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| @@ -87,14 +79,19 @@ func (h *MySQL) disableReferentialIntegrity(db *sql.DB, loadFn loadFunction) (er | |||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if err = loadFn(tx); err != nil { | 	err = loadFn(tx) | ||||||
|  | 	_, err2 := tx.Exec("SET FOREIGN_KEY_CHECKS = 1") | ||||||
|  | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  | 	if err2 != nil { | ||||||
|  | 		return err2 | ||||||
|  | 	} | ||||||
| 
 | 
 | ||||||
| 	return tx.Commit() | 	return tx.Commit() | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (h *MySQL) isTableModified(q queryable, tableName string) (bool, error) { | func (h *mySQL) isTableModified(q queryable, tableName string) (bool, error) { | ||||||
| 	checksum, err := h.getChecksum(q, tableName) | 	checksum, err := h.getChecksum(q, tableName) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return true, err | 		return true, err | ||||||
| @@ -105,7 +102,7 @@ func (h *MySQL) isTableModified(q queryable, tableName string) (bool, error) { | |||||||
| 	return oldChecksum == 0 || checksum != oldChecksum, nil | 	return oldChecksum == 0 || checksum != oldChecksum, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (h *MySQL) afterLoad(q queryable) error { | func (h *mySQL) afterLoad(q queryable) error { | ||||||
| 	if h.tablesChecksum != nil { | 	if h.tablesChecksum != nil { | ||||||
| 		return nil | 		return nil | ||||||
| 	} | 	} | ||||||
| @@ -121,7 +118,7 @@ func (h *MySQL) afterLoad(q queryable) error { | |||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (h *MySQL) getChecksum(q queryable, tableName string) (int64, error) { | func (h *mySQL) getChecksum(q queryable, tableName string) (int64, error) { | ||||||
| 	sql := fmt.Sprintf("CHECKSUM TABLE %s", h.quoteKeyword(tableName)) | 	sql := fmt.Sprintf("CHECKSUM TABLE %s", h.quoteKeyword(tableName)) | ||||||
| 	var ( | 	var ( | ||||||
| 		table    string | 		table    string | ||||||
| @@ -6,15 +6,12 @@ import ( | |||||||
| 	"strings" | 	"strings" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // PostgreSQL is the PG helper for this package | type postgreSQL struct { | ||||||
| type PostgreSQL struct { |  | ||||||
| 	baseHelper | 	baseHelper | ||||||
| 
 | 
 | ||||||
| 	// UseAlterConstraint If true, the contraint disabling will do | 	useAlterConstraint bool | ||||||
| 	// using ALTER CONTRAINT sintax, only allowed in PG >= 9.4. | 	skipResetSequences bool | ||||||
| 	// If false, the constraint disabling will use DISABLE TRIGGER ALL, | 	resetSequencesTo   int64 | ||||||
| 	// which requires SUPERUSER privileges. |  | ||||||
| 	UseAlterConstraint bool |  | ||||||
| 
 | 
 | ||||||
| 	tables                   []string | 	tables                   []string | ||||||
| 	sequences                []string | 	sequences                []string | ||||||
| @@ -27,7 +24,7 @@ type pgConstraint struct { | |||||||
| 	constraintName string | 	constraintName string | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (h *PostgreSQL) init(db *sql.DB) error { | func (h *postgreSQL) init(db *sql.DB) error { | ||||||
| 	var err error | 	var err error | ||||||
| 
 | 
 | ||||||
| 	h.tables, err = h.tableNames(db) | 	h.tables, err = h.tableNames(db) | ||||||
| @@ -48,17 +45,17 @@ func (h *PostgreSQL) init(db *sql.DB) error { | |||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (*PostgreSQL) paramType() int { | func (*postgreSQL) paramType() int { | ||||||
| 	return paramTypeDollar | 	return paramTypeDollar | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (*PostgreSQL) databaseName(q queryable) (string, error) { | func (*postgreSQL) databaseName(q queryable) (string, error) { | ||||||
| 	var dbName string | 	var dbName string | ||||||
| 	err := q.QueryRow("SELECT current_database()").Scan(&dbName) | 	err := q.QueryRow("SELECT current_database()").Scan(&dbName) | ||||||
| 	return dbName, err | 	return dbName, err | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (h *PostgreSQL) tableNames(q queryable) ([]string, error) { | func (h *postgreSQL) tableNames(q queryable) ([]string, error) { | ||||||
| 	var tables []string | 	var tables []string | ||||||
| 
 | 
 | ||||||
| 	sql := ` | 	sql := ` | ||||||
| @@ -67,7 +64,8 @@ func (h *PostgreSQL) tableNames(q queryable) ([]string, error) { | |||||||
| 		INNER JOIN pg_namespace ON pg_namespace.oid = pg_class.relnamespace | 		INNER JOIN pg_namespace ON pg_namespace.oid = pg_class.relnamespace | ||||||
| 		WHERE pg_class.relkind = 'r' | 		WHERE pg_class.relkind = 'r' | ||||||
| 		  AND pg_namespace.nspname NOT IN ('pg_catalog', 'information_schema') | 		  AND pg_namespace.nspname NOT IN ('pg_catalog', 'information_schema') | ||||||
| 		  AND pg_namespace.nspname NOT LIKE 'pg_toast%'; | 		  AND pg_namespace.nspname NOT LIKE 'pg_toast%' | ||||||
|  | 		  AND pg_namespace.nspname NOT LIKE '\_timescaledb%'; | ||||||
| 	` | 	` | ||||||
| 	rows, err := q.Query(sql) | 	rows, err := q.Query(sql) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| @@ -88,12 +86,13 @@ func (h *PostgreSQL) tableNames(q queryable) ([]string, error) { | |||||||
| 	return tables, nil | 	return tables, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (h *PostgreSQL) getSequences(q queryable) ([]string, error) { | func (h *postgreSQL) getSequences(q queryable) ([]string, error) { | ||||||
| 	const sql = ` | 	const sql = ` | ||||||
| 		SELECT pg_namespace.nspname || '.' || pg_class.relname AS sequence_name | 		SELECT pg_namespace.nspname || '.' || pg_class.relname AS sequence_name | ||||||
| 		FROM pg_class | 		FROM pg_class | ||||||
| 		INNER JOIN pg_namespace ON pg_namespace.oid = pg_class.relnamespace | 		INNER JOIN pg_namespace ON pg_namespace.oid = pg_class.relnamespace | ||||||
| 		WHERE pg_class.relkind = 'S' | 		WHERE pg_class.relkind = 'S' | ||||||
|  | 		  AND pg_namespace.nspname NOT LIKE '\_timescaledb%' | ||||||
| 	` | 	` | ||||||
| 
 | 
 | ||||||
| 	rows, err := q.Query(sql) | 	rows, err := q.Query(sql) | ||||||
| @@ -116,7 +115,7 @@ func (h *PostgreSQL) getSequences(q queryable) ([]string, error) { | |||||||
| 	return sequences, nil | 	return sequences, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (*PostgreSQL) getNonDeferrableConstraints(q queryable) ([]pgConstraint, error) { | func (*postgreSQL) getNonDeferrableConstraints(q queryable) ([]pgConstraint, error) { | ||||||
| 	var constraints []pgConstraint | 	var constraints []pgConstraint | ||||||
| 
 | 
 | ||||||
| 	sql := ` | 	sql := ` | ||||||
| @@ -124,6 +123,7 @@ func (*PostgreSQL) getNonDeferrableConstraints(q queryable) ([]pgConstraint, err | |||||||
| 		FROM information_schema.table_constraints | 		FROM information_schema.table_constraints | ||||||
| 		WHERE constraint_type = 'FOREIGN KEY' | 		WHERE constraint_type = 'FOREIGN KEY' | ||||||
| 		  AND is_deferrable = 'NO' | 		  AND is_deferrable = 'NO' | ||||||
|  | 		  AND table_schema NOT LIKE '\_timescaledb%' | ||||||
|   	` |   	` | ||||||
| 	rows, err := q.Query(sql) | 	rows, err := q.Query(sql) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| @@ -144,7 +144,7 @@ func (*PostgreSQL) getNonDeferrableConstraints(q queryable) ([]pgConstraint, err | |||||||
| 	return constraints, nil | 	return constraints, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (h *PostgreSQL) disableTriggers(db *sql.DB, loadFn loadFunction) (err error) { | func (h *postgreSQL) disableTriggers(db *sql.DB, loadFn loadFunction) (err error) { | ||||||
| 	defer func() { | 	defer func() { | ||||||
| 		// re-enable triggers after load | 		// re-enable triggers after load | ||||||
| 		var sql string | 		var sql string | ||||||
| @@ -177,7 +177,7 @@ func (h *PostgreSQL) disableTriggers(db *sql.DB, loadFn loadFunction) (err error | |||||||
| 	return tx.Commit() | 	return tx.Commit() | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (h *PostgreSQL) makeConstraintsDeferrable(db *sql.DB, loadFn loadFunction) (err error) { | func (h *postgreSQL) makeConstraintsDeferrable(db *sql.DB, loadFn loadFunction) (err error) { | ||||||
| 	defer func() { | 	defer func() { | ||||||
| 		// ensure constraint being not deferrable again after load | 		// ensure constraint being not deferrable again after load | ||||||
| 		var sql string | 		var sql string | ||||||
| @@ -214,21 +214,28 @@ func (h *PostgreSQL) makeConstraintsDeferrable(db *sql.DB, loadFn loadFunction) | |||||||
| 	return tx.Commit() | 	return tx.Commit() | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (h *PostgreSQL) disableReferentialIntegrity(db *sql.DB, loadFn loadFunction) (err error) { | func (h *postgreSQL) disableReferentialIntegrity(db *sql.DB, loadFn loadFunction) (err error) { | ||||||
| 	// ensure sequences being reset after load | 	// ensure sequences being reset after load | ||||||
|  | 	if !h.skipResetSequences { | ||||||
| 		defer func() { | 		defer func() { | ||||||
| 			if err2 := h.resetSequences(db); err2 != nil && err == nil { | 			if err2 := h.resetSequences(db); err2 != nil && err == nil { | ||||||
| 				err = err2 | 				err = err2 | ||||||
| 			} | 			} | ||||||
| 		}() | 		}() | ||||||
|  | 	} | ||||||
| 
 | 
 | ||||||
| 	if h.UseAlterConstraint { | 	if h.useAlterConstraint { | ||||||
| 		return h.makeConstraintsDeferrable(db, loadFn) | 		return h.makeConstraintsDeferrable(db, loadFn) | ||||||
| 	} | 	} | ||||||
| 	return h.disableTriggers(db, loadFn) | 	return h.disableTriggers(db, loadFn) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (h *PostgreSQL) resetSequences(db *sql.DB) error { | func (h *postgreSQL) resetSequences(db *sql.DB) error { | ||||||
|  | 	resetSequencesTo := h.resetSequencesTo | ||||||
|  | 	if resetSequencesTo == 0 { | ||||||
|  | 		resetSequencesTo = 10000 | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	for _, sequence := range h.sequences { | 	for _, sequence := range h.sequences { | ||||||
| 		_, err := db.Exec(fmt.Sprintf("SELECT SETVAL('%s', %d)", sequence, resetSequencesTo)) | 		_, err := db.Exec(fmt.Sprintf("SELECT SETVAL('%s', %d)", sequence, resetSequencesTo)) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| @@ -238,7 +245,7 @@ func (h *PostgreSQL) resetSequences(db *sql.DB) error { | |||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (h *PostgreSQL) isTableModified(q queryable, tableName string) (bool, error) { | func (h *postgreSQL) isTableModified(q queryable, tableName string) (bool, error) { | ||||||
| 	checksum, err := h.getChecksum(q, tableName) | 	checksum, err := h.getChecksum(q, tableName) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return false, err | 		return false, err | ||||||
| @@ -249,7 +256,7 @@ func (h *PostgreSQL) isTableModified(q queryable, tableName string) (bool, error | |||||||
| 	return oldChecksum == "" || checksum != oldChecksum, nil | 	return oldChecksum == "" || checksum != oldChecksum, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (h *PostgreSQL) afterLoad(q queryable) error { | func (h *postgreSQL) afterLoad(q queryable) error { | ||||||
| 	if h.tablesChecksum != nil { | 	if h.tablesChecksum != nil { | ||||||
| 		return nil | 		return nil | ||||||
| 	} | 	} | ||||||
| @@ -265,7 +272,7 @@ func (h *PostgreSQL) afterLoad(q queryable) error { | |||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (h *PostgreSQL) getChecksum(q queryable, tableName string) (string, error) { | func (h *postgreSQL) getChecksum(q queryable, tableName string) (string, error) { | ||||||
| 	sqlStr := fmt.Sprintf(` | 	sqlStr := fmt.Sprintf(` | ||||||
| 			SELECT md5(CAST((array_agg(t.*)) AS TEXT)) | 			SELECT md5(CAST((array_agg(t.*)) AS TEXT)) | ||||||
| 			FROM %s AS t | 			FROM %s AS t | ||||||
| @@ -280,7 +287,7 @@ func (h *PostgreSQL) getChecksum(q queryable, tableName string) (string, error) | |||||||
| 	return checksum.String, nil | 	return checksum.String, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (*PostgreSQL) quoteKeyword(s string) string { | func (*postgreSQL) quoteKeyword(s string) string { | ||||||
| 	parts := strings.Split(s, ".") | 	parts := strings.Split(s, ".") | ||||||
| 	for i, p := range parts { | 	for i, p := range parts { | ||||||
| 		parts[i] = fmt.Sprintf(`"%s"`, p) | 		parts[i] = fmt.Sprintf(`"%s"`, p) | ||||||
| @@ -5,16 +5,15 @@ import ( | |||||||
| 	"path/filepath" | 	"path/filepath" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // SQLite is the SQLite Helper for this package | type sqlite struct { | ||||||
| type SQLite struct { |  | ||||||
| 	baseHelper | 	baseHelper | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (*SQLite) paramType() int { | func (*sqlite) paramType() int { | ||||||
| 	return paramTypeQuestion | 	return paramTypeQuestion | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (*SQLite) databaseName(q queryable) (string, error) { | func (*sqlite) databaseName(q queryable) (string, error) { | ||||||
| 	var seq int | 	var seq int | ||||||
| 	var main, dbName string | 	var main, dbName string | ||||||
| 	err := q.QueryRow("PRAGMA database_list").Scan(&seq, &main, &dbName) | 	err := q.QueryRow("PRAGMA database_list").Scan(&seq, &main, &dbName) | ||||||
| @@ -25,7 +24,7 @@ func (*SQLite) databaseName(q queryable) (string, error) { | |||||||
| 	return dbName, nil | 	return dbName, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (*SQLite) tableNames(q queryable) ([]string, error) { | func (*sqlite) tableNames(q queryable) ([]string, error) { | ||||||
| 	query := ` | 	query := ` | ||||||
| 		SELECT name | 		SELECT name | ||||||
| 		FROM sqlite_master | 		FROM sqlite_master | ||||||
| @@ -51,7 +50,7 @@ func (*SQLite) tableNames(q queryable) ([]string, error) { | |||||||
| 	return tables, nil | 	return tables, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (*SQLite) disableReferentialIntegrity(db *sql.DB, loadFn loadFunction) (err error) { | func (*sqlite) disableReferentialIntegrity(db *sql.DB, loadFn loadFunction) (err error) { | ||||||
| 	defer func() { | 	defer func() { | ||||||
| 		if _, err2 := db.Exec("PRAGMA defer_foreign_keys = OFF"); err2 != nil && err == nil { | 		if _, err2 := db.Exec("PRAGMA defer_foreign_keys = OFF"); err2 != nil && err == nil { | ||||||
| 			err = err2 | 			err = err2 | ||||||
| @@ -6,17 +6,29 @@ import ( | |||||||
| 	"strings" | 	"strings" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // SQLServer is the helper for SQL Server for this package. | type sqlserver struct { | ||||||
| // SQL Server >= 2008 is required. |  | ||||||
| type SQLServer struct { |  | ||||||
| 	baseHelper | 	baseHelper | ||||||
| 
 | 
 | ||||||
|  | 	paramTypeCache int | ||||||
| 	tables         []string | 	tables         []string | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (h *SQLServer) init(db *sql.DB) error { | func (h *sqlserver) init(db *sql.DB) error { | ||||||
| 	var err error | 	var err error | ||||||
| 
 | 
 | ||||||
|  | 	// NOTE(@andreynering): The SQL Server lib (github.com/denisenkom/go-mssqldb) | ||||||
|  | 	// supports both the "?" style (when using the deprecated "mssql" driver) | ||||||
|  | 	// and the "@p1" style (when using the new "sqlserver" driver). | ||||||
|  | 	// | ||||||
|  | 	// Since we don't have a way to know which driver it's been used, | ||||||
|  | 	// this is a small hack to detect the allowed param style. | ||||||
|  | 	var v int | ||||||
|  | 	if err := db.QueryRow("SELECT ?", 1).Scan(&v); err == nil && v == 1 { | ||||||
|  | 		h.paramTypeCache = paramTypeQuestion | ||||||
|  | 	} else { | ||||||
|  | 		h.paramTypeCache = paramTypeAtSign | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	h.tables, err = h.tableNames(db) | 	h.tables, err = h.tableNames(db) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| @@ -25,11 +37,11 @@ func (h *SQLServer) init(db *sql.DB) error { | |||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (*SQLServer) paramType() int { | func (h *sqlserver) paramType() int { | ||||||
| 	return paramTypeQuestion | 	return h.paramTypeCache | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (*SQLServer) quoteKeyword(s string) string { | func (*sqlserver) quoteKeyword(s string) string { | ||||||
| 	parts := strings.Split(s, ".") | 	parts := strings.Split(s, ".") | ||||||
| 	for i, p := range parts { | 	for i, p := range parts { | ||||||
| 		parts[i] = fmt.Sprintf(`[%s]`, p) | 		parts[i] = fmt.Sprintf(`[%s]`, p) | ||||||
| @@ -37,14 +49,14 @@ func (*SQLServer) quoteKeyword(s string) string { | |||||||
| 	return strings.Join(parts, ".") | 	return strings.Join(parts, ".") | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (*SQLServer) databaseName(q queryable) (string, error) { | func (*sqlserver) databaseName(q queryable) (string, error) { | ||||||
| 	var dbName string | 	var dbName string | ||||||
| 	err := q.QueryRow("SELECT DB_NAME()").Scan(&dbName) | 	err := q.QueryRow("SELECT DB_NAME()").Scan(&dbName) | ||||||
| 	return dbName, err | 	return dbName, err | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (*SQLServer) tableNames(q queryable) ([]string, error) { | func (*sqlserver) tableNames(q queryable) ([]string, error) { | ||||||
| 	rows, err := q.Query("SELECT table_schema + '.' + table_name FROM information_schema.tables") | 	rows, err := q.Query("SELECT table_schema + '.' + table_name FROM information_schema.tables WHERE table_name <> 'spt_values'") | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
| @@ -64,36 +76,42 @@ func (*SQLServer) tableNames(q queryable) ([]string, error) { | |||||||
| 	return tables, nil | 	return tables, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (h *SQLServer) tableHasIdentityColumn(q queryable, tableName string) bool { | func (h *sqlserver) tableHasIdentityColumn(q queryable, tableName string) (bool, error) { | ||||||
| 	sql := ` | 	sql := fmt.Sprintf(` | ||||||
| 		SELECT COUNT(*) | 		SELECT COUNT(*) | ||||||
| 		FROM SYS.IDENTITY_COLUMNS | 		FROM SYS.IDENTITY_COLUMNS | ||||||
| 		WHERE OBJECT_ID = OBJECT_ID(?) | 		WHERE OBJECT_ID = OBJECT_ID('%s') | ||||||
| 	` | 	`, tableName) | ||||||
| 	var count int | 	var count int | ||||||
| 	q.QueryRow(sql, h.quoteKeyword(tableName)).Scan(&count) | 	if err := q.QueryRow(sql).Scan(&count); err != nil { | ||||||
| 	return count > 0 | 		return false, err | ||||||
|  | 	} | ||||||
|  | 	return count > 0, nil | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (h *SQLServer) whileInsertOnTable(tx *sql.Tx, tableName string, fn func() error) (err error) { | func (h *sqlserver) whileInsertOnTable(tx *sql.Tx, tableName string, fn func() error) (err error) { | ||||||
| 	if h.tableHasIdentityColumn(tx, tableName) { | 	hasIdentityColumn, err := h.tableHasIdentityColumn(tx, tableName) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	if hasIdentityColumn { | ||||||
| 		defer func() { | 		defer func() { | ||||||
| 			_, err2 := tx.Exec(fmt.Sprintf("SET IDENTITY_INSERT %s OFF", h.quoteKeyword(tableName))) | 			_, err2 := tx.Exec(fmt.Sprintf("SET IDENTITY_INSERT %s OFF", h.quoteKeyword(tableName))) | ||||||
| 			if err2 != nil && err == nil { | 			if err2 != nil && err == nil { | ||||||
| 				err = err2 | 				err = fmt.Errorf("testfixtures: could not disable identity insert: %w", err2) | ||||||
| 			} | 			} | ||||||
| 		}() | 		}() | ||||||
| 
 | 
 | ||||||
| 		_, err := tx.Exec(fmt.Sprintf("SET IDENTITY_INSERT %s ON", h.quoteKeyword(tableName))) | 		_, err := tx.Exec(fmt.Sprintf("SET IDENTITY_INSERT %s ON", h.quoteKeyword(tableName))) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return err | 			return fmt.Errorf("testfixtures: could not enable identity insert: %w", err) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	return fn() | 	return fn() | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (h *SQLServer) disableReferentialIntegrity(db *sql.DB, loadFn loadFunction) (err error) { | func (h *sqlserver) disableReferentialIntegrity(db *sql.DB, loadFn loadFunction) (err error) { | ||||||
| 	// ensure the triggers are re-enable after all | 	// ensure the triggers are re-enable after all | ||||||
| 	defer func() { | 	defer func() { | ||||||
| 		var sql string | 		var sql string | ||||||
| @@ -130,6 +148,6 @@ func (h *SQLServer) disableReferentialIntegrity(db *sql.DB, loadFn loadFunction) | |||||||
| // SQL Server because commands like a `CREATE SCHEMA...` and a `CREATE TABLE...` | // SQL Server because commands like a `CREATE SCHEMA...` and a `CREATE TABLE...` | ||||||
| // could not be executed in the same batch. | // could not be executed in the same batch. | ||||||
| // See https://docs.microsoft.com/en-us/previous-versions/sql/sql-server-2008-r2/ms175502(v=sql.105)#rules-for-using-batches | // See https://docs.microsoft.com/en-us/previous-versions/sql/sql-server-2008-r2/ms175502(v=sql.105)#rules-for-using-batches | ||||||
| func (*SQLServer) splitter() []byte { | func (*sqlserver) splitter() []byte { | ||||||
| 	return []byte("GO\n") | 	return []byte("GO\n") | ||||||
| } | } | ||||||
							
								
								
									
										599
									
								
								vendor/github.com/go-testfixtures/testfixtures/v3/testfixtures.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										599
									
								
								vendor/github.com/go-testfixtures/testfixtures/v3/testfixtures.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,599 @@ | |||||||
|  | package testfixtures // import "github.com/go-testfixtures/testfixtures/v3" | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"bytes" | ||||||
|  | 	"database/sql" | ||||||
|  | 	"fmt" | ||||||
|  | 	"io/ioutil" | ||||||
|  | 	"os" | ||||||
|  | 	"path" | ||||||
|  | 	"path/filepath" | ||||||
|  | 	"regexp" | ||||||
|  | 	"strings" | ||||||
|  | 	"text/template" | ||||||
|  | 	"time" | ||||||
|  |  | ||||||
|  | 	"gopkg.in/yaml.v2" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // Loader is the responsible to loading fixtures. | ||||||
|  | type Loader struct { | ||||||
|  | 	db            *sql.DB | ||||||
|  | 	helper        helper | ||||||
|  | 	fixturesFiles []*fixtureFile | ||||||
|  |  | ||||||
|  | 	skipTestDatabaseCheck bool | ||||||
|  | 	location              *time.Location | ||||||
|  |  | ||||||
|  | 	template           bool | ||||||
|  | 	templateFuncs      template.FuncMap | ||||||
|  | 	templateLeftDelim  string | ||||||
|  | 	templateRightDelim string | ||||||
|  | 	templateOptions    []string | ||||||
|  | 	templateData       interface{} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | type fixtureFile struct { | ||||||
|  | 	path       string | ||||||
|  | 	fileName   string | ||||||
|  | 	content    []byte | ||||||
|  | 	insertSQLs []insertSQL | ||||||
|  | } | ||||||
|  |  | ||||||
|  | type insertSQL struct { | ||||||
|  | 	sql    string | ||||||
|  | 	params []interface{} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | var ( | ||||||
|  | 	testDatabaseRegexp = regexp.MustCompile("(?i)test") | ||||||
|  |  | ||||||
|  | 	errDatabaseIsRequired = fmt.Errorf("testfixtures: database is required") | ||||||
|  | 	errDialectIsRequired  = fmt.Errorf("testfixtures: dialect is required") | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // New instantiates a new Loader instance. The "Database" and "Driver" | ||||||
|  | // options are required. | ||||||
|  | func New(options ...func(*Loader) error) (*Loader, error) { | ||||||
|  | 	l := &Loader{ | ||||||
|  | 		templateLeftDelim:  "{{", | ||||||
|  | 		templateRightDelim: "}}", | ||||||
|  | 		templateOptions:    []string{"missingkey=zero"}, | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	for _, option := range options { | ||||||
|  | 		if err := option(l); err != nil { | ||||||
|  | 			return nil, err | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if l.db == nil { | ||||||
|  | 		return nil, errDatabaseIsRequired | ||||||
|  | 	} | ||||||
|  | 	if l.helper == nil { | ||||||
|  | 		return nil, errDialectIsRequired | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if err := l.helper.init(l.db); err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	if err := l.buildInsertSQLs(); err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return l, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Database sets an existing sql.DB instant to Loader. | ||||||
|  | func Database(db *sql.DB) func(*Loader) error { | ||||||
|  | 	return func(l *Loader) error { | ||||||
|  | 		l.db = db | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Dialect informs Loader about which database dialect you're using. | ||||||
|  | // | ||||||
|  | // Possible options are "postgresql", "timescaledb", "mysql", "mariadb", | ||||||
|  | // "sqlite" and "sqlserver". | ||||||
|  | func Dialect(dialect string) func(*Loader) error { | ||||||
|  | 	return func(l *Loader) error { | ||||||
|  | 		h, err := helperForDialect(dialect) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return err | ||||||
|  | 		} | ||||||
|  | 		l.helper = h | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func helperForDialect(dialect string) (helper, error) { | ||||||
|  | 	switch dialect { | ||||||
|  | 	case "postgres", "postgresql", "timescaledb": | ||||||
|  | 		return &postgreSQL{}, nil | ||||||
|  | 	case "mysql", "mariadb": | ||||||
|  | 		return &mySQL{}, nil | ||||||
|  | 	case "sqlite", "sqlite3": | ||||||
|  | 		return &sqlite{}, nil | ||||||
|  | 	case "mssql", "sqlserver": | ||||||
|  | 		return &sqlserver{}, nil | ||||||
|  | 	default: | ||||||
|  | 		return nil, fmt.Errorf(`testfixtures: unrecognized dialect "%s"`, dialect) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // UseAlterConstraint If true, the contraint disabling will do | ||||||
|  | // using ALTER CONTRAINT sintax, only allowed in PG >= 9.4. | ||||||
|  | // If false, the constraint disabling will use DISABLE TRIGGER ALL, | ||||||
|  | // which requires SUPERUSER privileges. | ||||||
|  | // | ||||||
|  | // Only valid for PostgreSQL. Returns an error otherwise. | ||||||
|  | func UseAlterConstraint() func(*Loader) error { | ||||||
|  | 	return func(l *Loader) error { | ||||||
|  | 		pgHelper, ok := l.helper.(*postgreSQL) | ||||||
|  | 		if !ok { | ||||||
|  | 			return fmt.Errorf("testfixtures: UseAlterConstraint is only valid for PostgreSQL databases") | ||||||
|  | 		} | ||||||
|  | 		pgHelper.useAlterConstraint = true | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // SkipResetSequences prevents Loader from reseting sequences after loading | ||||||
|  | // fixtures. | ||||||
|  | // | ||||||
|  | // Only valid for PostgreSQL. Returns an error otherwise. | ||||||
|  | func SkipResetSequences() func(*Loader) error { | ||||||
|  | 	return func(l *Loader) error { | ||||||
|  | 		pgHelper, ok := l.helper.(*postgreSQL) | ||||||
|  | 		if !ok { | ||||||
|  | 			return fmt.Errorf("testfixtures: SkipResetSequences is only valid for PostgreSQL databases") | ||||||
|  | 		} | ||||||
|  | 		pgHelper.skipResetSequences = true | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // ResetSequencesTo sets the value the sequences will be reset to. | ||||||
|  | // | ||||||
|  | // Defaults to 10000. | ||||||
|  | // | ||||||
|  | // Only valid for PostgreSQL. Returns an error otherwise. | ||||||
|  | func ResetSequencesTo(value int64) func(*Loader) error { | ||||||
|  | 	return func(l *Loader) error { | ||||||
|  | 		pgHelper, ok := l.helper.(*postgreSQL) | ||||||
|  | 		if !ok { | ||||||
|  | 			return fmt.Errorf("testfixtures: ResetSequencesTo is only valid for PostgreSQL databases") | ||||||
|  | 		} | ||||||
|  | 		pgHelper.resetSequencesTo = value | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // DangerousSkipTestDatabaseCheck will make Loader not check if the database | ||||||
|  | // name contains "test". Use with caution! | ||||||
|  | func DangerousSkipTestDatabaseCheck() func(*Loader) error { | ||||||
|  | 	return func(l *Loader) error { | ||||||
|  | 		l.skipTestDatabaseCheck = true | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Directory informs Loader to load YAML files from a given directory. | ||||||
|  | func Directory(dir string) func(*Loader) error { | ||||||
|  | 	return func(l *Loader) error { | ||||||
|  | 		fixtures, err := l.fixturesFromDir(dir) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return err | ||||||
|  | 		} | ||||||
|  | 		l.fixturesFiles = append(l.fixturesFiles, fixtures...) | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Files informs Loader to load a given set of YAML files. | ||||||
|  | func Files(files ...string) func(*Loader) error { | ||||||
|  | 	return func(l *Loader) error { | ||||||
|  | 		fixtures, err := l.fixturesFromFiles(files...) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return err | ||||||
|  | 		} | ||||||
|  | 		l.fixturesFiles = append(l.fixturesFiles, fixtures...) | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Paths inform Loader to load a given set of YAML files and directories. | ||||||
|  | func Paths(paths ...string) func(*Loader) error { | ||||||
|  | 	return func(l *Loader) error { | ||||||
|  | 		fixtures, err := l.fixturesFromPaths(paths...) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return err | ||||||
|  | 		} | ||||||
|  | 		l.fixturesFiles = append(l.fixturesFiles, fixtures...) | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Location makes Loader use the given location by default when parsing | ||||||
|  | // dates. If not given, by default it uses the value of time.Local. | ||||||
|  | func Location(location *time.Location) func(*Loader) error { | ||||||
|  | 	return func(l *Loader) error { | ||||||
|  | 		l.location = location | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Template makes loader process each YAML file as an template using the | ||||||
|  | // text/template package. | ||||||
|  | // | ||||||
|  | // For more information on how templates work in Go please read: | ||||||
|  | // https://golang.org/pkg/text/template/ | ||||||
|  | // | ||||||
|  | // If not given the YAML files are parsed as is. | ||||||
|  | func Template() func(*Loader) error { | ||||||
|  | 	return func(l *Loader) error { | ||||||
|  | 		l.template = true | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // TemplateFuncs allow choosing which functions will be available | ||||||
|  | // when processing templates. | ||||||
|  | // | ||||||
|  | // For more information see: https://golang.org/pkg/text/template/#Template.Funcs | ||||||
|  | func TemplateFuncs(funcs template.FuncMap) func(*Loader) error { | ||||||
|  | 	return func(l *Loader) error { | ||||||
|  | 		if !l.template { | ||||||
|  | 			return fmt.Errorf(`testfixtures: the Template() options is required in order to use the TemplateFuns() option`) | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		l.templateFuncs = funcs | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // TemplateDelims allow choosing which delimiters will be used for templating. | ||||||
|  | // This defaults to "{{" and "}}". | ||||||
|  | // | ||||||
|  | // For more information see https://golang.org/pkg/text/template/#Template.Delims | ||||||
|  | func TemplateDelims(left, right string) func(*Loader) error { | ||||||
|  | 	return func(l *Loader) error { | ||||||
|  | 		if !l.template { | ||||||
|  | 			return fmt.Errorf(`testfixtures: the Template() options is required in order to use the TemplateDelims() option`) | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		l.templateLeftDelim = left | ||||||
|  | 		l.templateRightDelim = right | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // TemplateOptions allows you to specific which text/template options will | ||||||
|  | // be enabled when processing templates. | ||||||
|  | // | ||||||
|  | // This defaults to "missingkey=zero". Check the available options here: | ||||||
|  | // https://golang.org/pkg/text/template/#Template.Option | ||||||
|  | func TemplateOptions(options ...string) func(*Loader) error { | ||||||
|  | 	return func(l *Loader) error { | ||||||
|  | 		if !l.template { | ||||||
|  | 			return fmt.Errorf(`testfixtures: the Template() options is required in order to use the TemplateOptions() option`) | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		l.templateOptions = options | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // TemplateData allows you to specify which data will be available | ||||||
|  | // when processing templates. Data is accesible by prefixing it with a "." | ||||||
|  | // like {{.MyKey}}. | ||||||
|  | func TemplateData(data interface{}) func(*Loader) error { | ||||||
|  | 	return func(l *Loader) error { | ||||||
|  | 		if !l.template { | ||||||
|  | 			return fmt.Errorf(`testfixtures: the Template() options is required in order to use the TemplateData() option`) | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		l.templateData = data | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // EnsureTestDatabase returns an error if the database name does not contains | ||||||
|  | // "test". | ||||||
|  | func (l *Loader) EnsureTestDatabase() error { | ||||||
|  | 	dbName, err := l.helper.databaseName(l.db) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	if !testDatabaseRegexp.MatchString(dbName) { | ||||||
|  | 		return fmt.Errorf(`testfixtures: database "%s" does not appear to be a test database`, dbName) | ||||||
|  | 	} | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Load wipes and after load all fixtures in the database. | ||||||
|  | //     if err := fixtures.Load(); err != nil { | ||||||
|  | //             ... | ||||||
|  | //     } | ||||||
|  | func (l *Loader) Load() error { | ||||||
|  | 	if !l.skipTestDatabaseCheck { | ||||||
|  | 		if err := l.EnsureTestDatabase(); err != nil { | ||||||
|  | 			return err | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	err := l.helper.disableReferentialIntegrity(l.db, func(tx *sql.Tx) error { | ||||||
|  | 		for _, file := range l.fixturesFiles { | ||||||
|  | 			modified, err := l.helper.isTableModified(tx, file.fileNameWithoutExtension()) | ||||||
|  | 			if err != nil { | ||||||
|  | 				return err | ||||||
|  | 			} | ||||||
|  | 			if !modified { | ||||||
|  | 				continue | ||||||
|  | 			} | ||||||
|  | 			if err := file.delete(tx, l.helper); err != nil { | ||||||
|  | 				return err | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			err = l.helper.whileInsertOnTable(tx, file.fileNameWithoutExtension(), func() error { | ||||||
|  | 				for j, i := range file.insertSQLs { | ||||||
|  | 					if _, err := tx.Exec(i.sql, i.params...); err != nil { | ||||||
|  | 						return &InsertError{ | ||||||
|  | 							Err:    err, | ||||||
|  | 							File:   file.fileName, | ||||||
|  | 							Index:  j, | ||||||
|  | 							SQL:    i.sql, | ||||||
|  | 							Params: i.params, | ||||||
|  | 						} | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 				return nil | ||||||
|  | 			}) | ||||||
|  | 			if err != nil { | ||||||
|  | 				return err | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		return nil | ||||||
|  | 	}) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	return l.helper.afterLoad(l.db) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // InsertError will be returned if any error happens on database while | ||||||
|  | // inserting the record. | ||||||
|  | type InsertError struct { | ||||||
|  | 	Err    error | ||||||
|  | 	File   string | ||||||
|  | 	Index  int | ||||||
|  | 	SQL    string | ||||||
|  | 	Params []interface{} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (e *InsertError) Error() string { | ||||||
|  | 	return fmt.Sprintf( | ||||||
|  | 		"testfixtures: error inserting record: %v, on file: %s, index: %d, sql: %s, params: %v", | ||||||
|  | 		e.Err, | ||||||
|  | 		e.File, | ||||||
|  | 		e.Index, | ||||||
|  | 		e.SQL, | ||||||
|  | 		e.Params, | ||||||
|  | 	) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (l *Loader) buildInsertSQLs() error { | ||||||
|  | 	for _, f := range l.fixturesFiles { | ||||||
|  | 		var records interface{} | ||||||
|  | 		if err := yaml.Unmarshal(f.content, &records); err != nil { | ||||||
|  | 			return fmt.Errorf("testfixtures: could not unmarshal YAML: %w", err) | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		switch records := records.(type) { | ||||||
|  | 		case []interface{}: | ||||||
|  | 			f.insertSQLs = make([]insertSQL, 0, len(records)) | ||||||
|  |  | ||||||
|  | 			for _, record := range records { | ||||||
|  | 				recordMap, ok := record.(map[interface{}]interface{}) | ||||||
|  | 				if !ok { | ||||||
|  | 					return fmt.Errorf("testfixtures: could not cast record: not a map[interface{}]interface{}") | ||||||
|  | 				} | ||||||
|  |  | ||||||
|  | 				sql, values, err := l.buildInsertSQL(f, recordMap) | ||||||
|  | 				if err != nil { | ||||||
|  | 					return err | ||||||
|  | 				} | ||||||
|  |  | ||||||
|  | 				f.insertSQLs = append(f.insertSQLs, insertSQL{sql, values}) | ||||||
|  | 			} | ||||||
|  | 		case map[interface{}]interface{}: | ||||||
|  | 			f.insertSQLs = make([]insertSQL, 0, len(records)) | ||||||
|  |  | ||||||
|  | 			for _, record := range records { | ||||||
|  | 				recordMap, ok := record.(map[interface{}]interface{}) | ||||||
|  | 				if !ok { | ||||||
|  | 					return fmt.Errorf("testfixtures: could not cast record: not a map[interface{}]interface{}") | ||||||
|  | 				} | ||||||
|  |  | ||||||
|  | 				sql, values, err := l.buildInsertSQL(f, recordMap) | ||||||
|  | 				if err != nil { | ||||||
|  | 					return err | ||||||
|  | 				} | ||||||
|  |  | ||||||
|  | 				f.insertSQLs = append(f.insertSQLs, insertSQL{sql, values}) | ||||||
|  | 			} | ||||||
|  | 		default: | ||||||
|  | 			return fmt.Errorf("testfixtures: fixture is not a slice or map") | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (f *fixtureFile) fileNameWithoutExtension() string { | ||||||
|  | 	return strings.Replace(f.fileName, filepath.Ext(f.fileName), "", 1) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (f *fixtureFile) delete(tx *sql.Tx, h helper) error { | ||||||
|  | 	if _, err := tx.Exec(fmt.Sprintf("DELETE FROM %s", h.quoteKeyword(f.fileNameWithoutExtension()))); err != nil { | ||||||
|  | 		return fmt.Errorf(`testfixtures: could not clean table "%s": %w`, f.fileNameWithoutExtension(), err) | ||||||
|  | 	} | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (l *Loader) buildInsertSQL(f *fixtureFile, record map[interface{}]interface{}) (sqlStr string, values []interface{}, err error) { | ||||||
|  | 	var ( | ||||||
|  | 		sqlColumns = make([]string, 0, len(record)) | ||||||
|  | 		sqlValues  = make([]string, 0, len(record)) | ||||||
|  | 		i          = 1 | ||||||
|  | 	) | ||||||
|  | 	for key, value := range record { | ||||||
|  | 		keyStr, ok := key.(string) | ||||||
|  | 		if !ok { | ||||||
|  | 			err = fmt.Errorf("testfixtures: record map key is not a string") | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		sqlColumns = append(sqlColumns, l.helper.quoteKeyword(keyStr)) | ||||||
|  |  | ||||||
|  | 		// if string, try convert to SQL or time | ||||||
|  | 		// if map or array, convert to json | ||||||
|  | 		switch v := value.(type) { | ||||||
|  | 		case string: | ||||||
|  | 			if strings.HasPrefix(v, "RAW=") { | ||||||
|  | 				sqlValues = append(sqlValues, strings.TrimPrefix(v, "RAW=")) | ||||||
|  | 				continue | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			if t, err := l.tryStrToDate(v); err == nil { | ||||||
|  | 				value = t | ||||||
|  | 			} | ||||||
|  | 		case []interface{}, map[interface{}]interface{}: | ||||||
|  | 			value = recursiveToJSON(v) | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		switch l.helper.paramType() { | ||||||
|  | 		case paramTypeDollar: | ||||||
|  | 			sqlValues = append(sqlValues, fmt.Sprintf("$%d", i)) | ||||||
|  | 		case paramTypeQuestion: | ||||||
|  | 			sqlValues = append(sqlValues, "?") | ||||||
|  | 		case paramTypeAtSign: | ||||||
|  | 			sqlValues = append(sqlValues, fmt.Sprintf("@p%d", i)) | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		values = append(values, value) | ||||||
|  | 		i++ | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	sqlStr = fmt.Sprintf( | ||||||
|  | 		"INSERT INTO %s (%s) VALUES (%s)", | ||||||
|  | 		l.helper.quoteKeyword(f.fileNameWithoutExtension()), | ||||||
|  | 		strings.Join(sqlColumns, ", "), | ||||||
|  | 		strings.Join(sqlValues, ", "), | ||||||
|  | 	) | ||||||
|  | 	return | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (l *Loader) fixturesFromDir(dir string) ([]*fixtureFile, error) { | ||||||
|  | 	fileinfos, err := ioutil.ReadDir(dir) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, fmt.Errorf(`testfixtures: could not stat directory "%s": %w`, dir, err) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	files := make([]*fixtureFile, 0, len(fileinfos)) | ||||||
|  |  | ||||||
|  | 	for _, fileinfo := range fileinfos { | ||||||
|  | 		fileExt := filepath.Ext(fileinfo.Name()) | ||||||
|  | 		if !fileinfo.IsDir() && (fileExt == ".yml" || fileExt == ".yaml") { | ||||||
|  | 			fixture := &fixtureFile{ | ||||||
|  | 				path:     path.Join(dir, fileinfo.Name()), | ||||||
|  | 				fileName: fileinfo.Name(), | ||||||
|  | 			} | ||||||
|  | 			fixture.content, err = ioutil.ReadFile(fixture.path) | ||||||
|  | 			if err != nil { | ||||||
|  | 				return nil, fmt.Errorf(`testfixtures: could not read file "%s": %w`, fixture.path, err) | ||||||
|  | 			} | ||||||
|  | 			if err := l.processFileTemplate(fixture); err != nil { | ||||||
|  | 				return nil, err | ||||||
|  | 			} | ||||||
|  | 			files = append(files, fixture) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return files, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (l *Loader) fixturesFromFiles(fileNames ...string) ([]*fixtureFile, error) { | ||||||
|  | 	var ( | ||||||
|  | 		fixtureFiles = make([]*fixtureFile, 0, len(fileNames)) | ||||||
|  | 		err          error | ||||||
|  | 	) | ||||||
|  |  | ||||||
|  | 	for _, f := range fileNames { | ||||||
|  | 		fixture := &fixtureFile{ | ||||||
|  | 			path:     f, | ||||||
|  | 			fileName: filepath.Base(f), | ||||||
|  | 		} | ||||||
|  | 		fixture.content, err = ioutil.ReadFile(fixture.path) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return nil, fmt.Errorf(`testfixtures: could not read file "%s": %w`, fixture.path, err) | ||||||
|  | 		} | ||||||
|  | 		if err := l.processFileTemplate(fixture); err != nil { | ||||||
|  | 			return nil, err | ||||||
|  | 		} | ||||||
|  | 		fixtureFiles = append(fixtureFiles, fixture) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return fixtureFiles, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (l *Loader) fixturesFromPaths(paths ...string) ([]*fixtureFile, error) { | ||||||
|  | 	fixtureExtractor := func(p string, isDir bool) ([]*fixtureFile, error) { | ||||||
|  | 		if isDir { | ||||||
|  | 			return l.fixturesFromDir(p) | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		return l.fixturesFromFiles(p) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	var fixtureFiles []*fixtureFile | ||||||
|  |  | ||||||
|  | 	for _, p := range paths { | ||||||
|  | 		f, err := os.Stat(p) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return nil, fmt.Errorf(`testfixtures: could not stat path "%s": %w`, p, err) | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		fixtures, err := fixtureExtractor(p, f.IsDir()) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return nil, err | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		fixtureFiles = append(fixtureFiles, fixtures...) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return fixtureFiles, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (l *Loader) processFileTemplate(f *fixtureFile) error { | ||||||
|  | 	if !l.template { | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	t := template.New(""). | ||||||
|  | 		Funcs(l.templateFuncs). | ||||||
|  | 		Delims(l.templateLeftDelim, l.templateRightDelim). | ||||||
|  | 		Option(l.templateOptions...) | ||||||
|  | 	t, err := t.Parse(string(f.content)) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return fmt.Errorf(`textfixtures: error on parsing template in %s: %w`, f.fileName, err) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	var buffer bytes.Buffer | ||||||
|  | 	if err := t.Execute(&buffer, l.templateData); err != nil { | ||||||
|  | 		return fmt.Errorf(`textfixtures: error on executing template in %s: %w`, f.fileName, err) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	f.content = buffer.Bytes() | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
							
								
								
									
										43
									
								
								vendor/github.com/go-testfixtures/testfixtures/v3/time.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								vendor/github.com/go-testfixtures/testfixtures/v3/time.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,43 @@ | |||||||
|  | package testfixtures | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | 	"time" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | var timeFormats = [...]string{ | ||||||
|  | 	"2006-01-02", | ||||||
|  | 	"2006-01-02 15:04", | ||||||
|  | 	"2006-01-02 15:04:05", | ||||||
|  | 	"20060102", | ||||||
|  | 	"20060102 15:04", | ||||||
|  | 	"20060102 15:04:05", | ||||||
|  | 	"02/01/2006", | ||||||
|  | 	"02/01/2006 15:04", | ||||||
|  | 	"02/01/2006 15:04:05", | ||||||
|  | 	"2006-01-02T15:04-07:00", | ||||||
|  | 	"2006-01-02T15:04:05-07:00", | ||||||
|  | 	"2006-01-02T15:04:05Z07:00", | ||||||
|  | 	"2006-01-02 15:04:05Z07:00", | ||||||
|  | 	"2006-01-02T15:04:05Z0700", | ||||||
|  | 	"2006-01-02 15:04:05Z0700", | ||||||
|  | 	"2006-01-02T15:04:05Z07", | ||||||
|  | 	"2006-01-02 15:04:05Z07", | ||||||
|  | 	"2006-01-02 15:04:05 MST", | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (l *Loader) tryStrToDate(s string) (time.Time, error) { | ||||||
|  | 	loc := l.location | ||||||
|  | 	if loc == nil { | ||||||
|  | 		loc = time.Local | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	for _, f := range timeFormats { | ||||||
|  | 		t, err := time.ParseInLocation(f, s, loc) | ||||||
|  | 		if err != nil { | ||||||
|  | 			continue | ||||||
|  | 		} | ||||||
|  | 		return t, nil | ||||||
|  | 	} | ||||||
|  | 	return time.Time{}, fmt.Errorf(`testfixtures: could not convert string "%s" to time`, s) | ||||||
|  | } | ||||||
							
								
								
									
										4
									
								
								vendor/github.com/mattn/go-sqlite3/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								vendor/github.com/mattn/go-sqlite3/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -12,6 +12,8 @@ go: | |||||||
|   - 1.9.x |   - 1.9.x | ||||||
|   - 1.10.x |   - 1.10.x | ||||||
|   - 1.11.x |   - 1.11.x | ||||||
|  |   - 1.12.x | ||||||
|  |   - 1.13.x | ||||||
|   - master |   - master | ||||||
|  |  | ||||||
| before_install: | before_install: | ||||||
| @@ -27,5 +29,5 @@ script: | |||||||
|   - $HOME/gopath/bin/goveralls -repotoken 3qJVUE0iQwqnCbmNcDsjYu1nh4J4KIFXx |   - $HOME/gopath/bin/goveralls -repotoken 3qJVUE0iQwqnCbmNcDsjYu1nh4J4KIFXx | ||||||
|   - go test -race -v . -tags "" |   - go test -race -v . -tags "" | ||||||
|   - go test -race -v . -tags "libsqlite3" |   - go test -race -v . -tags "libsqlite3" | ||||||
|   - go test -race -v . -tags "sqlite_allow_uri_authority sqlite_app_armor sqlite_foreign_keys sqlite_fts5 sqlite_icu sqlite_introspect sqlite_json sqlite_secure_delete sqlite_see sqlite_stat4 sqlite_trace sqlite_userauth sqlite_vacuum_incr sqlite_vtable sqlite_unlock_notify" |   - go test -race -v . -tags "sqlite_allow_uri_authority sqlite_app_armor sqlite_foreign_keys sqlite_fts5 sqlite_icu sqlite_introspect sqlite_json sqlite_preupdate_hook sqlite_secure_delete sqlite_see sqlite_stat4 sqlite_trace sqlite_userauth sqlite_vacuum_incr sqlite_vtable sqlite_unlock_notify" | ||||||
|   - go test -race -v . -tags "sqlite_vacuum_full" |   - go test -race -v . -tags "sqlite_vacuum_full" | ||||||
							
								
								
									
										51
									
								
								vendor/github.com/mattn/go-sqlite3/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										51
									
								
								vendor/github.com/mattn/go-sqlite3/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -3,6 +3,7 @@ go-sqlite3 | |||||||
|  |  | ||||||
| [](http://godoc.org/github.com/mattn/go-sqlite3) | [](http://godoc.org/github.com/mattn/go-sqlite3) | ||||||
| [](https://travis-ci.org/mattn/go-sqlite3) | [](https://travis-ci.org/mattn/go-sqlite3) | ||||||
|  | [](https://opencollective.com/mattn-go-sqlite3)  | ||||||
| [](https://coveralls.io/r/mattn/go-sqlite3?branch=master) | [](https://coveralls.io/r/mattn/go-sqlite3?branch=master) | ||||||
| [](https://goreportcard.com/report/github.com/mattn/go-sqlite3) | [](https://goreportcard.com/report/github.com/mattn/go-sqlite3) | ||||||
|  |  | ||||||
| @@ -16,10 +17,16 @@ Supported Golang version: See .travis.yml | |||||||
|  |  | ||||||
| ### Overview | ### Overview | ||||||
|  |  | ||||||
|  | - [go-sqlite3](#go-sqlite3) | ||||||
|  | - [Description](#description) | ||||||
|  |     - [Overview](#overview) | ||||||
| - [Installation](#installation) | - [Installation](#installation) | ||||||
| - [API Reference](#api-reference) | - [API Reference](#api-reference) | ||||||
| - [Connection String](#connection-string) | - [Connection String](#connection-string) | ||||||
|  |   - [DSN Examples](#dsn-examples) | ||||||
| - [Features](#features) | - [Features](#features) | ||||||
|  |     - [Usage](#usage) | ||||||
|  |     - [Feature / Extension List](#feature--extension-list) | ||||||
| - [Compilation](#compilation) | - [Compilation](#compilation) | ||||||
|   - [Android](#android) |   - [Android](#android) | ||||||
| - [ARM](#arm) | - [ARM](#arm) | ||||||
| @@ -34,11 +41,22 @@ Supported Golang version: See .travis.yml | |||||||
|   - [Errors](#errors) |   - [Errors](#errors) | ||||||
| - [User Authentication](#user-authentication) | - [User Authentication](#user-authentication) | ||||||
|   - [Compile](#compile) |   - [Compile](#compile) | ||||||
|   - [Usage](#usage) |   - [Usage](#usage-1) | ||||||
|  |     - [Create protected database](#create-protected-database) | ||||||
|  |     - [Password Encoding](#password-encoding) | ||||||
|  |       - [Available Encoders](#available-encoders) | ||||||
|  |     - [Restrictions](#restrictions) | ||||||
|  |     - [Support](#support) | ||||||
|  |     - [User Management](#user-management) | ||||||
|  |       - [SQL](#sql) | ||||||
|  |         - [Examples](#examples) | ||||||
|  |       - [*SQLiteConn](#sqliteconn) | ||||||
|  |     - [Attached database](#attached-database) | ||||||
| - [Extensions](#extensions) | - [Extensions](#extensions) | ||||||
|   - [Spatialite](#spatialite) |   - [Spatialite](#spatialite) | ||||||
| - [FAQ](#faq) | - [FAQ](#faq) | ||||||
| - [License](#license) | - [License](#license) | ||||||
|  | - [Author](#author) | ||||||
|  |  | ||||||
| # Installation | # Installation | ||||||
|  |  | ||||||
| @@ -149,6 +167,7 @@ go build --tags "icu json1 fts5 secure_delete" | |||||||
| |  International Components for Unicode | sqlite_icu | This option causes the International Components for Unicode or "ICU" extension to SQLite to be added to the build | | |  International Components for Unicode | sqlite_icu | This option causes the International Components for Unicode or "ICU" extension to SQLite to be added to the build | | ||||||
| | Introspect PRAGMAS | sqlite_introspect | This option adds some extra PRAGMA statements. <ul><li>PRAGMA function_list</li><li>PRAGMA module_list</li><li>PRAGMA pragma_list</li></ul> | | | Introspect PRAGMAS | sqlite_introspect | This option adds some extra PRAGMA statements. <ul><li>PRAGMA function_list</li><li>PRAGMA module_list</li><li>PRAGMA pragma_list</li></ul> | | ||||||
| | JSON SQL Functions | sqlite_json | When this option is defined in the amalgamation, the JSON SQL functions are added to the build automatically | | | JSON SQL Functions | sqlite_json | When this option is defined in the amalgamation, the JSON SQL functions are added to the build automatically | | ||||||
|  | | Pre Update Hook | sqlite_preupdate_hook | Registers a callback function that is invoked prior to each INSERT, UPDATE, and DELETE operation on a database table. | | ||||||
| | Secure Delete | sqlite_secure_delete | This compile-time option changes the default setting of the secure_delete pragma.<br><br>When this option is not used, secure_delete defaults to off. When this option is present, secure_delete defaults to on.<br><br>The secure_delete setting causes deleted content to be overwritten with zeros. There is a small performance penalty since additional I/O must occur.<br><br>On the other hand, secure_delete can prevent fragments of sensitive information from lingering in unused parts of the database file after it has been deleted. See the documentation on the secure_delete pragma for additional information | | | Secure Delete | sqlite_secure_delete | This compile-time option changes the default setting of the secure_delete pragma.<br><br>When this option is not used, secure_delete defaults to off. When this option is present, secure_delete defaults to on.<br><br>The secure_delete setting causes deleted content to be overwritten with zeros. There is a small performance penalty since additional I/O must occur.<br><br>On the other hand, secure_delete can prevent fragments of sensitive information from lingering in unused parts of the database file after it has been deleted. See the documentation on the secure_delete pragma for additional information | | ||||||
| | Secure Delete (FAST) | sqlite_secure_delete_fast | For more information see [PRAGMA secure_delete](https://www.sqlite.org/pragma.html#pragma_secure_delete) | | | Secure Delete (FAST) | sqlite_secure_delete_fast | For more information see [PRAGMA secure_delete](https://www.sqlite.org/pragma.html#pragma_secure_delete) | | ||||||
| | Tracing / Debug | sqlite_trace | Activate trace functions | | | Tracing / Debug | sqlite_trace | Activate trace functions | | ||||||
| @@ -504,6 +523,36 @@ For an example see [shaxbee/go-spatialite](https://github.com/shaxbee/go-spatial | |||||||
|  |  | ||||||
|     More information see [#209](https://github.com/mattn/go-sqlite3/issues/209) |     More information see [#209](https://github.com/mattn/go-sqlite3/issues/209) | ||||||
|  |  | ||||||
|  | ## Contributors | ||||||
|  |  | ||||||
|  | ### Code Contributors | ||||||
|  |  | ||||||
|  | This project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)]. | ||||||
|  | <a href="https://github.com/mattn/go-sqlite3/graphs/contributors"><img src="https://opencollective.com/mattn-go-sqlite3/contributors.svg?width=890&button=false" /></a> | ||||||
|  |  | ||||||
|  | ### Financial Contributors | ||||||
|  |  | ||||||
|  | Become a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/mattn-go-sqlite3/contribute)] | ||||||
|  |  | ||||||
|  | #### Individuals | ||||||
|  |  | ||||||
|  | <a href="https://opencollective.com/mattn-go-sqlite3"><img src="https://opencollective.com/mattn-go-sqlite3/individuals.svg?width=890"></a> | ||||||
|  |  | ||||||
|  | #### Organizations | ||||||
|  |  | ||||||
|  | Support this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/mattn-go-sqlite3/contribute)] | ||||||
|  |  | ||||||
|  | <a href="https://opencollective.com/mattn-go-sqlite3/organization/0/website"><img src="https://opencollective.com/mattn-go-sqlite3/organization/0/avatar.svg"></a> | ||||||
|  | <a href="https://opencollective.com/mattn-go-sqlite3/organization/1/website"><img src="https://opencollective.com/mattn-go-sqlite3/organization/1/avatar.svg"></a> | ||||||
|  | <a href="https://opencollective.com/mattn-go-sqlite3/organization/2/website"><img src="https://opencollective.com/mattn-go-sqlite3/organization/2/avatar.svg"></a> | ||||||
|  | <a href="https://opencollective.com/mattn-go-sqlite3/organization/3/website"><img src="https://opencollective.com/mattn-go-sqlite3/organization/3/avatar.svg"></a> | ||||||
|  | <a href="https://opencollective.com/mattn-go-sqlite3/organization/4/website"><img src="https://opencollective.com/mattn-go-sqlite3/organization/4/avatar.svg"></a> | ||||||
|  | <a href="https://opencollective.com/mattn-go-sqlite3/organization/5/website"><img src="https://opencollective.com/mattn-go-sqlite3/organization/5/avatar.svg"></a> | ||||||
|  | <a href="https://opencollective.com/mattn-go-sqlite3/organization/6/website"><img src="https://opencollective.com/mattn-go-sqlite3/organization/6/avatar.svg"></a> | ||||||
|  | <a href="https://opencollective.com/mattn-go-sqlite3/organization/7/website"><img src="https://opencollective.com/mattn-go-sqlite3/organization/7/avatar.svg"></a> | ||||||
|  | <a href="https://opencollective.com/mattn-go-sqlite3/organization/8/website"><img src="https://opencollective.com/mattn-go-sqlite3/organization/8/avatar.svg"></a> | ||||||
|  | <a href="https://opencollective.com/mattn-go-sqlite3/organization/9/website"><img src="https://opencollective.com/mattn-go-sqlite3/organization/9/avatar.svg"></a> | ||||||
|  |  | ||||||
| # License | # License | ||||||
|  |  | ||||||
| MIT: http://mattn.mit-license.org/2018 | MIT: http://mattn.mit-license.org/2018 | ||||||
|   | |||||||
							
								
								
									
										8
									
								
								vendor/github.com/mattn/go-sqlite3/backup.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								vendor/github.com/mattn/go-sqlite3/backup.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| // Copyright (C) 2014 Yasuhiro Matsumoto <mattn.jp@gmail.com>. | // Copyright (C) 2019 Yasuhiro Matsumoto <mattn.jp@gmail.com>. | ||||||
| // | // | ||||||
| // Use of this source code is governed by an MIT-style | // Use of this source code is governed by an MIT-style | ||||||
| // license that can be found in the LICENSE file. | // license that can be found in the LICENSE file. | ||||||
| @@ -25,18 +25,18 @@ type SQLiteBackup struct { | |||||||
| } | } | ||||||
|  |  | ||||||
| // Backup make backup from src to dest. | // Backup make backup from src to dest. | ||||||
| func (c *SQLiteConn) Backup(dest string, conn *SQLiteConn, src string) (*SQLiteBackup, error) { | func (destConn *SQLiteConn) Backup(dest string, srcConn *SQLiteConn, src string) (*SQLiteBackup, error) { | ||||||
| 	destptr := C.CString(dest) | 	destptr := C.CString(dest) | ||||||
| 	defer C.free(unsafe.Pointer(destptr)) | 	defer C.free(unsafe.Pointer(destptr)) | ||||||
| 	srcptr := C.CString(src) | 	srcptr := C.CString(src) | ||||||
| 	defer C.free(unsafe.Pointer(srcptr)) | 	defer C.free(unsafe.Pointer(srcptr)) | ||||||
|  |  | ||||||
| 	if b := C.sqlite3_backup_init(c.db, destptr, conn.db, srcptr); b != nil { | 	if b := C.sqlite3_backup_init(destConn.db, destptr, srcConn.db, srcptr); b != nil { | ||||||
| 		bb := &SQLiteBackup{b: b} | 		bb := &SQLiteBackup{b: b} | ||||||
| 		runtime.SetFinalizer(bb, (*SQLiteBackup).Finish) | 		runtime.SetFinalizer(bb, (*SQLiteBackup).Finish) | ||||||
| 		return bb, nil | 		return bb, nil | ||||||
| 	} | 	} | ||||||
| 	return nil, c.lastError() | 	return nil, destConn.lastError() | ||||||
| } | } | ||||||
|  |  | ||||||
| // Step to backs up for one step. Calls the underlying `sqlite3_backup_step` | // Step to backs up for one step. Calls the underlying `sqlite3_backup_step` | ||||||
|   | |||||||
							
								
								
									
										26
									
								
								vendor/github.com/mattn/go-sqlite3/callback.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										26
									
								
								vendor/github.com/mattn/go-sqlite3/callback.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| // Copyright (C) 2014 Yasuhiro Matsumoto <mattn.jp@gmail.com>. | // Copyright (C) 2019 Yasuhiro Matsumoto <mattn.jp@gmail.com>. | ||||||
| // | // | ||||||
| // Use of this source code is governed by an MIT-style | // Use of this source code is governed by an MIT-style | ||||||
| // license that can be found in the LICENSE file. | // license that can be found in the LICENSE file. | ||||||
| @@ -83,8 +83,22 @@ func authorizerTrampoline(handle uintptr, op int, arg1 *C.char, arg2 *C.char, ar | |||||||
| 	return callback(op, C.GoString(arg1), C.GoString(arg2), C.GoString(arg3)) | 	return callback(op, C.GoString(arg1), C.GoString(arg2), C.GoString(arg3)) | ||||||
| } | } | ||||||
|  |  | ||||||
| // Use handles to avoid passing Go pointers to C. | //export preUpdateHookTrampoline | ||||||
|  | func preUpdateHookTrampoline(handle uintptr, dbHandle uintptr, op int, db *C.char, table *C.char, oldrowid int64, newrowid int64) { | ||||||
|  | 	hval := lookupHandleVal(handle) | ||||||
|  | 	data := SQLitePreUpdateData{ | ||||||
|  | 		Conn:         hval.db, | ||||||
|  | 		Op:           op, | ||||||
|  | 		DatabaseName: C.GoString(db), | ||||||
|  | 		TableName:    C.GoString(table), | ||||||
|  | 		OldRowID:     oldrowid, | ||||||
|  | 		NewRowID:     newrowid, | ||||||
|  | 	} | ||||||
|  | 	callback := hval.val.(func(SQLitePreUpdateData)) | ||||||
|  | 	callback(data) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Use handles to avoid passing Go pointers to C. | ||||||
| type handleVal struct { | type handleVal struct { | ||||||
| 	db  *SQLiteConn | 	db  *SQLiteConn | ||||||
| 	val interface{} | 	val interface{} | ||||||
| @@ -103,7 +117,7 @@ func newHandle(db *SQLiteConn, v interface{}) uintptr { | |||||||
| 	return i | 	return i | ||||||
| } | } | ||||||
|  |  | ||||||
| func lookupHandle(handle uintptr) interface{} { | func lookupHandleVal(handle uintptr) handleVal { | ||||||
| 	handleLock.Lock() | 	handleLock.Lock() | ||||||
| 	defer handleLock.Unlock() | 	defer handleLock.Unlock() | ||||||
| 	r, ok := handleVals[handle] | 	r, ok := handleVals[handle] | ||||||
| @@ -114,7 +128,11 @@ func lookupHandle(handle uintptr) interface{} { | |||||||
| 			panic("invalid handle") | 			panic("invalid handle") | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	return r.val | 	return r | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func lookupHandle(handle uintptr) interface{} { | ||||||
|  | 	return lookupHandleVal(handle).val | ||||||
| } | } | ||||||
|  |  | ||||||
| func deleteHandles(db *SQLiteConn) { | func deleteHandles(db *SQLiteConn) { | ||||||
|   | |||||||
							
								
								
									
										299
									
								
								vendor/github.com/mattn/go-sqlite3/convert.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										299
									
								
								vendor/github.com/mattn/go-sqlite3/convert.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,299 @@ | |||||||
|  | // Extracted from Go database/sql source code | ||||||
|  |  | ||||||
|  | // Copyright 2011 The Go Authors. All rights reserved. | ||||||
|  | // Use of this source code is governed by a BSD-style | ||||||
|  | // license that can be found in the LICENSE file. | ||||||
|  |  | ||||||
|  | // Type conversions for Scan. | ||||||
|  |  | ||||||
|  | package sqlite3 | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"database/sql" | ||||||
|  | 	"database/sql/driver" | ||||||
|  | 	"errors" | ||||||
|  | 	"fmt" | ||||||
|  | 	"reflect" | ||||||
|  | 	"strconv" | ||||||
|  | 	"time" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | var errNilPtr = errors.New("destination pointer is nil") // embedded in descriptive error | ||||||
|  |  | ||||||
|  | // convertAssign copies to dest the value in src, converting it if possible. | ||||||
|  | // An error is returned if the copy would result in loss of information. | ||||||
|  | // dest should be a pointer type. | ||||||
|  | func convertAssign(dest, src interface{}) error { | ||||||
|  | 	// Common cases, without reflect. | ||||||
|  | 	switch s := src.(type) { | ||||||
|  | 	case string: | ||||||
|  | 		switch d := dest.(type) { | ||||||
|  | 		case *string: | ||||||
|  | 			if d == nil { | ||||||
|  | 				return errNilPtr | ||||||
|  | 			} | ||||||
|  | 			*d = s | ||||||
|  | 			return nil | ||||||
|  | 		case *[]byte: | ||||||
|  | 			if d == nil { | ||||||
|  | 				return errNilPtr | ||||||
|  | 			} | ||||||
|  | 			*d = []byte(s) | ||||||
|  | 			return nil | ||||||
|  | 		case *sql.RawBytes: | ||||||
|  | 			if d == nil { | ||||||
|  | 				return errNilPtr | ||||||
|  | 			} | ||||||
|  | 			*d = append((*d)[:0], s...) | ||||||
|  | 			return nil | ||||||
|  | 		} | ||||||
|  | 	case []byte: | ||||||
|  | 		switch d := dest.(type) { | ||||||
|  | 		case *string: | ||||||
|  | 			if d == nil { | ||||||
|  | 				return errNilPtr | ||||||
|  | 			} | ||||||
|  | 			*d = string(s) | ||||||
|  | 			return nil | ||||||
|  | 		case *interface{}: | ||||||
|  | 			if d == nil { | ||||||
|  | 				return errNilPtr | ||||||
|  | 			} | ||||||
|  | 			*d = cloneBytes(s) | ||||||
|  | 			return nil | ||||||
|  | 		case *[]byte: | ||||||
|  | 			if d == nil { | ||||||
|  | 				return errNilPtr | ||||||
|  | 			} | ||||||
|  | 			*d = cloneBytes(s) | ||||||
|  | 			return nil | ||||||
|  | 		case *sql.RawBytes: | ||||||
|  | 			if d == nil { | ||||||
|  | 				return errNilPtr | ||||||
|  | 			} | ||||||
|  | 			*d = s | ||||||
|  | 			return nil | ||||||
|  | 		} | ||||||
|  | 	case time.Time: | ||||||
|  | 		switch d := dest.(type) { | ||||||
|  | 		case *time.Time: | ||||||
|  | 			*d = s | ||||||
|  | 			return nil | ||||||
|  | 		case *string: | ||||||
|  | 			*d = s.Format(time.RFC3339Nano) | ||||||
|  | 			return nil | ||||||
|  | 		case *[]byte: | ||||||
|  | 			if d == nil { | ||||||
|  | 				return errNilPtr | ||||||
|  | 			} | ||||||
|  | 			*d = []byte(s.Format(time.RFC3339Nano)) | ||||||
|  | 			return nil | ||||||
|  | 		case *sql.RawBytes: | ||||||
|  | 			if d == nil { | ||||||
|  | 				return errNilPtr | ||||||
|  | 			} | ||||||
|  | 			*d = s.AppendFormat((*d)[:0], time.RFC3339Nano) | ||||||
|  | 			return nil | ||||||
|  | 		} | ||||||
|  | 	case nil: | ||||||
|  | 		switch d := dest.(type) { | ||||||
|  | 		case *interface{}: | ||||||
|  | 			if d == nil { | ||||||
|  | 				return errNilPtr | ||||||
|  | 			} | ||||||
|  | 			*d = nil | ||||||
|  | 			return nil | ||||||
|  | 		case *[]byte: | ||||||
|  | 			if d == nil { | ||||||
|  | 				return errNilPtr | ||||||
|  | 			} | ||||||
|  | 			*d = nil | ||||||
|  | 			return nil | ||||||
|  | 		case *sql.RawBytes: | ||||||
|  | 			if d == nil { | ||||||
|  | 				return errNilPtr | ||||||
|  | 			} | ||||||
|  | 			*d = nil | ||||||
|  | 			return nil | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	var sv reflect.Value | ||||||
|  |  | ||||||
|  | 	switch d := dest.(type) { | ||||||
|  | 	case *string: | ||||||
|  | 		sv = reflect.ValueOf(src) | ||||||
|  | 		switch sv.Kind() { | ||||||
|  | 		case reflect.Bool, | ||||||
|  | 			reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, | ||||||
|  | 			reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, | ||||||
|  | 			reflect.Float32, reflect.Float64: | ||||||
|  | 			*d = asString(src) | ||||||
|  | 			return nil | ||||||
|  | 		} | ||||||
|  | 	case *[]byte: | ||||||
|  | 		sv = reflect.ValueOf(src) | ||||||
|  | 		if b, ok := asBytes(nil, sv); ok { | ||||||
|  | 			*d = b | ||||||
|  | 			return nil | ||||||
|  | 		} | ||||||
|  | 	case *sql.RawBytes: | ||||||
|  | 		sv = reflect.ValueOf(src) | ||||||
|  | 		if b, ok := asBytes([]byte(*d)[:0], sv); ok { | ||||||
|  | 			*d = sql.RawBytes(b) | ||||||
|  | 			return nil | ||||||
|  | 		} | ||||||
|  | 	case *bool: | ||||||
|  | 		bv, err := driver.Bool.ConvertValue(src) | ||||||
|  | 		if err == nil { | ||||||
|  | 			*d = bv.(bool) | ||||||
|  | 		} | ||||||
|  | 		return err | ||||||
|  | 	case *interface{}: | ||||||
|  | 		*d = src | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if scanner, ok := dest.(sql.Scanner); ok { | ||||||
|  | 		return scanner.Scan(src) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	dpv := reflect.ValueOf(dest) | ||||||
|  | 	if dpv.Kind() != reflect.Ptr { | ||||||
|  | 		return errors.New("destination not a pointer") | ||||||
|  | 	} | ||||||
|  | 	if dpv.IsNil() { | ||||||
|  | 		return errNilPtr | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if !sv.IsValid() { | ||||||
|  | 		sv = reflect.ValueOf(src) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	dv := reflect.Indirect(dpv) | ||||||
|  | 	if sv.IsValid() && sv.Type().AssignableTo(dv.Type()) { | ||||||
|  | 		switch b := src.(type) { | ||||||
|  | 		case []byte: | ||||||
|  | 			dv.Set(reflect.ValueOf(cloneBytes(b))) | ||||||
|  | 		default: | ||||||
|  | 			dv.Set(sv) | ||||||
|  | 		} | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if dv.Kind() == sv.Kind() && sv.Type().ConvertibleTo(dv.Type()) { | ||||||
|  | 		dv.Set(sv.Convert(dv.Type())) | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// The following conversions use a string value as an intermediate representation | ||||||
|  | 	// to convert between various numeric types. | ||||||
|  | 	// | ||||||
|  | 	// This also allows scanning into user defined types such as "type Int int64". | ||||||
|  | 	// For symmetry, also check for string destination types. | ||||||
|  | 	switch dv.Kind() { | ||||||
|  | 	case reflect.Ptr: | ||||||
|  | 		if src == nil { | ||||||
|  | 			dv.Set(reflect.Zero(dv.Type())) | ||||||
|  | 			return nil | ||||||
|  | 		} | ||||||
|  | 		dv.Set(reflect.New(dv.Type().Elem())) | ||||||
|  | 		return convertAssign(dv.Interface(), src) | ||||||
|  | 	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: | ||||||
|  | 		s := asString(src) | ||||||
|  | 		i64, err := strconv.ParseInt(s, 10, dv.Type().Bits()) | ||||||
|  | 		if err != nil { | ||||||
|  | 			err = strconvErr(err) | ||||||
|  | 			return fmt.Errorf("converting driver.Value type %T (%q) to a %s: %v", src, s, dv.Kind(), err) | ||||||
|  | 		} | ||||||
|  | 		dv.SetInt(i64) | ||||||
|  | 		return nil | ||||||
|  | 	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: | ||||||
|  | 		s := asString(src) | ||||||
|  | 		u64, err := strconv.ParseUint(s, 10, dv.Type().Bits()) | ||||||
|  | 		if err != nil { | ||||||
|  | 			err = strconvErr(err) | ||||||
|  | 			return fmt.Errorf("converting driver.Value type %T (%q) to a %s: %v", src, s, dv.Kind(), err) | ||||||
|  | 		} | ||||||
|  | 		dv.SetUint(u64) | ||||||
|  | 		return nil | ||||||
|  | 	case reflect.Float32, reflect.Float64: | ||||||
|  | 		s := asString(src) | ||||||
|  | 		f64, err := strconv.ParseFloat(s, dv.Type().Bits()) | ||||||
|  | 		if err != nil { | ||||||
|  | 			err = strconvErr(err) | ||||||
|  | 			return fmt.Errorf("converting driver.Value type %T (%q) to a %s: %v", src, s, dv.Kind(), err) | ||||||
|  | 		} | ||||||
|  | 		dv.SetFloat(f64) | ||||||
|  | 		return nil | ||||||
|  | 	case reflect.String: | ||||||
|  | 		switch v := src.(type) { | ||||||
|  | 		case string: | ||||||
|  | 			dv.SetString(v) | ||||||
|  | 			return nil | ||||||
|  | 		case []byte: | ||||||
|  | 			dv.SetString(string(v)) | ||||||
|  | 			return nil | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return fmt.Errorf("unsupported Scan, storing driver.Value type %T into type %T", src, dest) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func strconvErr(err error) error { | ||||||
|  | 	if ne, ok := err.(*strconv.NumError); ok { | ||||||
|  | 		return ne.Err | ||||||
|  | 	} | ||||||
|  | 	return err | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func cloneBytes(b []byte) []byte { | ||||||
|  | 	if b == nil { | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  | 	c := make([]byte, len(b)) | ||||||
|  | 	copy(c, b) | ||||||
|  | 	return c | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func asString(src interface{}) string { | ||||||
|  | 	switch v := src.(type) { | ||||||
|  | 	case string: | ||||||
|  | 		return v | ||||||
|  | 	case []byte: | ||||||
|  | 		return string(v) | ||||||
|  | 	} | ||||||
|  | 	rv := reflect.ValueOf(src) | ||||||
|  | 	switch rv.Kind() { | ||||||
|  | 	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: | ||||||
|  | 		return strconv.FormatInt(rv.Int(), 10) | ||||||
|  | 	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: | ||||||
|  | 		return strconv.FormatUint(rv.Uint(), 10) | ||||||
|  | 	case reflect.Float64: | ||||||
|  | 		return strconv.FormatFloat(rv.Float(), 'g', -1, 64) | ||||||
|  | 	case reflect.Float32: | ||||||
|  | 		return strconv.FormatFloat(rv.Float(), 'g', -1, 32) | ||||||
|  | 	case reflect.Bool: | ||||||
|  | 		return strconv.FormatBool(rv.Bool()) | ||||||
|  | 	} | ||||||
|  | 	return fmt.Sprintf("%v", src) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func asBytes(buf []byte, rv reflect.Value) (b []byte, ok bool) { | ||||||
|  | 	switch rv.Kind() { | ||||||
|  | 	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: | ||||||
|  | 		return strconv.AppendInt(buf, rv.Int(), 10), true | ||||||
|  | 	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: | ||||||
|  | 		return strconv.AppendUint(buf, rv.Uint(), 10), true | ||||||
|  | 	case reflect.Float32: | ||||||
|  | 		return strconv.AppendFloat(buf, rv.Float(), 'g', -1, 32), true | ||||||
|  | 	case reflect.Float64: | ||||||
|  | 		return strconv.AppendFloat(buf, rv.Float(), 'g', -1, 64), true | ||||||
|  | 	case reflect.Bool: | ||||||
|  | 		return strconv.AppendBool(buf, rv.Bool()), true | ||||||
|  | 	case reflect.String: | ||||||
|  | 		s := rv.String() | ||||||
|  | 		return append(buf, s...), true | ||||||
|  | 	} | ||||||
|  | 	return | ||||||
|  | } | ||||||
							
								
								
									
										21
									
								
								vendor/github.com/mattn/go-sqlite3/error.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										21
									
								
								vendor/github.com/mattn/go-sqlite3/error.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,11 +1,19 @@ | |||||||
| // Copyright (C) 2014 Yasuhiro Matsumoto <mattn.jp@gmail.com>. | // Copyright (C) 2019 Yasuhiro Matsumoto <mattn.jp@gmail.com>. | ||||||
| // | // | ||||||
| // Use of this source code is governed by an MIT-style | // Use of this source code is governed by an MIT-style | ||||||
| // license that can be found in the LICENSE file. | // license that can be found in the LICENSE file. | ||||||
|  |  | ||||||
| package sqlite3 | package sqlite3 | ||||||
|  |  | ||||||
|  | /* | ||||||
|  | #ifndef USE_LIBSQLITE3 | ||||||
|  | #include <sqlite3-binding.h> | ||||||
|  | #else | ||||||
|  | #include <sqlite3.h> | ||||||
|  | #endif | ||||||
|  | */ | ||||||
| import "C" | import "C" | ||||||
|  | import "syscall" | ||||||
|  |  | ||||||
| // ErrNo inherit errno. | // ErrNo inherit errno. | ||||||
| type ErrNo int | type ErrNo int | ||||||
| @@ -20,6 +28,7 @@ type ErrNoExtended int | |||||||
| type Error struct { | type Error struct { | ||||||
| 	Code         ErrNo         /* The error code returned by SQLite */ | 	Code         ErrNo         /* The error code returned by SQLite */ | ||||||
| 	ExtendedCode ErrNoExtended /* The extended error code returned by SQLite */ | 	ExtendedCode ErrNoExtended /* The extended error code returned by SQLite */ | ||||||
|  | 	SystemErrno  syscall.Errno /* The system errno returned by the OS through SQLite, if applicable */ | ||||||
| 	err          string        /* The error string returned by sqlite3_errmsg(), | 	err          string        /* The error string returned by sqlite3_errmsg(), | ||||||
| 	this usually contains more specific details. */ | 	this usually contains more specific details. */ | ||||||
| } | } | ||||||
| @@ -72,10 +81,16 @@ func (err ErrNoExtended) Error() string { | |||||||
| } | } | ||||||
|  |  | ||||||
| func (err Error) Error() string { | func (err Error) Error() string { | ||||||
|  | 	var str string | ||||||
| 	if err.err != "" { | 	if err.err != "" { | ||||||
| 		return err.err | 		str = err.err | ||||||
|  | 	} else { | ||||||
|  | 		str = C.GoString(C.sqlite3_errstr(C.int(err.Code))) | ||||||
| 	} | 	} | ||||||
| 	return errorString(err) | 	if err.SystemErrno != 0 { | ||||||
|  | 		str += ": " + err.SystemErrno.Error() | ||||||
|  | 	} | ||||||
|  | 	return str | ||||||
| } | } | ||||||
|  |  | ||||||
| // result codes from http://www.sqlite.org/c3ref/c_abort_rollback.html | // result codes from http://www.sqlite.org/c3ref/c_abort_rollback.html | ||||||
|   | |||||||
							
								
								
									
										8863
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3-binding.c
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										8863
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3-binding.c
									
									
									
										generated
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										81
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3-binding.h
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										81
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3-binding.h
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -124,9 +124,9 @@ extern "C" { | |||||||
| ** [sqlite3_libversion_number()], [sqlite3_sourceid()], | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], | ||||||
| ** [sqlite_version()] and [sqlite_source_id()]. | ** [sqlite_version()] and [sqlite_source_id()]. | ||||||
| */ | */ | ||||||
| #define SQLITE_VERSION        "3.29.0" | #define SQLITE_VERSION        "3.30.1" | ||||||
| #define SQLITE_VERSION_NUMBER 3029000 | #define SQLITE_VERSION_NUMBER 3030001 | ||||||
| #define SQLITE_SOURCE_ID      "2019-07-10 17:32:03 fc82b73eaac8b36950e527f12c4b5dc1e147e6f4ad2217ae43ad82882a88bfa6" | #define SQLITE_SOURCE_ID      "2019-10-10 20:19:45 18db032d058f1436ce3dea84081f4ee5a0f2259ad97301d43c426bc7f3df1b0b" | ||||||
|  |  | ||||||
| /* | /* | ||||||
| ** CAPI3REF: Run-Time Library Version Numbers | ** CAPI3REF: Run-Time Library Version Numbers | ||||||
| @@ -2094,6 +2094,17 @@ struct sqlite3_mem_methods { | |||||||
| ** following this call.  The second parameter may be a NULL pointer, in | ** following this call.  The second parameter may be a NULL pointer, in | ||||||
| ** which case the trigger setting is not reported back. </dd> | ** which case the trigger setting is not reported back. </dd> | ||||||
| ** | ** | ||||||
|  | ** [[SQLITE_DBCONFIG_ENABLE_VIEW]] | ||||||
|  | ** <dt>SQLITE_DBCONFIG_ENABLE_VIEW</dt> | ||||||
|  | ** <dd> ^This option is used to enable or disable [CREATE VIEW | views]. | ||||||
|  | ** There should be two additional arguments. | ||||||
|  | ** The first argument is an integer which is 0 to disable views, | ||||||
|  | ** positive to enable views or negative to leave the setting unchanged. | ||||||
|  | ** The second parameter is a pointer to an integer into which | ||||||
|  | ** is written 0 or 1 to indicate whether views are disabled or enabled | ||||||
|  | ** following this call.  The second parameter may be a NULL pointer, in | ||||||
|  | ** which case the view setting is not reported back. </dd> | ||||||
|  | ** | ||||||
| ** [[SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER]] | ** [[SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER]] | ||||||
| ** <dt>SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER</dt> | ** <dt>SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER</dt> | ||||||
| ** <dd> ^This option is used to enable or disable the | ** <dd> ^This option is used to enable or disable the | ||||||
| @@ -2266,7 +2277,8 @@ struct sqlite3_mem_methods { | |||||||
| #define SQLITE_DBCONFIG_LEGACY_ALTER_TABLE    1012 /* int int* */ | #define SQLITE_DBCONFIG_LEGACY_ALTER_TABLE    1012 /* int int* */ | ||||||
| #define SQLITE_DBCONFIG_DQS_DML               1013 /* int int* */ | #define SQLITE_DBCONFIG_DQS_DML               1013 /* int int* */ | ||||||
| #define SQLITE_DBCONFIG_DQS_DDL               1014 /* int int* */ | #define SQLITE_DBCONFIG_DQS_DDL               1014 /* int int* */ | ||||||
| #define SQLITE_DBCONFIG_MAX                   1014 /* Largest DBCONFIG */ | #define SQLITE_DBCONFIG_ENABLE_VIEW           1015 /* int int* */ | ||||||
|  | #define SQLITE_DBCONFIG_MAX                   1015 /* Largest DBCONFIG */ | ||||||
|  |  | ||||||
| /* | /* | ||||||
| ** CAPI3REF: Enable Or Disable Extended Result Codes | ** CAPI3REF: Enable Or Disable Extended Result Codes | ||||||
| @@ -3815,7 +3827,7 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal); | |||||||
| ** ^The specific value of WHERE-clause [parameter] might influence the  | ** ^The specific value of WHERE-clause [parameter] might influence the  | ||||||
| ** choice of query plan if the parameter is the left-hand side of a [LIKE] | ** choice of query plan if the parameter is the left-hand side of a [LIKE] | ||||||
| ** or [GLOB] operator or if the parameter is compared to an indexed column | ** or [GLOB] operator or if the parameter is compared to an indexed column | ||||||
| ** and the [SQLITE_ENABLE_STAT3] compile-time option is enabled. | ** and the [SQLITE_ENABLE_STAT4] compile-time option is enabled. | ||||||
| ** </li> | ** </li> | ||||||
| ** </ol> | ** </ol> | ||||||
| ** | ** | ||||||
| @@ -4850,6 +4862,12 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt); | |||||||
| ** perform additional optimizations on deterministic functions, so use | ** perform additional optimizations on deterministic functions, so use | ||||||
| ** of the [SQLITE_DETERMINISTIC] flag is recommended where possible. | ** of the [SQLITE_DETERMINISTIC] flag is recommended where possible. | ||||||
| ** | ** | ||||||
|  | ** ^The fourth parameter may also optionally include the [SQLITE_DIRECTONLY] | ||||||
|  | ** flag, which if present prevents the function from being invoked from | ||||||
|  | ** within VIEWs or TRIGGERs.  For security reasons, the [SQLITE_DIRECTONLY] | ||||||
|  | ** flag is recommended for any application-defined SQL function that has | ||||||
|  | ** side-effects. | ||||||
|  | ** | ||||||
| ** ^(The fifth parameter is an arbitrary pointer.  The implementation of the | ** ^(The fifth parameter is an arbitrary pointer.  The implementation of the | ||||||
| ** function can gain access to this pointer using [sqlite3_user_data()].)^ | ** function can gain access to this pointer using [sqlite3_user_data()].)^ | ||||||
| ** | ** | ||||||
| @@ -4966,8 +4984,30 @@ SQLITE_API int sqlite3_create_window_function( | |||||||
| ** [SQLITE_UTF8 | preferred text encoding] as the fourth argument | ** [SQLITE_UTF8 | preferred text encoding] as the fourth argument | ||||||
| ** to [sqlite3_create_function()], [sqlite3_create_function16()], or | ** to [sqlite3_create_function()], [sqlite3_create_function16()], or | ||||||
| ** [sqlite3_create_function_v2()]. | ** [sqlite3_create_function_v2()]. | ||||||
|  | ** | ||||||
|  | ** The SQLITE_DETERMINISTIC flag means that the new function will always | ||||||
|  | ** maps the same inputs into the same output.  The abs() function is | ||||||
|  | ** deterministic, for example, but randomblob() is not. | ||||||
|  | ** | ||||||
|  | ** The SQLITE_DIRECTONLY flag means that the function may only be invoked | ||||||
|  | ** from top-level SQL, and cannot be used in VIEWs or TRIGGERs.  This is | ||||||
|  | ** a security feature which is recommended for all  | ||||||
|  | ** [application-defined SQL functions] that have side-effects.  This flag  | ||||||
|  | ** prevents an attacker from adding triggers and views to a schema then  | ||||||
|  | ** tricking a high-privilege application into causing unintended side-effects | ||||||
|  | ** while performing ordinary queries. | ||||||
|  | ** | ||||||
|  | ** The SQLITE_SUBTYPE flag indicates to SQLite that a function may call | ||||||
|  | ** [sqlite3_value_subtype()] to inspect the sub-types of its arguments. | ||||||
|  | ** Specifying this flag makes no difference for scalar or aggregate user | ||||||
|  | ** functions. However, if it is not specified for a user-defined window | ||||||
|  | ** function, then any sub-types belonging to arguments passed to the window | ||||||
|  | ** function may be discarded before the window function is called (i.e. | ||||||
|  | ** sqlite3_value_subtype() will always return 0). | ||||||
| */ | */ | ||||||
| #define SQLITE_DETERMINISTIC    0x800 | #define SQLITE_DETERMINISTIC    0x000000800 | ||||||
|  | #define SQLITE_DIRECTONLY       0x000080000 | ||||||
|  | #define SQLITE_SUBTYPE          0x000100000 | ||||||
|  |  | ||||||
| /* | /* | ||||||
| ** CAPI3REF: Deprecated Functions | ** CAPI3REF: Deprecated Functions | ||||||
| @@ -6613,6 +6653,12 @@ struct sqlite3_index_info { | |||||||
| ** ^The sqlite3_create_module() | ** ^The sqlite3_create_module() | ||||||
| ** interface is equivalent to sqlite3_create_module_v2() with a NULL | ** interface is equivalent to sqlite3_create_module_v2() with a NULL | ||||||
| ** destructor. | ** destructor. | ||||||
|  | ** | ||||||
|  | ** ^If the third parameter (the pointer to the sqlite3_module object) is | ||||||
|  | ** NULL then no new module is create and any existing modules with the | ||||||
|  | ** same name are dropped. | ||||||
|  | ** | ||||||
|  | ** See also: [sqlite3_drop_modules()] | ||||||
| */ | */ | ||||||
| SQLITE_API int sqlite3_create_module( | SQLITE_API int sqlite3_create_module( | ||||||
|   sqlite3 *db,               /* SQLite connection to register module with */ |   sqlite3 *db,               /* SQLite connection to register module with */ | ||||||
| @@ -6628,6 +6674,23 @@ SQLITE_API int sqlite3_create_module_v2( | |||||||
|   void(*xDestroy)(void*)     /* Module destructor function */ |   void(*xDestroy)(void*)     /* Module destructor function */ | ||||||
| ); | ); | ||||||
|  |  | ||||||
|  | /* | ||||||
|  | ** CAPI3REF: Remove Unnecessary Virtual Table Implementations | ||||||
|  | ** METHOD: sqlite3 | ||||||
|  | ** | ||||||
|  | ** ^The sqlite3_drop_modules(D,L) interface removes all virtual | ||||||
|  | ** table modules from database connection D except those named on list L. | ||||||
|  | ** The L parameter must be either NULL or a pointer to an array of pointers | ||||||
|  | ** to strings where the array is terminated by a single NULL pointer. | ||||||
|  | ** ^If the L parameter is NULL, then all virtual table modules are removed. | ||||||
|  | ** | ||||||
|  | ** See also: [sqlite3_create_module()] | ||||||
|  | */ | ||||||
|  | SQLITE_API int sqlite3_drop_modules( | ||||||
|  |   sqlite3 *db,                /* Remove modules from this connection */ | ||||||
|  |   const char **azKeep         /* Except, do not remove the ones named here */ | ||||||
|  | ); | ||||||
|  |  | ||||||
| /* | /* | ||||||
| ** CAPI3REF: Virtual Table Instance Object | ** CAPI3REF: Virtual Table Instance Object | ||||||
| ** KEYWORDS: sqlite3_vtab | ** KEYWORDS: sqlite3_vtab | ||||||
| @@ -7336,7 +7399,7 @@ SQLITE_API int sqlite3_test_control(int op, ...); | |||||||
| #define SQLITE_TESTCTRL_FIRST                    5 | #define SQLITE_TESTCTRL_FIRST                    5 | ||||||
| #define SQLITE_TESTCTRL_PRNG_SAVE                5 | #define SQLITE_TESTCTRL_PRNG_SAVE                5 | ||||||
| #define SQLITE_TESTCTRL_PRNG_RESTORE             6 | #define SQLITE_TESTCTRL_PRNG_RESTORE             6 | ||||||
| #define SQLITE_TESTCTRL_PRNG_RESET               7 | #define SQLITE_TESTCTRL_PRNG_RESET               7  /* NOT USED */ | ||||||
| #define SQLITE_TESTCTRL_BITVEC_TEST              8 | #define SQLITE_TESTCTRL_BITVEC_TEST              8 | ||||||
| #define SQLITE_TESTCTRL_FAULT_INSTALL            9 | #define SQLITE_TESTCTRL_FAULT_INSTALL            9 | ||||||
| #define SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS     10 | #define SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS     10 | ||||||
| @@ -7359,7 +7422,9 @@ SQLITE_API int sqlite3_test_control(int op, ...); | |||||||
| #define SQLITE_TESTCTRL_IMPOSTER                25 | #define SQLITE_TESTCTRL_IMPOSTER                25 | ||||||
| #define SQLITE_TESTCTRL_PARSER_COVERAGE         26 | #define SQLITE_TESTCTRL_PARSER_COVERAGE         26 | ||||||
| #define SQLITE_TESTCTRL_RESULT_INTREAL          27 | #define SQLITE_TESTCTRL_RESULT_INTREAL          27 | ||||||
| #define SQLITE_TESTCTRL_LAST                    27  /* Largest TESTCTRL */ | #define SQLITE_TESTCTRL_PRNG_SEED               28 | ||||||
|  | #define SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS     29 | ||||||
|  | #define SQLITE_TESTCTRL_LAST                    29  /* Largest TESTCTRL */ | ||||||
|  |  | ||||||
| /* | /* | ||||||
| ** CAPI3REF: SQL Keyword Checking | ** CAPI3REF: SQL Keyword Checking | ||||||
|   | |||||||
							
								
								
									
										148
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										148
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| // Copyright (C) 2014 Yasuhiro Matsumoto <mattn.jp@gmail.com>. | // Copyright (C) 2019 Yasuhiro Matsumoto <mattn.jp@gmail.com>. | ||||||
| // Copyright (C) 2018 G.J.R. Timmer <gjr.timmer@gmail.com>. | // Copyright (C) 2018 G.J.R. Timmer <gjr.timmer@gmail.com>. | ||||||
| // | // | ||||||
| // Use of this source code is governed by an MIT-style | // Use of this source code is governed by an MIT-style | ||||||
| @@ -183,6 +183,12 @@ static int _sqlite3_limit(sqlite3* db, int limitId, int newLimit) { | |||||||
|   return sqlite3_limit(db, limitId, newLimit); |   return sqlite3_limit(db, limitId, newLimit); | ||||||
| #endif | #endif | ||||||
| } | } | ||||||
|  |  | ||||||
|  | #if SQLITE_VERSION_NUMBER < 3012000 | ||||||
|  | static int sqlite3_system_errno(sqlite3 *db) { | ||||||
|  |   return 0; | ||||||
|  | } | ||||||
|  | #endif | ||||||
| */ | */ | ||||||
| import "C" | import "C" | ||||||
| import ( | import ( | ||||||
| @@ -198,6 +204,7 @@ import ( | |||||||
| 	"strconv" | 	"strconv" | ||||||
| 	"strings" | 	"strings" | ||||||
| 	"sync" | 	"sync" | ||||||
|  | 	"syscall" | ||||||
| 	"time" | 	"time" | ||||||
| 	"unsafe" | 	"unsafe" | ||||||
| ) | ) | ||||||
| @@ -328,7 +335,7 @@ type SQLiteRows struct { | |||||||
| 	decltype []string | 	decltype []string | ||||||
| 	cls      bool | 	cls      bool | ||||||
| 	closed   bool | 	closed   bool | ||||||
| 	done     chan struct{} | 	ctx      context.Context // no better alternative to pass context into Next() method | ||||||
| } | } | ||||||
|  |  | ||||||
| type functionInfo struct { | type functionInfo struct { | ||||||
| @@ -749,15 +756,28 @@ func (c *SQLiteConn) lastError() error { | |||||||
| 	return lastError(c.db) | 	return lastError(c.db) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // Note: may be called with db == nil | ||||||
| func lastError(db *C.sqlite3) error { | func lastError(db *C.sqlite3) error { | ||||||
| 	rv := C.sqlite3_errcode(db) | 	rv := C.sqlite3_errcode(db) // returns SQLITE_NOMEM if db == nil | ||||||
| 	if rv == C.SQLITE_OK { | 	if rv == C.SQLITE_OK { | ||||||
| 		return nil | 		return nil | ||||||
| 	} | 	} | ||||||
|  | 	extrv := C.sqlite3_extended_errcode(db)    // returns SQLITE_NOMEM if db == nil | ||||||
|  | 	errStr := C.GoString(C.sqlite3_errmsg(db)) // returns "out of memory" if db == nil | ||||||
|  |  | ||||||
|  | 	// https://www.sqlite.org/c3ref/system_errno.html | ||||||
|  | 	// sqlite3_system_errno is only meaningful if the error code was SQLITE_CANTOPEN, | ||||||
|  | 	// or it was SQLITE_IOERR and the extended code was not SQLITE_IOERR_NOMEM | ||||||
|  | 	var systemErrno syscall.Errno | ||||||
|  | 	if rv == C.SQLITE_CANTOPEN || (rv == C.SQLITE_IOERR && extrv != C.SQLITE_IOERR_NOMEM) { | ||||||
|  | 		systemErrno = syscall.Errno(C.sqlite3_system_errno(db)) | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	return Error{ | 	return Error{ | ||||||
| 		Code:         ErrNo(rv), | 		Code:         ErrNo(rv), | ||||||
| 		ExtendedCode: ErrNoExtended(C.sqlite3_extended_errcode(db)), | 		ExtendedCode: ErrNoExtended(extrv), | ||||||
| 		err:          C.GoString(C.sqlite3_errmsg(db)), | 		SystemErrno:  systemErrno, | ||||||
|  | 		err:          errStr, | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -869,10 +889,6 @@ func (c *SQLiteConn) begin(ctx context.Context) (driver.Tx, error) { | |||||||
| 	return &SQLiteTx{c}, nil | 	return &SQLiteTx{c}, nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func errorString(err Error) string { |  | ||||||
| 	return C.GoString(C.sqlite3_errstr(C.int(err.Code))) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Open database and return a new connection. | // Open database and return a new connection. | ||||||
| // | // | ||||||
| // A pragma can take either zero or one argument. | // A pragma can take either zero or one argument. | ||||||
| @@ -897,7 +913,7 @@ func errorString(err Error) string { | |||||||
| //      - rwc | //      - rwc | ||||||
| //      - memory | //      - memory | ||||||
| // | // | ||||||
| //   shared | //   cache | ||||||
| //     SQLite Shared-Cache Mode | //     SQLite Shared-Cache Mode | ||||||
| //     https://www.sqlite.org/sharedcache.html | //     https://www.sqlite.org/sharedcache.html | ||||||
| //     Values: | //     Values: | ||||||
| @@ -1000,7 +1016,7 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) { | |||||||
| 	deferForeignKeys := -1 | 	deferForeignKeys := -1 | ||||||
| 	foreignKeys := -1 | 	foreignKeys := -1 | ||||||
| 	ignoreCheckConstraints := -1 | 	ignoreCheckConstraints := -1 | ||||||
| 	journalMode := "DELETE" | 	var journalMode string | ||||||
| 	lockingMode := "NORMAL" | 	lockingMode := "NORMAL" | ||||||
| 	queryOnly := -1 | 	queryOnly := -1 | ||||||
| 	recursiveTriggers := -1 | 	recursiveTriggers := -1 | ||||||
| @@ -1232,7 +1248,7 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) { | |||||||
| 		if _, ok := params["_locking"]; ok { | 		if _, ok := params["_locking"]; ok { | ||||||
| 			pkey = "_locking" | 			pkey = "_locking" | ||||||
| 		} | 		} | ||||||
| 		if val := params.Get("_locking"); val != "" { | 		if val := params.Get(pkey); val != "" { | ||||||
| 			switch strings.ToUpper(val) { | 			switch strings.ToUpper(val) { | ||||||
| 			case "NORMAL", "EXCLUSIVE": | 			case "NORMAL", "EXCLUSIVE": | ||||||
| 				lockingMode = strings.ToUpper(val) | 				lockingMode = strings.ToUpper(val) | ||||||
| @@ -1342,10 +1358,13 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) { | |||||||
| 		mutex|C.SQLITE_OPEN_READWRITE|C.SQLITE_OPEN_CREATE, | 		mutex|C.SQLITE_OPEN_READWRITE|C.SQLITE_OPEN_CREATE, | ||||||
| 		nil) | 		nil) | ||||||
| 	if rv != 0 { | 	if rv != 0 { | ||||||
|  | 		// Save off the error _before_ closing the database. | ||||||
|  | 		// This is safe even if db is nil. | ||||||
|  | 		err := lastError(db) | ||||||
| 		if db != nil { | 		if db != nil { | ||||||
| 			C.sqlite3_close_v2(db) | 			C.sqlite3_close_v2(db) | ||||||
| 		} | 		} | ||||||
| 		return nil, Error{Code: ErrNo(rv)} | 		return nil, err | ||||||
| 	} | 	} | ||||||
| 	if db == nil { | 	if db == nil { | ||||||
| 		return nil, errors.New("sqlite succeeded without returning a database") | 		return nil, errors.New("sqlite succeeded without returning a database") | ||||||
| @@ -1522,10 +1541,10 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) { | |||||||
| 		// Before going any further, we need to check that the user | 		// Before going any further, we need to check that the user | ||||||
| 		// has provided an username and password within the DSN. | 		// has provided an username and password within the DSN. | ||||||
| 		// We are not allowed to continue. | 		// We are not allowed to continue. | ||||||
| 		if len(authUser) < 0 { | 		if len(authUser) == 0 { | ||||||
| 			return nil, fmt.Errorf("Missing '_auth_user' while user authentication was requested with '_auth'") | 			return nil, fmt.Errorf("Missing '_auth_user' while user authentication was requested with '_auth'") | ||||||
| 		} | 		} | ||||||
| 		if len(authPass) < 0 { | 		if len(authPass) == 0 { | ||||||
| 			return nil, fmt.Errorf("Missing '_auth_pass' while user authentication was requested with '_auth'") | 			return nil, fmt.Errorf("Missing '_auth_pass' while user authentication was requested with '_auth'") | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| @@ -1571,11 +1590,12 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// Journal Mode | 	// Journal Mode | ||||||
| 	// Because default Journal Mode is DELETE this PRAGMA can always be executed. | 	if journalMode != "" { | ||||||
| 		if err := exec(fmt.Sprintf("PRAGMA journal_mode = %s;", journalMode)); err != nil { | 		if err := exec(fmt.Sprintf("PRAGMA journal_mode = %s;", journalMode)); err != nil { | ||||||
| 			C.sqlite3_close_v2(db) | 			C.sqlite3_close_v2(db) | ||||||
| 			return nil, err | 			return nil, err | ||||||
| 		} | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	// Locking Mode | 	// Locking Mode | ||||||
| 	// Because the default is NORMAL and this is not changed in this package | 	// Because the default is NORMAL and this is not changed in this package | ||||||
| @@ -1846,28 +1866,13 @@ func (s *SQLiteStmt) query(ctx context.Context, args []namedValue) (driver.Rows, | |||||||
| 		decltype: nil, | 		decltype: nil, | ||||||
| 		cls:      s.cls, | 		cls:      s.cls, | ||||||
| 		closed:   false, | 		closed:   false, | ||||||
| 		done:     make(chan struct{}), | 		ctx:      ctx, | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if ctxdone := ctx.Done(); ctxdone != nil { |  | ||||||
| 		go func(db *C.sqlite3) { |  | ||||||
| 			select { |  | ||||||
| 			case <-ctxdone: |  | ||||||
| 				select { |  | ||||||
| 				case <-rows.done: |  | ||||||
| 				default: |  | ||||||
| 					C.sqlite3_interrupt(db) |  | ||||||
| 					rows.Close() |  | ||||||
| 				} |  | ||||||
| 			case <-rows.done: |  | ||||||
| 			} |  | ||||||
| 		}(s.c.db) |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return rows, nil | 	return rows, nil | ||||||
| } | } | ||||||
|  |  | ||||||
| // LastInsertId teturn last inserted ID. | // LastInsertId return last inserted ID. | ||||||
| func (r *SQLiteResult) LastInsertId() (int64, error) { | func (r *SQLiteResult) LastInsertId() (int64, error) { | ||||||
| 	return r.id, nil | 	return r.id, nil | ||||||
| } | } | ||||||
| @@ -1889,29 +1894,43 @@ func (s *SQLiteStmt) Exec(args []driver.Value) (driver.Result, error) { | |||||||
| 	return s.exec(context.Background(), list) | 	return s.exec(context.Background(), list) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // exec executes a query that doesn't return rows. Attempts to honor context timeout. | ||||||
| func (s *SQLiteStmt) exec(ctx context.Context, args []namedValue) (driver.Result, error) { | func (s *SQLiteStmt) exec(ctx context.Context, args []namedValue) (driver.Result, error) { | ||||||
|  | 	if ctx.Done() == nil { | ||||||
|  | 		return s.execSync(args) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	type result struct { | ||||||
|  | 		r   driver.Result | ||||||
|  | 		err error | ||||||
|  | 	} | ||||||
|  | 	resultCh := make(chan result) | ||||||
|  | 	go func() { | ||||||
|  | 		r, err := s.execSync(args) | ||||||
|  | 		resultCh <- result{r, err} | ||||||
|  | 	}() | ||||||
|  | 	select { | ||||||
|  | 	case rv := <-resultCh: | ||||||
|  | 		return rv.r, rv.err | ||||||
|  | 	case <-ctx.Done(): | ||||||
|  | 		select { | ||||||
|  | 		case <-resultCh: // no need to interrupt | ||||||
|  | 		default: | ||||||
|  | 			// this is still racy and can be no-op if executed between sqlite3_* calls in execSync. | ||||||
|  | 			C.sqlite3_interrupt(s.c.db) | ||||||
|  | 			<-resultCh // ensure goroutine completed | ||||||
|  | 		} | ||||||
|  | 		return nil, ctx.Err() | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (s *SQLiteStmt) execSync(args []namedValue) (driver.Result, error) { | ||||||
| 	if err := s.bind(args); err != nil { | 	if err := s.bind(args); err != nil { | ||||||
| 		C.sqlite3_reset(s.s) | 		C.sqlite3_reset(s.s) | ||||||
| 		C.sqlite3_clear_bindings(s.s) | 		C.sqlite3_clear_bindings(s.s) | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if ctxdone := ctx.Done(); ctxdone != nil { |  | ||||||
| 		done := make(chan struct{}) |  | ||||||
| 		defer close(done) |  | ||||||
| 		go func(db *C.sqlite3) { |  | ||||||
| 			select { |  | ||||||
| 			case <-done: |  | ||||||
| 			case <-ctxdone: |  | ||||||
| 				select { |  | ||||||
| 				case <-done: |  | ||||||
| 				default: |  | ||||||
| 					C.sqlite3_interrupt(db) |  | ||||||
| 				} |  | ||||||
| 			} |  | ||||||
| 		}(s.c.db) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	var rowid, changes C.longlong | 	var rowid, changes C.longlong | ||||||
| 	rv := C._sqlite3_step_row_internal(s.s, &rowid, &changes) | 	rv := C._sqlite3_step_row_internal(s.s, &rowid, &changes) | ||||||
| 	if rv != C.SQLITE_ROW && rv != C.SQLITE_OK && rv != C.SQLITE_DONE { | 	if rv != C.SQLITE_ROW && rv != C.SQLITE_OK && rv != C.SQLITE_DONE { | ||||||
| @@ -1932,9 +1951,6 @@ func (rc *SQLiteRows) Close() error { | |||||||
| 		return nil | 		return nil | ||||||
| 	} | 	} | ||||||
| 	rc.closed = true | 	rc.closed = true | ||||||
| 	if rc.done != nil { |  | ||||||
| 		close(rc.done) |  | ||||||
| 	} |  | ||||||
| 	if rc.cls { | 	if rc.cls { | ||||||
| 		rc.s.mu.Unlock() | 		rc.s.mu.Unlock() | ||||||
| 		return rc.s.Close() | 		return rc.s.Close() | ||||||
| @@ -1978,13 +1994,39 @@ func (rc *SQLiteRows) DeclTypes() []string { | |||||||
| 	return rc.declTypes() | 	return rc.declTypes() | ||||||
| } | } | ||||||
|  |  | ||||||
| // Next move cursor to next. | // Next move cursor to next. Attempts to honor context timeout from QueryContext call. | ||||||
| func (rc *SQLiteRows) Next(dest []driver.Value) error { | func (rc *SQLiteRows) Next(dest []driver.Value) error { | ||||||
| 	rc.s.mu.Lock() | 	rc.s.mu.Lock() | ||||||
| 	defer rc.s.mu.Unlock() | 	defer rc.s.mu.Unlock() | ||||||
|  |  | ||||||
| 	if rc.s.closed { | 	if rc.s.closed { | ||||||
| 		return io.EOF | 		return io.EOF | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	if rc.ctx.Done() == nil { | ||||||
|  | 		return rc.nextSyncLocked(dest) | ||||||
|  | 	} | ||||||
|  | 	resultCh := make(chan error) | ||||||
|  | 	go func() { | ||||||
|  | 		resultCh <- rc.nextSyncLocked(dest) | ||||||
|  | 	}() | ||||||
|  | 	select { | ||||||
|  | 	case err := <-resultCh: | ||||||
|  | 		return err | ||||||
|  | 	case <-rc.ctx.Done(): | ||||||
|  | 		select { | ||||||
|  | 		case <-resultCh: // no need to interrupt | ||||||
|  | 		default: | ||||||
|  | 			// this is still racy and can be no-op if executed between sqlite3_* calls in nextSyncLocked. | ||||||
|  | 			C.sqlite3_interrupt(rc.s.c.db) | ||||||
|  | 			<-resultCh // ensure goroutine completed | ||||||
|  | 		} | ||||||
|  | 		return rc.ctx.Err() | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // nextSyncLocked moves cursor to next; must be called with locked mutex. | ||||||
|  | func (rc *SQLiteRows) nextSyncLocked(dest []driver.Value) error { | ||||||
| 	rv := C._sqlite3_step_internal(rc.s.s) | 	rv := C._sqlite3_step_internal(rc.s.s) | ||||||
| 	if rv == C.SQLITE_DONE { | 	if rv == C.SQLITE_DONE { | ||||||
| 		return io.EOF | 		return io.EOF | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3_context.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3_context.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| // Copyright (C) 2014 Yasuhiro Matsumoto <mattn.jp@gmail.com>. | // Copyright (C) 2019 Yasuhiro Matsumoto <mattn.jp@gmail.com>. | ||||||
| // | // | ||||||
| // Use of this source code is governed by an MIT-style | // Use of this source code is governed by an MIT-style | ||||||
| // license that can be found in the LICENSE file. | // license that can be found in the LICENSE file. | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3_go18.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3_go18.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| // Copyright (C) 2014 Yasuhiro Matsumoto <mattn.jp@gmail.com>. | // Copyright (C) 2019 Yasuhiro Matsumoto <mattn.jp@gmail.com>. | ||||||
| // | // | ||||||
| // Use of this source code is governed by an MIT-style | // Use of this source code is governed by an MIT-style | ||||||
| // license that can be found in the LICENSE file. | // license that can be found in the LICENSE file. | ||||||
|   | |||||||
							
								
								
									
										3
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3_libsqlite3.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3_libsqlite3.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| // Copyright (C) 2014 Yasuhiro Matsumoto <mattn.jp@gmail.com>. | // Copyright (C) 2019 Yasuhiro Matsumoto <mattn.jp@gmail.com>. | ||||||
| // | // | ||||||
| // Use of this source code is governed by an MIT-style | // Use of this source code is governed by an MIT-style | ||||||
| // license that can be found in the LICENSE file. | // license that can be found in the LICENSE file. | ||||||
| @@ -11,6 +11,7 @@ package sqlite3 | |||||||
| #cgo CFLAGS: -DUSE_LIBSQLITE3 | #cgo CFLAGS: -DUSE_LIBSQLITE3 | ||||||
| #cgo linux LDFLAGS: -lsqlite3 | #cgo linux LDFLAGS: -lsqlite3 | ||||||
| #cgo darwin LDFLAGS: -L/usr/local/opt/sqlite/lib -lsqlite3 | #cgo darwin LDFLAGS: -L/usr/local/opt/sqlite/lib -lsqlite3 | ||||||
|  | #cgo darwin CFLAGS: -I/usr/local/opt/sqlite/include | ||||||
| #cgo openbsd LDFLAGS: -lsqlite3 | #cgo openbsd LDFLAGS: -lsqlite3 | ||||||
| #cgo solaris LDFLAGS: -lsqlite3 | #cgo solaris LDFLAGS: -lsqlite3 | ||||||
| */ | */ | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3_load_extension.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3_load_extension.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| // Copyright (C) 2014 Yasuhiro Matsumoto <mattn.jp@gmail.com>. | // Copyright (C) 2019 Yasuhiro Matsumoto <mattn.jp@gmail.com>. | ||||||
| // | // | ||||||
| // Use of this source code is governed by an MIT-style | // Use of this source code is governed by an MIT-style | ||||||
| // license that can be found in the LICENSE file. | // license that can be found in the LICENSE file. | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3_load_extension_omit.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3_load_extension_omit.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| // Copyright (C) 2014 Yasuhiro Matsumoto <mattn.jp@gmail.com>. | // Copyright (C) 2019 Yasuhiro Matsumoto <mattn.jp@gmail.com>. | ||||||
| // | // | ||||||
| // Use of this source code is governed by an MIT-style | // Use of this source code is governed by an MIT-style | ||||||
| // license that can be found in the LICENSE file. | // license that can be found in the LICENSE file. | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3_opt_allow_uri_authority.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3_opt_allow_uri_authority.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| // Copyright (C) 2014 Yasuhiro Matsumoto <mattn.jp@gmail.com>. | // Copyright (C) 2019 Yasuhiro Matsumoto <mattn.jp@gmail.com>. | ||||||
| // Copyright (C) 2018 G.J.R. Timmer <gjr.timmer@gmail.com>. | // Copyright (C) 2018 G.J.R. Timmer <gjr.timmer@gmail.com>. | ||||||
| // | // | ||||||
| // Use of this source code is governed by an MIT-style | // Use of this source code is governed by an MIT-style | ||||||
|   | |||||||
							
								
								
									
										4
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3_opt_app_armor.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3_opt_app_armor.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,6 +1,6 @@ | |||||||
| // Copyright (C) 2014 Yasuhiro Matsumoto <mattn.jp@gmail.com>. | // Copyright (C) 2019 Yasuhiro Matsumoto <mattn.jp@gmail.com>. | ||||||
| // Copyright (C) 2018 G.J.R. Timmer <gjr.timmer@gmail.com>. | // Copyright (C) 2018 G.J.R. Timmer <gjr.timmer@gmail.com>. | ||||||
|  | // | ||||||
| // Use of this source code is governed by an MIT-style | // Use of this source code is governed by an MIT-style | ||||||
| // license that can be found in the LICENSE file. | // license that can be found in the LICENSE file. | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3_opt_foreign_keys.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3_opt_foreign_keys.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| // Copyright (C) 2014 Yasuhiro Matsumoto <mattn.jp@gmail.com>. | // Copyright (C) 2019 Yasuhiro Matsumoto <mattn.jp@gmail.com>. | ||||||
| // Copyright (C) 2018 G.J.R. Timmer <gjr.timmer@gmail.com>. | // Copyright (C) 2018 G.J.R. Timmer <gjr.timmer@gmail.com>. | ||||||
| // | // | ||||||
| // Use of this source code is governed by an MIT-style | // Use of this source code is governed by an MIT-style | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3_opt_fts5.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3_opt_fts5.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| // Copyright (C) 2014 Yasuhiro Matsumoto <mattn.jp@gmail.com>. | // Copyright (C) 2019 Yasuhiro Matsumoto <mattn.jp@gmail.com>. | ||||||
| // | // | ||||||
| // Use of this source code is governed by an MIT-style | // Use of this source code is governed by an MIT-style | ||||||
| // license that can be found in the LICENSE file. | // license that can be found in the LICENSE file. | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3_opt_icu.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3_opt_icu.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| // Copyright (C) 2014 Yasuhiro Matsumoto <mattn.jp@gmail.com>. | // Copyright (C) 2019 Yasuhiro Matsumoto <mattn.jp@gmail.com>. | ||||||
| // | // | ||||||
| // Use of this source code is governed by an MIT-style | // Use of this source code is governed by an MIT-style | ||||||
| // license that can be found in the LICENSE file. | // license that can be found in the LICENSE file. | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3_opt_introspect.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3_opt_introspect.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| // Copyright (C) 2014 Yasuhiro Matsumoto <mattn.jp@gmail.com>. | // Copyright (C) 2019 Yasuhiro Matsumoto <mattn.jp@gmail.com>. | ||||||
| // Copyright (C) 2018 G.J.R. Timmer <gjr.timmer@gmail.com>. | // Copyright (C) 2018 G.J.R. Timmer <gjr.timmer@gmail.com>. | ||||||
|  |  | ||||||
| // Use of this source code is governed by an MIT-style | // Use of this source code is governed by an MIT-style | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3_opt_json1.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3_opt_json1.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| // Copyright (C) 2014 Yasuhiro Matsumoto <mattn.jp@gmail.com>. | // Copyright (C) 2019 Yasuhiro Matsumoto <mattn.jp@gmail.com>. | ||||||
| // | // | ||||||
| // Use of this source code is governed by an MIT-style | // Use of this source code is governed by an MIT-style | ||||||
| // license that can be found in the LICENSE file. | // license that can be found in the LICENSE file. | ||||||
|   | |||||||
							
								
								
									
										20
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3_opt_preupdate.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3_opt_preupdate.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,20 @@ | |||||||
|  | // Copyright (C) 2019 G.J.R. Timmer <gjr.timmer@gmail.com>. | ||||||
|  | // Copyright (C) 2018 segment.com <friends@segment.com> | ||||||
|  | // | ||||||
|  | // Use of this source code is governed by an MIT-style | ||||||
|  | // license that can be found in the LICENSE file. | ||||||
|  |  | ||||||
|  | // +build cgo | ||||||
|  |  | ||||||
|  | package sqlite3 | ||||||
|  |  | ||||||
|  | // SQLitePreUpdateData represents all of the data available during a | ||||||
|  | // pre-update hook call. | ||||||
|  | type SQLitePreUpdateData struct { | ||||||
|  | 	Conn         *SQLiteConn | ||||||
|  | 	Op           int | ||||||
|  | 	DatabaseName string | ||||||
|  | 	TableName    string | ||||||
|  | 	OldRowID     int64 | ||||||
|  | 	NewRowID     int64 | ||||||
|  | } | ||||||
							
								
								
									
										112
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3_opt_preupdate_hook.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										112
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3_opt_preupdate_hook.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,112 @@ | |||||||
|  | // Copyright (C) 2019 G.J.R. Timmer <gjr.timmer@gmail.com>. | ||||||
|  | // Copyright (C) 2018 segment.com <friends@segment.com> | ||||||
|  | // | ||||||
|  | // Use of this source code is governed by an MIT-style | ||||||
|  | // license that can be found in the LICENSE file. | ||||||
|  |  | ||||||
|  | // +build sqlite_preupdate_hook | ||||||
|  |  | ||||||
|  | package sqlite3 | ||||||
|  |  | ||||||
|  | /* | ||||||
|  | #cgo CFLAGS: -DSQLITE_ENABLE_PREUPDATE_HOOK | ||||||
|  | #cgo LDFLAGS: -lm | ||||||
|  |  | ||||||
|  | #ifndef USE_LIBSQLITE3 | ||||||
|  | #include <sqlite3-binding.h> | ||||||
|  | #else | ||||||
|  | #include <sqlite3.h> | ||||||
|  | #endif | ||||||
|  | #include <stdlib.h> | ||||||
|  | #include <string.h> | ||||||
|  |  | ||||||
|  | void preUpdateHookTrampoline(void*, sqlite3 *, int, char *, char *, sqlite3_int64, sqlite3_int64); | ||||||
|  | */ | ||||||
|  | import "C" | ||||||
|  | import ( | ||||||
|  | 	"errors" | ||||||
|  | 	"unsafe" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // RegisterPreUpdateHook sets the pre-update hook for a connection. | ||||||
|  | // | ||||||
|  | // The callback is passed a SQLitePreUpdateData struct with the data for | ||||||
|  | // the update, as well as methods for fetching copies of impacted data. | ||||||
|  | // | ||||||
|  | // If there is an existing update hook for this connection, it will be | ||||||
|  | // removed. If callback is nil the existing hook (if any) will be removed | ||||||
|  | // without creating a new one. | ||||||
|  | func (c *SQLiteConn) RegisterPreUpdateHook(callback func(SQLitePreUpdateData)) { | ||||||
|  | 	if callback == nil { | ||||||
|  | 		C.sqlite3_preupdate_hook(c.db, nil, nil) | ||||||
|  | 	} else { | ||||||
|  | 		C.sqlite3_preupdate_hook(c.db, (*[0]byte)(unsafe.Pointer(C.preUpdateHookTrampoline)), unsafe.Pointer(newHandle(c, callback))) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Depth returns the source path of the write, see sqlite3_preupdate_depth() | ||||||
|  | func (d *SQLitePreUpdateData) Depth() int { | ||||||
|  | 	return int(C.sqlite3_preupdate_depth(d.Conn.db)) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Count returns the number of columns in the row | ||||||
|  | func (d *SQLitePreUpdateData) Count() int { | ||||||
|  | 	return int(C.sqlite3_preupdate_count(d.Conn.db)) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (d *SQLitePreUpdateData) row(dest []interface{}, new bool) error { | ||||||
|  | 	for i := 0; i < d.Count() && i < len(dest); i++ { | ||||||
|  | 		var val *C.sqlite3_value | ||||||
|  | 		var src interface{} | ||||||
|  |  | ||||||
|  | 		// Initially I tried making this just a function pointer argument, but | ||||||
|  | 		// it's absurdly complicated to pass C function pointers. | ||||||
|  | 		if new { | ||||||
|  | 			C.sqlite3_preupdate_new(d.Conn.db, C.int(i), &val) | ||||||
|  | 		} else { | ||||||
|  | 			C.sqlite3_preupdate_old(d.Conn.db, C.int(i), &val) | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		switch C.sqlite3_value_type(val) { | ||||||
|  | 		case C.SQLITE_INTEGER: | ||||||
|  | 			src = int64(C.sqlite3_value_int64(val)) | ||||||
|  | 		case C.SQLITE_FLOAT: | ||||||
|  | 			src = float64(C.sqlite3_value_double(val)) | ||||||
|  | 		case C.SQLITE_BLOB: | ||||||
|  | 			len := C.sqlite3_value_bytes(val) | ||||||
|  | 			blobptr := C.sqlite3_value_blob(val) | ||||||
|  | 			src = C.GoBytes(blobptr, len) | ||||||
|  | 		case C.SQLITE_TEXT: | ||||||
|  | 			len := C.sqlite3_value_bytes(val) | ||||||
|  | 			cstrptr := unsafe.Pointer(C.sqlite3_value_text(val)) | ||||||
|  | 			src = C.GoBytes(cstrptr, len) | ||||||
|  | 		case C.SQLITE_NULL: | ||||||
|  | 			src = nil | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		err := convertAssign(&dest[i], src) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return err | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Old populates dest with the row data to be replaced. This works similar to | ||||||
|  | // database/sql's Rows.Scan() | ||||||
|  | func (d *SQLitePreUpdateData) Old(dest ...interface{}) error { | ||||||
|  | 	if d.Op == SQLITE_INSERT { | ||||||
|  | 		return errors.New("There is no old row for INSERT operations") | ||||||
|  | 	} | ||||||
|  | 	return d.row(dest, false) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // New populates dest with the replacement row data. This works similar to | ||||||
|  | // database/sql's Rows.Scan() | ||||||
|  | func (d *SQLitePreUpdateData) New(dest ...interface{}) error { | ||||||
|  | 	if d.Op == SQLITE_DELETE { | ||||||
|  | 		return errors.New("There is no new row for DELETE operations") | ||||||
|  | 	} | ||||||
|  | 	return d.row(dest, true) | ||||||
|  | } | ||||||
							
								
								
									
										21
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3_opt_preupdate_omit.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3_opt_preupdate_omit.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | |||||||
|  | // Copyright (C) 2019 G.J.R. Timmer <gjr.timmer@gmail.com>. | ||||||
|  | // Copyright (C) 2018 segment.com <friends@segment.com> | ||||||
|  | // | ||||||
|  | // Use of this source code is governed by an MIT-style | ||||||
|  | // license that can be found in the LICENSE file. | ||||||
|  |  | ||||||
|  | // +build !sqlite_preupdate_hook,cgo | ||||||
|  |  | ||||||
|  | package sqlite3 | ||||||
|  |  | ||||||
|  | // RegisterPreUpdateHook sets the pre-update hook for a connection. | ||||||
|  | // | ||||||
|  | // The callback is passed a SQLitePreUpdateData struct with the data for | ||||||
|  | // the update, as well as methods for fetching copies of impacted data. | ||||||
|  | // | ||||||
|  | // If there is an existing update hook for this connection, it will be | ||||||
|  | // removed. If callback is nil the existing hook (if any) will be removed | ||||||
|  | // without creating a new one. | ||||||
|  | func (c *SQLiteConn) RegisterPreUpdateHook(callback func(SQLitePreUpdateData)) { | ||||||
|  | 	// NOOP | ||||||
|  | } | ||||||
							
								
								
									
										2
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3_opt_secure_delete.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3_opt_secure_delete.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| // Copyright (C) 2014 Yasuhiro Matsumoto <mattn.jp@gmail.com>. | // Copyright (C) 2019 Yasuhiro Matsumoto <mattn.jp@gmail.com>. | ||||||
| // Copyright (C) 2018 G.J.R. Timmer <gjr.timmer@gmail.com>. | // Copyright (C) 2018 G.J.R. Timmer <gjr.timmer@gmail.com>. | ||||||
| // | // | ||||||
| // Use of this source code is governed by an MIT-style | // Use of this source code is governed by an MIT-style | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3_opt_secure_delete_fast.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3_opt_secure_delete_fast.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| // Copyright (C) 2014 Yasuhiro Matsumoto <mattn.jp@gmail.com>. | // Copyright (C) 2019 Yasuhiro Matsumoto <mattn.jp@gmail.com>. | ||||||
| // Copyright (C) 2018 G.J.R. Timmer <gjr.timmer@gmail.com>. | // Copyright (C) 2018 G.J.R. Timmer <gjr.timmer@gmail.com>. | ||||||
| // | // | ||||||
| // Use of this source code is governed by an MIT-style | // Use of this source code is governed by an MIT-style | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3_opt_stat4.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3_opt_stat4.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| // Copyright (C) 2014 Yasuhiro Matsumoto <mattn.jp@gmail.com>. | // Copyright (C) 2019 Yasuhiro Matsumoto <mattn.jp@gmail.com>. | ||||||
| // Copyright (C) 2018 G.J.R. Timmer <gjr.timmer@gmail.com>. | // Copyright (C) 2018 G.J.R. Timmer <gjr.timmer@gmail.com>. | ||||||
| // | // | ||||||
| // Use of this source code is governed by an MIT-style | // Use of this source code is governed by an MIT-style | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3_opt_unlock_notify.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3_opt_unlock_notify.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| // Copyright (C) 2018 Yasuhiro Matsumoto <mattn.jp@gmail.com>. | // Copyright (C) 2019 Yasuhiro Matsumoto <mattn.jp@gmail.com>. | ||||||
| // | // | ||||||
| // Use of this source code is governed by an MIT-style | // Use of this source code is governed by an MIT-style | ||||||
| // license that can be found in the LICENSE file. | // license that can be found in the LICENSE file. | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3_opt_vacuum_full.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3_opt_vacuum_full.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| // Copyright (C) 2014 Yasuhiro Matsumoto <mattn.jp@gmail.com>. | // Copyright (C) 2019 Yasuhiro Matsumoto <mattn.jp@gmail.com>. | ||||||
| // Copyright (C) 2018 G.J.R. Timmer <gjr.timmer@gmail.com>. | // Copyright (C) 2018 G.J.R. Timmer <gjr.timmer@gmail.com>. | ||||||
| // | // | ||||||
| // Use of this source code is governed by an MIT-style | // Use of this source code is governed by an MIT-style | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3_opt_vacuum_incr.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3_opt_vacuum_incr.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| // Copyright (C) 2014 Yasuhiro Matsumoto <mattn.jp@gmail.com>. | // Copyright (C) 2019 Yasuhiro Matsumoto <mattn.jp@gmail.com>. | ||||||
| // Copyright (C) 2018 G.J.R. Timmer <gjr.timmer@gmail.com>. | // Copyright (C) 2018 G.J.R. Timmer <gjr.timmer@gmail.com>. | ||||||
| // | // | ||||||
| // Use of this source code is governed by an MIT-style | // Use of this source code is governed by an MIT-style | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3_opt_vtable.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3_opt_vtable.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| // Copyright (C) 2014 Yasuhiro Matsumoto <mattn.jp@gmail.com>. | // Copyright (C) 2019 Yasuhiro Matsumoto <mattn.jp@gmail.com>. | ||||||
| // | // | ||||||
| // Use of this source code is governed by an MIT-style | // Use of this source code is governed by an MIT-style | ||||||
| // license that can be found in the LICENSE file. | // license that can be found in the LICENSE file. | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3_other.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3_other.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| // Copyright (C) 2014 Yasuhiro Matsumoto <mattn.jp@gmail.com>. | // Copyright (C) 2019 Yasuhiro Matsumoto <mattn.jp@gmail.com>. | ||||||
| // | // | ||||||
| // Use of this source code is governed by an MIT-style | // Use of this source code is governed by an MIT-style | ||||||
| // license that can be found in the LICENSE file. | // license that can be found in the LICENSE file. | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3_solaris.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3_solaris.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| // Copyright (C) 2018 Yasuhiro Matsumoto <mattn.jp@gmail.com>. | // Copyright (C) 2019 Yasuhiro Matsumoto <mattn.jp@gmail.com>. | ||||||
| // | // | ||||||
| // Use of this source code is governed by an MIT-style | // Use of this source code is governed by an MIT-style | ||||||
| // license that can be found in the LICENSE file. | // license that can be found in the LICENSE file. | ||||||
|   | |||||||
							
								
								
									
										3
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3_trace.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3_trace.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| // Copyright (C) 2016 Yasuhiro Matsumoto <mattn.jp@gmail.com>. | // Copyright (C) 2019 Yasuhiro Matsumoto <mattn.jp@gmail.com>. | ||||||
| // | // | ||||||
| // Use of this source code is governed by an MIT-style | // Use of this source code is governed by an MIT-style | ||||||
| // license that can be found in the LICENSE file. | // license that can be found in the LICENSE file. | ||||||
| @@ -89,6 +89,7 @@ func fillExpandedSQL(info *TraceInfo, db *C.sqlite3, pStmt unsafe.Pointer) { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	expSQLiteCStr := C.sqlite3_expanded_sql((*C.sqlite3_stmt)(pStmt)) | 	expSQLiteCStr := C.sqlite3_expanded_sql((*C.sqlite3_stmt)(pStmt)) | ||||||
|  | 	defer C.sqlite3_free(unsafe.Pointer(expSQLiteCStr)) | ||||||
| 	if expSQLiteCStr == nil { | 	if expSQLiteCStr == nil { | ||||||
| 		fillDBError(&info.DBError, db) | 		fillDBError(&info.DBError, db) | ||||||
| 		return | 		return | ||||||
|   | |||||||
							
								
								
									
										5
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3_type.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										5
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3_type.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,3 +1,8 @@ | |||||||
|  | // Copyright (C) 2019 Yasuhiro Matsumoto <mattn.jp@gmail.com>. | ||||||
|  | // | ||||||
|  | // Use of this source code is governed by an MIT-style | ||||||
|  | // license that can be found in the LICENSE file. | ||||||
|  |  | ||||||
| package sqlite3 | package sqlite3 | ||||||
|  |  | ||||||
| /* | /* | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3_windows.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3_windows.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| // Copyright (C) 2014 Yasuhiro Matsumoto <mattn.jp@gmail.com>. | // Copyright (C) 2019 Yasuhiro Matsumoto <mattn.jp@gmail.com>. | ||||||
| // | // | ||||||
| // Use of this source code is governed by an MIT-style | // Use of this source code is governed by an MIT-style | ||||||
| // license that can be found in the LICENSE file. | // license that can be found in the LICENSE file. | ||||||
|   | |||||||
							
								
								
									
										4
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3ext.h
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								vendor/github.com/mattn/go-sqlite3/sqlite3ext.h
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -323,6 +323,8 @@ struct sqlite3_api_routines { | |||||||
|   /* Version 3.28.0 and later */ |   /* Version 3.28.0 and later */ | ||||||
|   int (*stmt_isexplain)(sqlite3_stmt*); |   int (*stmt_isexplain)(sqlite3_stmt*); | ||||||
|   int (*value_frombind)(sqlite3_value*); |   int (*value_frombind)(sqlite3_value*); | ||||||
|  |   /* Version 3.30.0 and later */ | ||||||
|  |   int (*drop_modules)(sqlite3*,const char**); | ||||||
| }; | }; | ||||||
|  |  | ||||||
| /* | /* | ||||||
| @@ -615,6 +617,8 @@ typedef int (*sqlite3_loadext_entry)( | |||||||
| /* Version 3.28.0 and later */ | /* Version 3.28.0 and later */ | ||||||
| #define sqlite3_stmt_isexplain         sqlite3_api->isexplain | #define sqlite3_stmt_isexplain         sqlite3_api->isexplain | ||||||
| #define sqlite3_value_frombind         sqlite3_api->frombind | #define sqlite3_value_frombind         sqlite3_api->frombind | ||||||
|  | /* Version 3.30.0 and later */ | ||||||
|  | #define sqlite3_drop_modules           sqlite3_api->drop_modules | ||||||
| #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */ | #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */ | ||||||
|  |  | ||||||
| #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) | #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) | ||||||
|   | |||||||
							
								
								
									
										5
									
								
								vendor/github.com/mattn/go-sqlite3/static_mock.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										5
									
								
								vendor/github.com/mattn/go-sqlite3/static_mock.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,3 +1,8 @@ | |||||||
|  | // Copyright (C) 2019 Yasuhiro Matsumoto <mattn.jp@gmail.com>. | ||||||
|  | // | ||||||
|  | // Use of this source code is governed by an MIT-style | ||||||
|  | // license that can be found in the LICENSE file. | ||||||
|  |  | ||||||
| // +build !cgo | // +build !cgo | ||||||
|  |  | ||||||
| package sqlite3 | package sqlite3 | ||||||
|   | |||||||
							
								
								
									
										7
									
								
								vendor/github.com/spf13/pflag/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										7
									
								
								vendor/github.com/spf13/pflag/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -3,8 +3,9 @@ sudo: false | |||||||
| language: go | language: go | ||||||
|  |  | ||||||
| go: | go: | ||||||
|   - 1.7.3 |   - 1.9.x | ||||||
|   - 1.8.1 |   - 1.10.x | ||||||
|  |   - 1.11.x | ||||||
|   - tip |   - tip | ||||||
|  |  | ||||||
| matrix: | matrix: | ||||||
| @@ -12,7 +13,7 @@ matrix: | |||||||
|     - go: tip |     - go: tip | ||||||
|  |  | ||||||
| install: | install: | ||||||
|   - go get github.com/golang/lint/golint |   - go get golang.org/x/lint/golint | ||||||
|   - export PATH=$GOPATH/bin:$PATH |   - export PATH=$GOPATH/bin:$PATH | ||||||
|   - go install ./... |   - go install ./... | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										4
									
								
								vendor/github.com/spf13/pflag/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								vendor/github.com/spf13/pflag/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -86,8 +86,8 @@ fmt.Println("ip has value ", *ip) | |||||||
| fmt.Println("flagvar has value ", flagvar) | fmt.Println("flagvar has value ", flagvar) | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
| There are helpers function to get values later if you have the FlagSet but | There are helper functions available to get the value stored in a Flag if you have a FlagSet but find | ||||||
| it was difficult to keep up with all of the flag pointers in your code. | it difficult to keep up with all of the pointers in your code. | ||||||
| If you have a pflag.FlagSet with a flag called 'flagname' of type int you | If you have a pflag.FlagSet with a flag called 'flagname' of type int you | ||||||
| can use GetInt() to get the int value. But notice that 'flagname' must exist | can use GetInt() to get the int value. But notice that 'flagname' must exist | ||||||
| and it must be an int. GetString("flagname") will fail. | and it must be an int. GetString("flagname") will fail. | ||||||
|   | |||||||
							
								
								
									
										38
									
								
								vendor/github.com/spf13/pflag/bool_slice.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										38
									
								
								vendor/github.com/spf13/pflag/bool_slice.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -71,6 +71,44 @@ func (s *boolSliceValue) String() string { | |||||||
| 	return "[" + out + "]" | 	return "[" + out + "]" | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func (s *boolSliceValue) fromString(val string) (bool, error) { | ||||||
|  | 	return strconv.ParseBool(val) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (s *boolSliceValue) toString(val bool) string { | ||||||
|  | 	return strconv.FormatBool(val) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (s *boolSliceValue) Append(val string) error { | ||||||
|  | 	i, err := s.fromString(val) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	*s.value = append(*s.value, i) | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (s *boolSliceValue) Replace(val []string) error { | ||||||
|  | 	out := make([]bool, len(val)) | ||||||
|  | 	for i, d := range val { | ||||||
|  | 		var err error | ||||||
|  | 		out[i], err = s.fromString(d) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return err | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	*s.value = out | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (s *boolSliceValue) GetSlice() []string { | ||||||
|  | 	out := make([]string, len(*s.value)) | ||||||
|  | 	for i, d := range *s.value { | ||||||
|  | 		out[i] = s.toString(d) | ||||||
|  | 	} | ||||||
|  | 	return out | ||||||
|  | } | ||||||
|  |  | ||||||
| func boolSliceConv(val string) (interface{}, error) { | func boolSliceConv(val string) (interface{}, error) { | ||||||
| 	val = strings.Trim(val, "[]") | 	val = strings.Trim(val, "[]") | ||||||
| 	// Empty string would cause a slice with one (empty) entry | 	// Empty string would cause a slice with one (empty) entry | ||||||
|   | |||||||
							
								
								
									
										4
									
								
								vendor/github.com/spf13/pflag/count.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								vendor/github.com/spf13/pflag/count.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -46,7 +46,7 @@ func (f *FlagSet) GetCount(name string) (int, error) { | |||||||
|  |  | ||||||
| // CountVar defines a count flag with specified name, default value, and usage string. | // CountVar defines a count flag with specified name, default value, and usage string. | ||||||
| // The argument p points to an int variable in which to store the value of the flag. | // The argument p points to an int variable in which to store the value of the flag. | ||||||
| // A count flag will add 1 to its value evey time it is found on the command line | // A count flag will add 1 to its value every time it is found on the command line | ||||||
| func (f *FlagSet) CountVar(p *int, name string, usage string) { | func (f *FlagSet) CountVar(p *int, name string, usage string) { | ||||||
| 	f.CountVarP(p, name, "", usage) | 	f.CountVarP(p, name, "", usage) | ||||||
| } | } | ||||||
| @@ -69,7 +69,7 @@ func CountVarP(p *int, name, shorthand string, usage string) { | |||||||
|  |  | ||||||
| // Count defines a count flag with specified name, default value, and usage string. | // Count defines a count flag with specified name, default value, and usage string. | ||||||
| // The return value is the address of an int variable that stores the value of the flag. | // The return value is the address of an int variable that stores the value of the flag. | ||||||
| // A count flag will add 1 to its value evey time it is found on the command line | // A count flag will add 1 to its value every time it is found on the command line | ||||||
| func (f *FlagSet) Count(name string, usage string) *int { | func (f *FlagSet) Count(name string, usage string) *int { | ||||||
| 	p := new(int) | 	p := new(int) | ||||||
| 	f.CountVarP(p, name, "", usage) | 	f.CountVarP(p, name, "", usage) | ||||||
|   | |||||||
							
								
								
									
										38
									
								
								vendor/github.com/spf13/pflag/duration_slice.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										38
									
								
								vendor/github.com/spf13/pflag/duration_slice.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -51,6 +51,44 @@ func (s *durationSliceValue) String() string { | |||||||
| 	return "[" + strings.Join(out, ",") + "]" | 	return "[" + strings.Join(out, ",") + "]" | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func (s *durationSliceValue) fromString(val string) (time.Duration, error) { | ||||||
|  | 	return time.ParseDuration(val) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (s *durationSliceValue) toString(val time.Duration) string { | ||||||
|  | 	return fmt.Sprintf("%s", val) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (s *durationSliceValue) Append(val string) error { | ||||||
|  | 	i, err := s.fromString(val) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	*s.value = append(*s.value, i) | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (s *durationSliceValue) Replace(val []string) error { | ||||||
|  | 	out := make([]time.Duration, len(val)) | ||||||
|  | 	for i, d := range val { | ||||||
|  | 		var err error | ||||||
|  | 		out[i], err = s.fromString(d) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return err | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	*s.value = out | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (s *durationSliceValue) GetSlice() []string { | ||||||
|  | 	out := make([]string, len(*s.value)) | ||||||
|  | 	for i, d := range *s.value { | ||||||
|  | 		out[i] = s.toString(d) | ||||||
|  | 	} | ||||||
|  | 	return out | ||||||
|  | } | ||||||
|  |  | ||||||
| func durationSliceConv(val string) (interface{}, error) { | func durationSliceConv(val string) (interface{}, error) { | ||||||
| 	val = strings.Trim(val, "[]") | 	val = strings.Trim(val, "[]") | ||||||
| 	// Empty string would cause a slice with one (empty) entry | 	// Empty string would cause a slice with one (empty) entry | ||||||
|   | |||||||
							
								
								
									
										16
									
								
								vendor/github.com/spf13/pflag/flag.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										16
									
								
								vendor/github.com/spf13/pflag/flag.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -57,9 +57,9 @@ that give one-letter shorthands for flags. You can use these by appending | |||||||
| 	var ip = flag.IntP("flagname", "f", 1234, "help message") | 	var ip = flag.IntP("flagname", "f", 1234, "help message") | ||||||
| 	var flagvar bool | 	var flagvar bool | ||||||
| 	func init() { | 	func init() { | ||||||
| 		flag.BoolVarP("boolname", "b", true, "help message") | 		flag.BoolVarP(&flagvar, "boolname", "b", true, "help message") | ||||||
| 	} | 	} | ||||||
| 	flag.VarP(&flagVar, "varname", "v", 1234, "help message") | 	flag.VarP(&flagval, "varname", "v", "help message") | ||||||
| Shorthand letters can be used with single dashes on the command line. | Shorthand letters can be used with single dashes on the command line. | ||||||
| Boolean shorthand flags can be combined with other shorthand flags. | Boolean shorthand flags can be combined with other shorthand flags. | ||||||
|  |  | ||||||
| @@ -190,6 +190,18 @@ type Value interface { | |||||||
| 	Type() string | 	Type() string | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // SliceValue is a secondary interface to all flags which hold a list | ||||||
|  | // of values.  This allows full control over the value of list flags, | ||||||
|  | // and avoids complicated marshalling and unmarshalling to csv. | ||||||
|  | type SliceValue interface { | ||||||
|  | 	// Append adds the specified value to the end of the flag value list. | ||||||
|  | 	Append(string) error | ||||||
|  | 	// Replace will fully overwrite any data currently in the flag value list. | ||||||
|  | 	Replace([]string) error | ||||||
|  | 	// GetSlice returns the flag value list as an array of strings. | ||||||
|  | 	GetSlice() []string | ||||||
|  | } | ||||||
|  |  | ||||||
| // sortFlags returns the flags as a slice in lexicographical sorted order. | // sortFlags returns the flags as a slice in lexicographical sorted order. | ||||||
| func sortFlags(flags map[NormalizedName]*Flag) []*Flag { | func sortFlags(flags map[NormalizedName]*Flag) []*Flag { | ||||||
| 	list := make(sort.StringSlice, len(flags)) | 	list := make(sort.StringSlice, len(flags)) | ||||||
|   | |||||||
							
								
								
									
										174
									
								
								vendor/github.com/spf13/pflag/float32_slice.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										174
									
								
								vendor/github.com/spf13/pflag/float32_slice.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,174 @@ | |||||||
|  | package pflag | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | 	"strconv" | ||||||
|  | 	"strings" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // -- float32Slice Value | ||||||
|  | type float32SliceValue struct { | ||||||
|  | 	value   *[]float32 | ||||||
|  | 	changed bool | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func newFloat32SliceValue(val []float32, p *[]float32) *float32SliceValue { | ||||||
|  | 	isv := new(float32SliceValue) | ||||||
|  | 	isv.value = p | ||||||
|  | 	*isv.value = val | ||||||
|  | 	return isv | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (s *float32SliceValue) Set(val string) error { | ||||||
|  | 	ss := strings.Split(val, ",") | ||||||
|  | 	out := make([]float32, len(ss)) | ||||||
|  | 	for i, d := range ss { | ||||||
|  | 		var err error | ||||||
|  | 		var temp64 float64 | ||||||
|  | 		temp64, err = strconv.ParseFloat(d, 32) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return err | ||||||
|  | 		} | ||||||
|  | 		out[i] = float32(temp64) | ||||||
|  |  | ||||||
|  | 	} | ||||||
|  | 	if !s.changed { | ||||||
|  | 		*s.value = out | ||||||
|  | 	} else { | ||||||
|  | 		*s.value = append(*s.value, out...) | ||||||
|  | 	} | ||||||
|  | 	s.changed = true | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (s *float32SliceValue) Type() string { | ||||||
|  | 	return "float32Slice" | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (s *float32SliceValue) String() string { | ||||||
|  | 	out := make([]string, len(*s.value)) | ||||||
|  | 	for i, d := range *s.value { | ||||||
|  | 		out[i] = fmt.Sprintf("%f", d) | ||||||
|  | 	} | ||||||
|  | 	return "[" + strings.Join(out, ",") + "]" | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (s *float32SliceValue) fromString(val string) (float32, error) { | ||||||
|  | 	t64, err := strconv.ParseFloat(val, 32) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return 0, err | ||||||
|  | 	} | ||||||
|  | 	return float32(t64), nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (s *float32SliceValue) toString(val float32) string { | ||||||
|  | 	return fmt.Sprintf("%f", val) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (s *float32SliceValue) Append(val string) error { | ||||||
|  | 	i, err := s.fromString(val) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	*s.value = append(*s.value, i) | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (s *float32SliceValue) Replace(val []string) error { | ||||||
|  | 	out := make([]float32, len(val)) | ||||||
|  | 	for i, d := range val { | ||||||
|  | 		var err error | ||||||
|  | 		out[i], err = s.fromString(d) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return err | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	*s.value = out | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (s *float32SliceValue) GetSlice() []string { | ||||||
|  | 	out := make([]string, len(*s.value)) | ||||||
|  | 	for i, d := range *s.value { | ||||||
|  | 		out[i] = s.toString(d) | ||||||
|  | 	} | ||||||
|  | 	return out | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func float32SliceConv(val string) (interface{}, error) { | ||||||
|  | 	val = strings.Trim(val, "[]") | ||||||
|  | 	// Empty string would cause a slice with one (empty) entry | ||||||
|  | 	if len(val) == 0 { | ||||||
|  | 		return []float32{}, nil | ||||||
|  | 	} | ||||||
|  | 	ss := strings.Split(val, ",") | ||||||
|  | 	out := make([]float32, len(ss)) | ||||||
|  | 	for i, d := range ss { | ||||||
|  | 		var err error | ||||||
|  | 		var temp64 float64 | ||||||
|  | 		temp64, err = strconv.ParseFloat(d, 32) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return nil, err | ||||||
|  | 		} | ||||||
|  | 		out[i] = float32(temp64) | ||||||
|  |  | ||||||
|  | 	} | ||||||
|  | 	return out, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GetFloat32Slice return the []float32 value of a flag with the given name | ||||||
|  | func (f *FlagSet) GetFloat32Slice(name string) ([]float32, error) { | ||||||
|  | 	val, err := f.getFlagType(name, "float32Slice", float32SliceConv) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return []float32{}, err | ||||||
|  | 	} | ||||||
|  | 	return val.([]float32), nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Float32SliceVar defines a float32Slice flag with specified name, default value, and usage string. | ||||||
|  | // The argument p points to a []float32 variable in which to store the value of the flag. | ||||||
|  | func (f *FlagSet) Float32SliceVar(p *[]float32, name string, value []float32, usage string) { | ||||||
|  | 	f.VarP(newFloat32SliceValue(value, p), name, "", usage) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Float32SliceVarP is like Float32SliceVar, but accepts a shorthand letter that can be used after a single dash. | ||||||
|  | func (f *FlagSet) Float32SliceVarP(p *[]float32, name, shorthand string, value []float32, usage string) { | ||||||
|  | 	f.VarP(newFloat32SliceValue(value, p), name, shorthand, usage) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Float32SliceVar defines a float32[] flag with specified name, default value, and usage string. | ||||||
|  | // The argument p points to a float32[] variable in which to store the value of the flag. | ||||||
|  | func Float32SliceVar(p *[]float32, name string, value []float32, usage string) { | ||||||
|  | 	CommandLine.VarP(newFloat32SliceValue(value, p), name, "", usage) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Float32SliceVarP is like Float32SliceVar, but accepts a shorthand letter that can be used after a single dash. | ||||||
|  | func Float32SliceVarP(p *[]float32, name, shorthand string, value []float32, usage string) { | ||||||
|  | 	CommandLine.VarP(newFloat32SliceValue(value, p), name, shorthand, usage) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Float32Slice defines a []float32 flag with specified name, default value, and usage string. | ||||||
|  | // The return value is the address of a []float32 variable that stores the value of the flag. | ||||||
|  | func (f *FlagSet) Float32Slice(name string, value []float32, usage string) *[]float32 { | ||||||
|  | 	p := []float32{} | ||||||
|  | 	f.Float32SliceVarP(&p, name, "", value, usage) | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Float32SliceP is like Float32Slice, but accepts a shorthand letter that can be used after a single dash. | ||||||
|  | func (f *FlagSet) Float32SliceP(name, shorthand string, value []float32, usage string) *[]float32 { | ||||||
|  | 	p := []float32{} | ||||||
|  | 	f.Float32SliceVarP(&p, name, shorthand, value, usage) | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Float32Slice defines a []float32 flag with specified name, default value, and usage string. | ||||||
|  | // The return value is the address of a []float32 variable that stores the value of the flag. | ||||||
|  | func Float32Slice(name string, value []float32, usage string) *[]float32 { | ||||||
|  | 	return CommandLine.Float32SliceP(name, "", value, usage) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Float32SliceP is like Float32Slice, but accepts a shorthand letter that can be used after a single dash. | ||||||
|  | func Float32SliceP(name, shorthand string, value []float32, usage string) *[]float32 { | ||||||
|  | 	return CommandLine.Float32SliceP(name, shorthand, value, usage) | ||||||
|  | } | ||||||
							
								
								
									
										166
									
								
								vendor/github.com/spf13/pflag/float64_slice.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										166
									
								
								vendor/github.com/spf13/pflag/float64_slice.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,166 @@ | |||||||
|  | package pflag | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | 	"strconv" | ||||||
|  | 	"strings" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // -- float64Slice Value | ||||||
|  | type float64SliceValue struct { | ||||||
|  | 	value   *[]float64 | ||||||
|  | 	changed bool | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func newFloat64SliceValue(val []float64, p *[]float64) *float64SliceValue { | ||||||
|  | 	isv := new(float64SliceValue) | ||||||
|  | 	isv.value = p | ||||||
|  | 	*isv.value = val | ||||||
|  | 	return isv | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (s *float64SliceValue) Set(val string) error { | ||||||
|  | 	ss := strings.Split(val, ",") | ||||||
|  | 	out := make([]float64, len(ss)) | ||||||
|  | 	for i, d := range ss { | ||||||
|  | 		var err error | ||||||
|  | 		out[i], err = strconv.ParseFloat(d, 64) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return err | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 	} | ||||||
|  | 	if !s.changed { | ||||||
|  | 		*s.value = out | ||||||
|  | 	} else { | ||||||
|  | 		*s.value = append(*s.value, out...) | ||||||
|  | 	} | ||||||
|  | 	s.changed = true | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (s *float64SliceValue) Type() string { | ||||||
|  | 	return "float64Slice" | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (s *float64SliceValue) String() string { | ||||||
|  | 	out := make([]string, len(*s.value)) | ||||||
|  | 	for i, d := range *s.value { | ||||||
|  | 		out[i] = fmt.Sprintf("%f", d) | ||||||
|  | 	} | ||||||
|  | 	return "[" + strings.Join(out, ",") + "]" | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (s *float64SliceValue) fromString(val string) (float64, error) { | ||||||
|  | 	return strconv.ParseFloat(val, 64) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (s *float64SliceValue) toString(val float64) string { | ||||||
|  | 	return fmt.Sprintf("%f", val) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (s *float64SliceValue) Append(val string) error { | ||||||
|  | 	i, err := s.fromString(val) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	*s.value = append(*s.value, i) | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (s *float64SliceValue) Replace(val []string) error { | ||||||
|  | 	out := make([]float64, len(val)) | ||||||
|  | 	for i, d := range val { | ||||||
|  | 		var err error | ||||||
|  | 		out[i], err = s.fromString(d) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return err | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	*s.value = out | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (s *float64SliceValue) GetSlice() []string { | ||||||
|  | 	out := make([]string, len(*s.value)) | ||||||
|  | 	for i, d := range *s.value { | ||||||
|  | 		out[i] = s.toString(d) | ||||||
|  | 	} | ||||||
|  | 	return out | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func float64SliceConv(val string) (interface{}, error) { | ||||||
|  | 	val = strings.Trim(val, "[]") | ||||||
|  | 	// Empty string would cause a slice with one (empty) entry | ||||||
|  | 	if len(val) == 0 { | ||||||
|  | 		return []float64{}, nil | ||||||
|  | 	} | ||||||
|  | 	ss := strings.Split(val, ",") | ||||||
|  | 	out := make([]float64, len(ss)) | ||||||
|  | 	for i, d := range ss { | ||||||
|  | 		var err error | ||||||
|  | 		out[i], err = strconv.ParseFloat(d, 64) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return nil, err | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 	} | ||||||
|  | 	return out, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GetFloat64Slice return the []float64 value of a flag with the given name | ||||||
|  | func (f *FlagSet) GetFloat64Slice(name string) ([]float64, error) { | ||||||
|  | 	val, err := f.getFlagType(name, "float64Slice", float64SliceConv) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return []float64{}, err | ||||||
|  | 	} | ||||||
|  | 	return val.([]float64), nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Float64SliceVar defines a float64Slice flag with specified name, default value, and usage string. | ||||||
|  | // The argument p points to a []float64 variable in which to store the value of the flag. | ||||||
|  | func (f *FlagSet) Float64SliceVar(p *[]float64, name string, value []float64, usage string) { | ||||||
|  | 	f.VarP(newFloat64SliceValue(value, p), name, "", usage) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Float64SliceVarP is like Float64SliceVar, but accepts a shorthand letter that can be used after a single dash. | ||||||
|  | func (f *FlagSet) Float64SliceVarP(p *[]float64, name, shorthand string, value []float64, usage string) { | ||||||
|  | 	f.VarP(newFloat64SliceValue(value, p), name, shorthand, usage) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Float64SliceVar defines a float64[] flag with specified name, default value, and usage string. | ||||||
|  | // The argument p points to a float64[] variable in which to store the value of the flag. | ||||||
|  | func Float64SliceVar(p *[]float64, name string, value []float64, usage string) { | ||||||
|  | 	CommandLine.VarP(newFloat64SliceValue(value, p), name, "", usage) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Float64SliceVarP is like Float64SliceVar, but accepts a shorthand letter that can be used after a single dash. | ||||||
|  | func Float64SliceVarP(p *[]float64, name, shorthand string, value []float64, usage string) { | ||||||
|  | 	CommandLine.VarP(newFloat64SliceValue(value, p), name, shorthand, usage) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Float64Slice defines a []float64 flag with specified name, default value, and usage string. | ||||||
|  | // The return value is the address of a []float64 variable that stores the value of the flag. | ||||||
|  | func (f *FlagSet) Float64Slice(name string, value []float64, usage string) *[]float64 { | ||||||
|  | 	p := []float64{} | ||||||
|  | 	f.Float64SliceVarP(&p, name, "", value, usage) | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Float64SliceP is like Float64Slice, but accepts a shorthand letter that can be used after a single dash. | ||||||
|  | func (f *FlagSet) Float64SliceP(name, shorthand string, value []float64, usage string) *[]float64 { | ||||||
|  | 	p := []float64{} | ||||||
|  | 	f.Float64SliceVarP(&p, name, shorthand, value, usage) | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Float64Slice defines a []float64 flag with specified name, default value, and usage string. | ||||||
|  | // The return value is the address of a []float64 variable that stores the value of the flag. | ||||||
|  | func Float64Slice(name string, value []float64, usage string) *[]float64 { | ||||||
|  | 	return CommandLine.Float64SliceP(name, "", value, usage) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Float64SliceP is like Float64Slice, but accepts a shorthand letter that can be used after a single dash. | ||||||
|  | func Float64SliceP(name, shorthand string, value []float64, usage string) *[]float64 { | ||||||
|  | 	return CommandLine.Float64SliceP(name, shorthand, value, usage) | ||||||
|  | } | ||||||
							
								
								
									
										3
									
								
								vendor/github.com/spf13/pflag/go.mod
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								vendor/github.com/spf13/pflag/go.mod
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | |||||||
|  | module github.com/spf13/pflag | ||||||
|  |  | ||||||
|  | go 1.12 | ||||||
							
								
								
									
										0
									
								
								vendor/github.com/spf13/pflag/go.sum
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								vendor/github.com/spf13/pflag/go.sum
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
								
								
									
										174
									
								
								vendor/github.com/spf13/pflag/int32_slice.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										174
									
								
								vendor/github.com/spf13/pflag/int32_slice.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,174 @@ | |||||||
|  | package pflag | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | 	"strconv" | ||||||
|  | 	"strings" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // -- int32Slice Value | ||||||
|  | type int32SliceValue struct { | ||||||
|  | 	value   *[]int32 | ||||||
|  | 	changed bool | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func newInt32SliceValue(val []int32, p *[]int32) *int32SliceValue { | ||||||
|  | 	isv := new(int32SliceValue) | ||||||
|  | 	isv.value = p | ||||||
|  | 	*isv.value = val | ||||||
|  | 	return isv | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (s *int32SliceValue) Set(val string) error { | ||||||
|  | 	ss := strings.Split(val, ",") | ||||||
|  | 	out := make([]int32, len(ss)) | ||||||
|  | 	for i, d := range ss { | ||||||
|  | 		var err error | ||||||
|  | 		var temp64 int64 | ||||||
|  | 		temp64, err = strconv.ParseInt(d, 0, 32) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return err | ||||||
|  | 		} | ||||||
|  | 		out[i] = int32(temp64) | ||||||
|  |  | ||||||
|  | 	} | ||||||
|  | 	if !s.changed { | ||||||
|  | 		*s.value = out | ||||||
|  | 	} else { | ||||||
|  | 		*s.value = append(*s.value, out...) | ||||||
|  | 	} | ||||||
|  | 	s.changed = true | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (s *int32SliceValue) Type() string { | ||||||
|  | 	return "int32Slice" | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (s *int32SliceValue) String() string { | ||||||
|  | 	out := make([]string, len(*s.value)) | ||||||
|  | 	for i, d := range *s.value { | ||||||
|  | 		out[i] = fmt.Sprintf("%d", d) | ||||||
|  | 	} | ||||||
|  | 	return "[" + strings.Join(out, ",") + "]" | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (s *int32SliceValue) fromString(val string) (int32, error) { | ||||||
|  | 	t64, err := strconv.ParseInt(val, 0, 32) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return 0, err | ||||||
|  | 	} | ||||||
|  | 	return int32(t64), nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (s *int32SliceValue) toString(val int32) string { | ||||||
|  | 	return fmt.Sprintf("%d", val) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (s *int32SliceValue) Append(val string) error { | ||||||
|  | 	i, err := s.fromString(val) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	*s.value = append(*s.value, i) | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (s *int32SliceValue) Replace(val []string) error { | ||||||
|  | 	out := make([]int32, len(val)) | ||||||
|  | 	for i, d := range val { | ||||||
|  | 		var err error | ||||||
|  | 		out[i], err = s.fromString(d) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return err | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	*s.value = out | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (s *int32SliceValue) GetSlice() []string { | ||||||
|  | 	out := make([]string, len(*s.value)) | ||||||
|  | 	for i, d := range *s.value { | ||||||
|  | 		out[i] = s.toString(d) | ||||||
|  | 	} | ||||||
|  | 	return out | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func int32SliceConv(val string) (interface{}, error) { | ||||||
|  | 	val = strings.Trim(val, "[]") | ||||||
|  | 	// Empty string would cause a slice with one (empty) entry | ||||||
|  | 	if len(val) == 0 { | ||||||
|  | 		return []int32{}, nil | ||||||
|  | 	} | ||||||
|  | 	ss := strings.Split(val, ",") | ||||||
|  | 	out := make([]int32, len(ss)) | ||||||
|  | 	for i, d := range ss { | ||||||
|  | 		var err error | ||||||
|  | 		var temp64 int64 | ||||||
|  | 		temp64, err = strconv.ParseInt(d, 0, 32) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return nil, err | ||||||
|  | 		} | ||||||
|  | 		out[i] = int32(temp64) | ||||||
|  |  | ||||||
|  | 	} | ||||||
|  | 	return out, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GetInt32Slice return the []int32 value of a flag with the given name | ||||||
|  | func (f *FlagSet) GetInt32Slice(name string) ([]int32, error) { | ||||||
|  | 	val, err := f.getFlagType(name, "int32Slice", int32SliceConv) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return []int32{}, err | ||||||
|  | 	} | ||||||
|  | 	return val.([]int32), nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Int32SliceVar defines a int32Slice flag with specified name, default value, and usage string. | ||||||
|  | // The argument p points to a []int32 variable in which to store the value of the flag. | ||||||
|  | func (f *FlagSet) Int32SliceVar(p *[]int32, name string, value []int32, usage string) { | ||||||
|  | 	f.VarP(newInt32SliceValue(value, p), name, "", usage) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Int32SliceVarP is like Int32SliceVar, but accepts a shorthand letter that can be used after a single dash. | ||||||
|  | func (f *FlagSet) Int32SliceVarP(p *[]int32, name, shorthand string, value []int32, usage string) { | ||||||
|  | 	f.VarP(newInt32SliceValue(value, p), name, shorthand, usage) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Int32SliceVar defines a int32[] flag with specified name, default value, and usage string. | ||||||
|  | // The argument p points to a int32[] variable in which to store the value of the flag. | ||||||
|  | func Int32SliceVar(p *[]int32, name string, value []int32, usage string) { | ||||||
|  | 	CommandLine.VarP(newInt32SliceValue(value, p), name, "", usage) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Int32SliceVarP is like Int32SliceVar, but accepts a shorthand letter that can be used after a single dash. | ||||||
|  | func Int32SliceVarP(p *[]int32, name, shorthand string, value []int32, usage string) { | ||||||
|  | 	CommandLine.VarP(newInt32SliceValue(value, p), name, shorthand, usage) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Int32Slice defines a []int32 flag with specified name, default value, and usage string. | ||||||
|  | // The return value is the address of a []int32 variable that stores the value of the flag. | ||||||
|  | func (f *FlagSet) Int32Slice(name string, value []int32, usage string) *[]int32 { | ||||||
|  | 	p := []int32{} | ||||||
|  | 	f.Int32SliceVarP(&p, name, "", value, usage) | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Int32SliceP is like Int32Slice, but accepts a shorthand letter that can be used after a single dash. | ||||||
|  | func (f *FlagSet) Int32SliceP(name, shorthand string, value []int32, usage string) *[]int32 { | ||||||
|  | 	p := []int32{} | ||||||
|  | 	f.Int32SliceVarP(&p, name, shorthand, value, usage) | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Int32Slice defines a []int32 flag with specified name, default value, and usage string. | ||||||
|  | // The return value is the address of a []int32 variable that stores the value of the flag. | ||||||
|  | func Int32Slice(name string, value []int32, usage string) *[]int32 { | ||||||
|  | 	return CommandLine.Int32SliceP(name, "", value, usage) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Int32SliceP is like Int32Slice, but accepts a shorthand letter that can be used after a single dash. | ||||||
|  | func Int32SliceP(name, shorthand string, value []int32, usage string) *[]int32 { | ||||||
|  | 	return CommandLine.Int32SliceP(name, shorthand, value, usage) | ||||||
|  | } | ||||||
							
								
								
									
										166
									
								
								vendor/github.com/spf13/pflag/int64_slice.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										166
									
								
								vendor/github.com/spf13/pflag/int64_slice.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,166 @@ | |||||||
|  | package pflag | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | 	"strconv" | ||||||
|  | 	"strings" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // -- int64Slice Value | ||||||
|  | type int64SliceValue struct { | ||||||
|  | 	value   *[]int64 | ||||||
|  | 	changed bool | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func newInt64SliceValue(val []int64, p *[]int64) *int64SliceValue { | ||||||
|  | 	isv := new(int64SliceValue) | ||||||
|  | 	isv.value = p | ||||||
|  | 	*isv.value = val | ||||||
|  | 	return isv | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (s *int64SliceValue) Set(val string) error { | ||||||
|  | 	ss := strings.Split(val, ",") | ||||||
|  | 	out := make([]int64, len(ss)) | ||||||
|  | 	for i, d := range ss { | ||||||
|  | 		var err error | ||||||
|  | 		out[i], err = strconv.ParseInt(d, 0, 64) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return err | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 	} | ||||||
|  | 	if !s.changed { | ||||||
|  | 		*s.value = out | ||||||
|  | 	} else { | ||||||
|  | 		*s.value = append(*s.value, out...) | ||||||
|  | 	} | ||||||
|  | 	s.changed = true | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (s *int64SliceValue) Type() string { | ||||||
|  | 	return "int64Slice" | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (s *int64SliceValue) String() string { | ||||||
|  | 	out := make([]string, len(*s.value)) | ||||||
|  | 	for i, d := range *s.value { | ||||||
|  | 		out[i] = fmt.Sprintf("%d", d) | ||||||
|  | 	} | ||||||
|  | 	return "[" + strings.Join(out, ",") + "]" | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (s *int64SliceValue) fromString(val string) (int64, error) { | ||||||
|  | 	return strconv.ParseInt(val, 0, 64) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (s *int64SliceValue) toString(val int64) string { | ||||||
|  | 	return fmt.Sprintf("%d", val) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (s *int64SliceValue) Append(val string) error { | ||||||
|  | 	i, err := s.fromString(val) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	*s.value = append(*s.value, i) | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (s *int64SliceValue) Replace(val []string) error { | ||||||
|  | 	out := make([]int64, len(val)) | ||||||
|  | 	for i, d := range val { | ||||||
|  | 		var err error | ||||||
|  | 		out[i], err = s.fromString(d) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return err | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	*s.value = out | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (s *int64SliceValue) GetSlice() []string { | ||||||
|  | 	out := make([]string, len(*s.value)) | ||||||
|  | 	for i, d := range *s.value { | ||||||
|  | 		out[i] = s.toString(d) | ||||||
|  | 	} | ||||||
|  | 	return out | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func int64SliceConv(val string) (interface{}, error) { | ||||||
|  | 	val = strings.Trim(val, "[]") | ||||||
|  | 	// Empty string would cause a slice with one (empty) entry | ||||||
|  | 	if len(val) == 0 { | ||||||
|  | 		return []int64{}, nil | ||||||
|  | 	} | ||||||
|  | 	ss := strings.Split(val, ",") | ||||||
|  | 	out := make([]int64, len(ss)) | ||||||
|  | 	for i, d := range ss { | ||||||
|  | 		var err error | ||||||
|  | 		out[i], err = strconv.ParseInt(d, 0, 64) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return nil, err | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 	} | ||||||
|  | 	return out, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GetInt64Slice return the []int64 value of a flag with the given name | ||||||
|  | func (f *FlagSet) GetInt64Slice(name string) ([]int64, error) { | ||||||
|  | 	val, err := f.getFlagType(name, "int64Slice", int64SliceConv) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return []int64{}, err | ||||||
|  | 	} | ||||||
|  | 	return val.([]int64), nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Int64SliceVar defines a int64Slice flag with specified name, default value, and usage string. | ||||||
|  | // The argument p points to a []int64 variable in which to store the value of the flag. | ||||||
|  | func (f *FlagSet) Int64SliceVar(p *[]int64, name string, value []int64, usage string) { | ||||||
|  | 	f.VarP(newInt64SliceValue(value, p), name, "", usage) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Int64SliceVarP is like Int64SliceVar, but accepts a shorthand letter that can be used after a single dash. | ||||||
|  | func (f *FlagSet) Int64SliceVarP(p *[]int64, name, shorthand string, value []int64, usage string) { | ||||||
|  | 	f.VarP(newInt64SliceValue(value, p), name, shorthand, usage) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Int64SliceVar defines a int64[] flag with specified name, default value, and usage string. | ||||||
|  | // The argument p points to a int64[] variable in which to store the value of the flag. | ||||||
|  | func Int64SliceVar(p *[]int64, name string, value []int64, usage string) { | ||||||
|  | 	CommandLine.VarP(newInt64SliceValue(value, p), name, "", usage) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Int64SliceVarP is like Int64SliceVar, but accepts a shorthand letter that can be used after a single dash. | ||||||
|  | func Int64SliceVarP(p *[]int64, name, shorthand string, value []int64, usage string) { | ||||||
|  | 	CommandLine.VarP(newInt64SliceValue(value, p), name, shorthand, usage) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Int64Slice defines a []int64 flag with specified name, default value, and usage string. | ||||||
|  | // The return value is the address of a []int64 variable that stores the value of the flag. | ||||||
|  | func (f *FlagSet) Int64Slice(name string, value []int64, usage string) *[]int64 { | ||||||
|  | 	p := []int64{} | ||||||
|  | 	f.Int64SliceVarP(&p, name, "", value, usage) | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Int64SliceP is like Int64Slice, but accepts a shorthand letter that can be used after a single dash. | ||||||
|  | func (f *FlagSet) Int64SliceP(name, shorthand string, value []int64, usage string) *[]int64 { | ||||||
|  | 	p := []int64{} | ||||||
|  | 	f.Int64SliceVarP(&p, name, shorthand, value, usage) | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Int64Slice defines a []int64 flag with specified name, default value, and usage string. | ||||||
|  | // The return value is the address of a []int64 variable that stores the value of the flag. | ||||||
|  | func Int64Slice(name string, value []int64, usage string) *[]int64 { | ||||||
|  | 	return CommandLine.Int64SliceP(name, "", value, usage) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Int64SliceP is like Int64Slice, but accepts a shorthand letter that can be used after a single dash. | ||||||
|  | func Int64SliceP(name, shorthand string, value []int64, usage string) *[]int64 { | ||||||
|  | 	return CommandLine.Int64SliceP(name, shorthand, value, usage) | ||||||
|  | } | ||||||
							
								
								
									
										30
									
								
								vendor/github.com/spf13/pflag/int_slice.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										30
									
								
								vendor/github.com/spf13/pflag/int_slice.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -51,6 +51,36 @@ func (s *intSliceValue) String() string { | |||||||
| 	return "[" + strings.Join(out, ",") + "]" | 	return "[" + strings.Join(out, ",") + "]" | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func (s *intSliceValue) Append(val string) error { | ||||||
|  | 	i, err := strconv.Atoi(val) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	*s.value = append(*s.value, i) | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (s *intSliceValue) Replace(val []string) error { | ||||||
|  | 	out := make([]int, len(val)) | ||||||
|  | 	for i, d := range val { | ||||||
|  | 		var err error | ||||||
|  | 		out[i], err = strconv.Atoi(d) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return err | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	*s.value = out | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (s *intSliceValue) GetSlice() []string { | ||||||
|  | 	out := make([]string, len(*s.value)) | ||||||
|  | 	for i, d := range *s.value { | ||||||
|  | 		out[i] = strconv.Itoa(d) | ||||||
|  | 	} | ||||||
|  | 	return out | ||||||
|  | } | ||||||
|  |  | ||||||
| func intSliceConv(val string) (interface{}, error) { | func intSliceConv(val string) (interface{}, error) { | ||||||
| 	val = strings.Trim(val, "[]") | 	val = strings.Trim(val, "[]") | ||||||
| 	// Empty string would cause a slice with one (empty) entry | 	// Empty string would cause a slice with one (empty) entry | ||||||
|   | |||||||
							
								
								
									
										40
									
								
								vendor/github.com/spf13/pflag/ip_slice.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										40
									
								
								vendor/github.com/spf13/pflag/ip_slice.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -72,9 +72,47 @@ func (s *ipSliceValue) String() string { | |||||||
| 	return "[" + out + "]" | 	return "[" + out + "]" | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func (s *ipSliceValue) fromString(val string) (net.IP, error) { | ||||||
|  | 	return net.ParseIP(strings.TrimSpace(val)), nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (s *ipSliceValue) toString(val net.IP) string { | ||||||
|  | 	return val.String() | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (s *ipSliceValue) Append(val string) error { | ||||||
|  | 	i, err := s.fromString(val) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	*s.value = append(*s.value, i) | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (s *ipSliceValue) Replace(val []string) error { | ||||||
|  | 	out := make([]net.IP, len(val)) | ||||||
|  | 	for i, d := range val { | ||||||
|  | 		var err error | ||||||
|  | 		out[i], err = s.fromString(d) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return err | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	*s.value = out | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (s *ipSliceValue) GetSlice() []string { | ||||||
|  | 	out := make([]string, len(*s.value)) | ||||||
|  | 	for i, d := range *s.value { | ||||||
|  | 		out[i] = s.toString(d) | ||||||
|  | 	} | ||||||
|  | 	return out | ||||||
|  | } | ||||||
|  |  | ||||||
| func ipSliceConv(val string) (interface{}, error) { | func ipSliceConv(val string) (interface{}, error) { | ||||||
| 	val = strings.Trim(val, "[]") | 	val = strings.Trim(val, "[]") | ||||||
| 	// Emtpy string would cause a slice with one (empty) entry | 	// Empty string would cause a slice with one (empty) entry | ||||||
| 	if len(val) == 0 { | 	if len(val) == 0 { | ||||||
| 		return []net.IP{}, nil | 		return []net.IP{}, nil | ||||||
| 	} | 	} | ||||||
|   | |||||||
							
								
								
									
										26
									
								
								vendor/github.com/spf13/pflag/string_array.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										26
									
								
								vendor/github.com/spf13/pflag/string_array.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -23,6 +23,32 @@ func (s *stringArrayValue) Set(val string) error { | |||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func (s *stringArrayValue) Append(val string) error { | ||||||
|  | 	*s.value = append(*s.value, val) | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (s *stringArrayValue) Replace(val []string) error { | ||||||
|  | 	out := make([]string, len(val)) | ||||||
|  | 	for i, d := range val { | ||||||
|  | 		var err error | ||||||
|  | 		out[i] = d | ||||||
|  | 		if err != nil { | ||||||
|  | 			return err | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	*s.value = out | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (s *stringArrayValue) GetSlice() []string { | ||||||
|  | 	out := make([]string, len(*s.value)) | ||||||
|  | 	for i, d := range *s.value { | ||||||
|  | 		out[i] = d | ||||||
|  | 	} | ||||||
|  | 	return out | ||||||
|  | } | ||||||
|  |  | ||||||
| func (s *stringArrayValue) Type() string { | func (s *stringArrayValue) Type() string { | ||||||
| 	return "stringArray" | 	return "stringArray" | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										22
									
								
								vendor/github.com/spf13/pflag/string_slice.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										22
									
								
								vendor/github.com/spf13/pflag/string_slice.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -62,6 +62,20 @@ func (s *stringSliceValue) String() string { | |||||||
| 	return "[" + str + "]" | 	return "[" + str + "]" | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func (s *stringSliceValue) Append(val string) error { | ||||||
|  | 	*s.value = append(*s.value, val) | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (s *stringSliceValue) Replace(val []string) error { | ||||||
|  | 	*s.value = val | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (s *stringSliceValue) GetSlice() []string { | ||||||
|  | 	return *s.value | ||||||
|  | } | ||||||
|  |  | ||||||
| func stringSliceConv(sval string) (interface{}, error) { | func stringSliceConv(sval string) (interface{}, error) { | ||||||
| 	sval = sval[1 : len(sval)-1] | 	sval = sval[1 : len(sval)-1] | ||||||
| 	// An empty string would cause a slice with one (empty) string | 	// An empty string would cause a slice with one (empty) string | ||||||
| @@ -84,7 +98,7 @@ func (f *FlagSet) GetStringSlice(name string) ([]string, error) { | |||||||
| // The argument p points to a []string variable in which to store the value of the flag. | // The argument p points to a []string variable in which to store the value of the flag. | ||||||
| // Compared to StringArray flags, StringSlice flags take comma-separated value as arguments and split them accordingly. | // Compared to StringArray flags, StringSlice flags take comma-separated value as arguments and split them accordingly. | ||||||
| // For example: | // For example: | ||||||
| //   --ss="v1,v2" -ss="v3" | //   --ss="v1,v2" --ss="v3" | ||||||
| // will result in | // will result in | ||||||
| //   []string{"v1", "v2", "v3"} | //   []string{"v1", "v2", "v3"} | ||||||
| func (f *FlagSet) StringSliceVar(p *[]string, name string, value []string, usage string) { | func (f *FlagSet) StringSliceVar(p *[]string, name string, value []string, usage string) { | ||||||
| @@ -100,7 +114,7 @@ func (f *FlagSet) StringSliceVarP(p *[]string, name, shorthand string, value []s | |||||||
| // The argument p points to a []string variable in which to store the value of the flag. | // The argument p points to a []string variable in which to store the value of the flag. | ||||||
| // Compared to StringArray flags, StringSlice flags take comma-separated value as arguments and split them accordingly. | // Compared to StringArray flags, StringSlice flags take comma-separated value as arguments and split them accordingly. | ||||||
| // For example: | // For example: | ||||||
| //   --ss="v1,v2" -ss="v3" | //   --ss="v1,v2" --ss="v3" | ||||||
| // will result in | // will result in | ||||||
| //   []string{"v1", "v2", "v3"} | //   []string{"v1", "v2", "v3"} | ||||||
| func StringSliceVar(p *[]string, name string, value []string, usage string) { | func StringSliceVar(p *[]string, name string, value []string, usage string) { | ||||||
| @@ -116,7 +130,7 @@ func StringSliceVarP(p *[]string, name, shorthand string, value []string, usage | |||||||
| // The return value is the address of a []string variable that stores the value of the flag. | // The return value is the address of a []string variable that stores the value of the flag. | ||||||
| // Compared to StringArray flags, StringSlice flags take comma-separated value as arguments and split them accordingly. | // Compared to StringArray flags, StringSlice flags take comma-separated value as arguments and split them accordingly. | ||||||
| // For example: | // For example: | ||||||
| //   --ss="v1,v2" -ss="v3" | //   --ss="v1,v2" --ss="v3" | ||||||
| // will result in | // will result in | ||||||
| //   []string{"v1", "v2", "v3"} | //   []string{"v1", "v2", "v3"} | ||||||
| func (f *FlagSet) StringSlice(name string, value []string, usage string) *[]string { | func (f *FlagSet) StringSlice(name string, value []string, usage string) *[]string { | ||||||
| @@ -136,7 +150,7 @@ func (f *FlagSet) StringSliceP(name, shorthand string, value []string, usage str | |||||||
| // The return value is the address of a []string variable that stores the value of the flag. | // The return value is the address of a []string variable that stores the value of the flag. | ||||||
| // Compared to StringArray flags, StringSlice flags take comma-separated value as arguments and split them accordingly. | // Compared to StringArray flags, StringSlice flags take comma-separated value as arguments and split them accordingly. | ||||||
| // For example: | // For example: | ||||||
| //   --ss="v1,v2" -ss="v3" | //   --ss="v1,v2" --ss="v3" | ||||||
| // will result in | // will result in | ||||||
| //   []string{"v1", "v2", "v3"} | //   []string{"v1", "v2", "v3"} | ||||||
| func StringSlice(name string, value []string, usage string) *[]string { | func StringSlice(name string, value []string, usage string) *[]string { | ||||||
|   | |||||||
							
								
								
									
										149
									
								
								vendor/github.com/spf13/pflag/string_to_int64.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										149
									
								
								vendor/github.com/spf13/pflag/string_to_int64.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,149 @@ | |||||||
|  | package pflag | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"bytes" | ||||||
|  | 	"fmt" | ||||||
|  | 	"strconv" | ||||||
|  | 	"strings" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // -- stringToInt64 Value | ||||||
|  | type stringToInt64Value struct { | ||||||
|  | 	value   *map[string]int64 | ||||||
|  | 	changed bool | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func newStringToInt64Value(val map[string]int64, p *map[string]int64) *stringToInt64Value { | ||||||
|  | 	ssv := new(stringToInt64Value) | ||||||
|  | 	ssv.value = p | ||||||
|  | 	*ssv.value = val | ||||||
|  | 	return ssv | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Format: a=1,b=2 | ||||||
|  | func (s *stringToInt64Value) Set(val string) error { | ||||||
|  | 	ss := strings.Split(val, ",") | ||||||
|  | 	out := make(map[string]int64, len(ss)) | ||||||
|  | 	for _, pair := range ss { | ||||||
|  | 		kv := strings.SplitN(pair, "=", 2) | ||||||
|  | 		if len(kv) != 2 { | ||||||
|  | 			return fmt.Errorf("%s must be formatted as key=value", pair) | ||||||
|  | 		} | ||||||
|  | 		var err error | ||||||
|  | 		out[kv[0]], err = strconv.ParseInt(kv[1], 10, 64) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return err | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	if !s.changed { | ||||||
|  | 		*s.value = out | ||||||
|  | 	} else { | ||||||
|  | 		for k, v := range out { | ||||||
|  | 			(*s.value)[k] = v | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	s.changed = true | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (s *stringToInt64Value) Type() string { | ||||||
|  | 	return "stringToInt64" | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (s *stringToInt64Value) String() string { | ||||||
|  | 	var buf bytes.Buffer | ||||||
|  | 	i := 0 | ||||||
|  | 	for k, v := range *s.value { | ||||||
|  | 		if i > 0 { | ||||||
|  | 			buf.WriteRune(',') | ||||||
|  | 		} | ||||||
|  | 		buf.WriteString(k) | ||||||
|  | 		buf.WriteRune('=') | ||||||
|  | 		buf.WriteString(strconv.FormatInt(v, 10)) | ||||||
|  | 		i++ | ||||||
|  | 	} | ||||||
|  | 	return "[" + buf.String() + "]" | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func stringToInt64Conv(val string) (interface{}, error) { | ||||||
|  | 	val = strings.Trim(val, "[]") | ||||||
|  | 	// An empty string would cause an empty map | ||||||
|  | 	if len(val) == 0 { | ||||||
|  | 		return map[string]int64{}, nil | ||||||
|  | 	} | ||||||
|  | 	ss := strings.Split(val, ",") | ||||||
|  | 	out := make(map[string]int64, len(ss)) | ||||||
|  | 	for _, pair := range ss { | ||||||
|  | 		kv := strings.SplitN(pair, "=", 2) | ||||||
|  | 		if len(kv) != 2 { | ||||||
|  | 			return nil, fmt.Errorf("%s must be formatted as key=value", pair) | ||||||
|  | 		} | ||||||
|  | 		var err error | ||||||
|  | 		out[kv[0]], err = strconv.ParseInt(kv[1], 10, 64) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return nil, err | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return out, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GetStringToInt64 return the map[string]int64 value of a flag with the given name | ||||||
|  | func (f *FlagSet) GetStringToInt64(name string) (map[string]int64, error) { | ||||||
|  | 	val, err := f.getFlagType(name, "stringToInt64", stringToInt64Conv) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return map[string]int64{}, err | ||||||
|  | 	} | ||||||
|  | 	return val.(map[string]int64), nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // StringToInt64Var defines a string flag with specified name, default value, and usage string. | ||||||
|  | // The argument p point64s to a map[string]int64 variable in which to store the values of the multiple flags. | ||||||
|  | // The value of each argument will not try to be separated by comma | ||||||
|  | func (f *FlagSet) StringToInt64Var(p *map[string]int64, name string, value map[string]int64, usage string) { | ||||||
|  | 	f.VarP(newStringToInt64Value(value, p), name, "", usage) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // StringToInt64VarP is like StringToInt64Var, but accepts a shorthand letter that can be used after a single dash. | ||||||
|  | func (f *FlagSet) StringToInt64VarP(p *map[string]int64, name, shorthand string, value map[string]int64, usage string) { | ||||||
|  | 	f.VarP(newStringToInt64Value(value, p), name, shorthand, usage) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // StringToInt64Var defines a string flag with specified name, default value, and usage string. | ||||||
|  | // The argument p point64s to a map[string]int64 variable in which to store the value of the flag. | ||||||
|  | // The value of each argument will not try to be separated by comma | ||||||
|  | func StringToInt64Var(p *map[string]int64, name string, value map[string]int64, usage string) { | ||||||
|  | 	CommandLine.VarP(newStringToInt64Value(value, p), name, "", usage) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // StringToInt64VarP is like StringToInt64Var, but accepts a shorthand letter that can be used after a single dash. | ||||||
|  | func StringToInt64VarP(p *map[string]int64, name, shorthand string, value map[string]int64, usage string) { | ||||||
|  | 	CommandLine.VarP(newStringToInt64Value(value, p), name, shorthand, usage) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // StringToInt64 defines a string flag with specified name, default value, and usage string. | ||||||
|  | // The return value is the address of a map[string]int64 variable that stores the value of the flag. | ||||||
|  | // The value of each argument will not try to be separated by comma | ||||||
|  | func (f *FlagSet) StringToInt64(name string, value map[string]int64, usage string) *map[string]int64 { | ||||||
|  | 	p := map[string]int64{} | ||||||
|  | 	f.StringToInt64VarP(&p, name, "", value, usage) | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // StringToInt64P is like StringToInt64, but accepts a shorthand letter that can be used after a single dash. | ||||||
|  | func (f *FlagSet) StringToInt64P(name, shorthand string, value map[string]int64, usage string) *map[string]int64 { | ||||||
|  | 	p := map[string]int64{} | ||||||
|  | 	f.StringToInt64VarP(&p, name, shorthand, value, usage) | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // StringToInt64 defines a string flag with specified name, default value, and usage string. | ||||||
|  | // The return value is the address of a map[string]int64 variable that stores the value of the flag. | ||||||
|  | // The value of each argument will not try to be separated by comma | ||||||
|  | func StringToInt64(name string, value map[string]int64, usage string) *map[string]int64 { | ||||||
|  | 	return CommandLine.StringToInt64P(name, "", value, usage) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // StringToInt64P is like StringToInt64, but accepts a shorthand letter that can be used after a single dash. | ||||||
|  | func StringToInt64P(name, shorthand string, value map[string]int64, usage string) *map[string]int64 { | ||||||
|  | 	return CommandLine.StringToInt64P(name, shorthand, value, usage) | ||||||
|  | } | ||||||
							
								
								
									
										42
									
								
								vendor/github.com/spf13/pflag/uint_slice.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										42
									
								
								vendor/github.com/spf13/pflag/uint_slice.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -50,6 +50,48 @@ func (s *uintSliceValue) String() string { | |||||||
| 	return "[" + strings.Join(out, ",") + "]" | 	return "[" + strings.Join(out, ",") + "]" | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func (s *uintSliceValue) fromString(val string) (uint, error) { | ||||||
|  | 	t, err := strconv.ParseUint(val, 10, 0) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return 0, err | ||||||
|  | 	} | ||||||
|  | 	return uint(t), nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (s *uintSliceValue) toString(val uint) string { | ||||||
|  | 	return fmt.Sprintf("%d", val) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (s *uintSliceValue) Append(val string) error { | ||||||
|  | 	i, err := s.fromString(val) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	*s.value = append(*s.value, i) | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (s *uintSliceValue) Replace(val []string) error { | ||||||
|  | 	out := make([]uint, len(val)) | ||||||
|  | 	for i, d := range val { | ||||||
|  | 		var err error | ||||||
|  | 		out[i], err = s.fromString(d) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return err | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	*s.value = out | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (s *uintSliceValue) GetSlice() []string { | ||||||
|  | 	out := make([]string, len(*s.value)) | ||||||
|  | 	for i, d := range *s.value { | ||||||
|  | 		out[i] = s.toString(d) | ||||||
|  | 	} | ||||||
|  | 	return out | ||||||
|  | } | ||||||
|  |  | ||||||
| func uintSliceConv(val string) (interface{}, error) { | func uintSliceConv(val string) (interface{}, error) { | ||||||
| 	val = strings.Trim(val, "[]") | 	val = strings.Trim(val, "[]") | ||||||
| 	// Empty string would cause a slice with one (empty) entry | 	// Empty string would cause a slice with one (empty) entry | ||||||
|   | |||||||
							
								
								
									
										26
									
								
								vendor/gopkg.in/testfixtures.v2/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										26
									
								
								vendor/gopkg.in/testfixtures.v2/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,26 +0,0 @@ | |||||||
| language: go |  | ||||||
|  |  | ||||||
| go: |  | ||||||
|   - '1.9' |  | ||||||
|   - '1.10' |  | ||||||
|  |  | ||||||
| services: |  | ||||||
|   - postgresql |  | ||||||
|   - mysql |  | ||||||
|  |  | ||||||
| addons: |  | ||||||
|   postgresql: "9.4" |  | ||||||
|  |  | ||||||
| before_script: |  | ||||||
|   - mysql -e 'CREATE DATABASE testfixtures_test;' |  | ||||||
|   - psql -c 'CREATE DATABASE testfixtures_test;' -U postgres |  | ||||||
|  |  | ||||||
| install: |  | ||||||
|   - go get -t -tags 'sqlite postgresql mysql' ./... |  | ||||||
|   - curl -s https://raw.githubusercontent.com/go-task/task/master/install-task.sh | sh |  | ||||||
|   - bin/task dl-deps |  | ||||||
|   - cp .sample.env .env |  | ||||||
|  |  | ||||||
| script: |  | ||||||
|   - bin/task lint |  | ||||||
|   - bin/task test-free |  | ||||||
							
								
								
									
										358
									
								
								vendor/gopkg.in/testfixtures.v2/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										358
									
								
								vendor/gopkg.in/testfixtures.v2/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,358 +0,0 @@ | |||||||
| # Go Test Fixtures |  | ||||||
|  |  | ||||||
| [](https://godoc.org/gopkg.in/testfixtures.v2) |  | ||||||
| [](https://goreportcard.com/report/github.com/go-testfixtures/testfixtures) |  | ||||||
| [](https://travis-ci.org/go-testfixtures/testfixtures) |  | ||||||
| [](https://ci.appveyor.com/project/andreynering/testfixtures) |  | ||||||
|  |  | ||||||
| > ***Warning***: this package will wipe the database data before loading the |  | ||||||
| fixtures! It is supposed to be used on a test database. Please, double check |  | ||||||
| if you are running it against the correct database. |  | ||||||
|  |  | ||||||
| Writing tests is hard, even more when you have to deal with an SQL database. |  | ||||||
| This package aims to make writing functional tests for web apps written in |  | ||||||
| Go easier. |  | ||||||
|  |  | ||||||
| Basically this package mimics the ["Rails' way"][railstests] of writing tests |  | ||||||
| for database applications, where sample data is kept in fixtures files. Before |  | ||||||
| the execution of every test, the test database is cleaned and the fixture data |  | ||||||
| is loaded into the database. |  | ||||||
|  |  | ||||||
| The idea is running tests against a real database, instead of relying in mocks, |  | ||||||
| which is boring to setup and may lead to production bugs not being caught in |  | ||||||
| the tests. |  | ||||||
|  |  | ||||||
| ## Installation |  | ||||||
|  |  | ||||||
| First, get it: |  | ||||||
|  |  | ||||||
| ```bash |  | ||||||
| go get -u -v gopkg.in/testfixtures.v2 |  | ||||||
| ``` |  | ||||||
|  |  | ||||||
| ## Usage |  | ||||||
|  |  | ||||||
| Create a folder for the fixture files. Each file should contain data for a |  | ||||||
| single table and have the name `<table_name>.yml`: |  | ||||||
|  |  | ||||||
| ``` |  | ||||||
| myapp/ |  | ||||||
|   myapp.go |  | ||||||
|   myapp_test.go |  | ||||||
|   ... |  | ||||||
|   fixtures/ |  | ||||||
|     posts.yml |  | ||||||
|     comments.yml |  | ||||||
|     tags.yml |  | ||||||
|     posts_tags.yml |  | ||||||
|     ... |  | ||||||
| ``` |  | ||||||
|  |  | ||||||
| The file would look like this (it can have as many record you want): |  | ||||||
|  |  | ||||||
| ```yml |  | ||||||
| # comments.yml |  | ||||||
| - id: 1 |  | ||||||
|   post_id: 1 |  | ||||||
|   content: A comment... |  | ||||||
|   author_name: John Doe |  | ||||||
|   author_email: john@doe.com |  | ||||||
|   created_at: 2016-01-01 12:30:12 |  | ||||||
|   updated_at: 2016-01-01 12:30:12 |  | ||||||
|  |  | ||||||
| - id: 2 |  | ||||||
|   post_id: 2 |  | ||||||
|   content: Another comment... |  | ||||||
|   author_name: John Doe |  | ||||||
|   author_email: john@doe.com |  | ||||||
|   created_at: 2016-01-01 12:30:12 |  | ||||||
|   updated_at: 2016-01-01 12:30:12 |  | ||||||
|  |  | ||||||
| # ... |  | ||||||
| ``` |  | ||||||
|  |  | ||||||
| An YAML object or array will be converted to JSON. It can be stored on a native |  | ||||||
| JSON type like JSONB on PostgreSQL or as a TEXT or VARCHAR column on other |  | ||||||
| databases. |  | ||||||
|  |  | ||||||
| ```yml |  | ||||||
| - id: 1 |  | ||||||
|   post_attributes: |  | ||||||
|     author: John Due |  | ||||||
|     author_email: john@due.com |  | ||||||
|     title: "..." |  | ||||||
|     tags: |  | ||||||
|       - programming |  | ||||||
|       - go |  | ||||||
|       - testing |  | ||||||
|     post: "..." |  | ||||||
| ``` |  | ||||||
|  |  | ||||||
| If you need to write raw SQL, probably to call a function, prefix the value |  | ||||||
| of the column with `RAW=`: |  | ||||||
|  |  | ||||||
| ```yml |  | ||||||
| - id: 1 |  | ||||||
|   uuid_column: RAW=uuid_generate_v4() |  | ||||||
|   postgis_type_column: RAW=ST_GeomFromText('params...') |  | ||||||
|   created_at: RAW=NOW() |  | ||||||
|   updated_at: RAW=NOW() |  | ||||||
| ``` |  | ||||||
|  |  | ||||||
| Your tests would look like this: |  | ||||||
|  |  | ||||||
| ```go |  | ||||||
| package myapp |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
|     "database/sql" |  | ||||||
|     "log" |  | ||||||
|  |  | ||||||
|     _ "github.com/lib/pq" |  | ||||||
|     "gopkg.in/testfixtures.v2" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| var ( |  | ||||||
|     db *sql.DB |  | ||||||
|     fixtures *testfixtures.Context |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| func TestMain(m *testing.M) { |  | ||||||
|     var err error |  | ||||||
|  |  | ||||||
|     // Open connection with the test database. |  | ||||||
|     // Do NOT import fixtures in a production database! |  | ||||||
|     // Existing data would be deleted |  | ||||||
|     db, err = sql.Open("postgres", "dbname=myapp_test") |  | ||||||
|     if err != nil { |  | ||||||
|         log.Fatal(err) |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     // creating the context that hold the fixtures |  | ||||||
|     // see about all compatible databases in this page below |  | ||||||
|     fixtures, err = testfixtures.NewFolder(db, &testfixtures.PostgreSQL{}, "testdata/fixtures") |  | ||||||
|     if err != nil { |  | ||||||
|         log.Fatal(err) |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     os.Exit(m.Run()) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func prepareTestDatabase() { |  | ||||||
|     if err := fixtures.Load(); err != nil { |  | ||||||
|         log.Fatal(err) |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func TestX(t *testing.T) { |  | ||||||
|     prepareTestDatabase() |  | ||||||
|     // your test here ... |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func TestY(t *testing.T) { |  | ||||||
|     prepareTestDatabase() |  | ||||||
|     // your test here ... |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func TestZ(t *testing.T) { |  | ||||||
|     prepareTestDatabase() |  | ||||||
|     // your test here ... |  | ||||||
| } |  | ||||||
| ``` |  | ||||||
|  |  | ||||||
| Alternatively, you can use the `NewFiles` function, to specify which |  | ||||||
| files you want to load into the database: |  | ||||||
|  |  | ||||||
| ```go |  | ||||||
| fixtures, err := testfixtures.NewFiles(db, &testfixtures.PostgreSQL{}, |  | ||||||
|     "fixtures/orders.yml", |  | ||||||
|     "fixtures/customers.yml", |  | ||||||
|     // add as many files you want |  | ||||||
| ) |  | ||||||
| if err != nil { |  | ||||||
|     log.Fatal(err) |  | ||||||
| } |  | ||||||
| ``` |  | ||||||
|  |  | ||||||
| ## Security check |  | ||||||
|  |  | ||||||
| In order to prevent you from accidentally wiping the wrong database, this |  | ||||||
| package will refuse to load fixtures if the database name (or database |  | ||||||
| filename for SQLite) doesn't contains "test". If you want to disable this |  | ||||||
| check, use: |  | ||||||
|  |  | ||||||
| ```go |  | ||||||
| testfixtures.SkipDatabaseNameCheck(true) |  | ||||||
| ``` |  | ||||||
|  |  | ||||||
| ## Sequences |  | ||||||
|  |  | ||||||
| For PostgreSQL or Oracle, this package also resets all sequences to a high |  | ||||||
| number to prevent duplicated primary keys while running the tests. |  | ||||||
| The default is 10000, but you can change that with: |  | ||||||
|  |  | ||||||
| ```go |  | ||||||
| testfixtures.ResetSequencesTo(10000) |  | ||||||
| ``` |  | ||||||
|  |  | ||||||
| ## Compatible databases |  | ||||||
|  |  | ||||||
| ### PostgreSQL |  | ||||||
|  |  | ||||||
| This package has two approaches to disable foreign keys while importing fixtures |  | ||||||
| in PostgreSQL databases: |  | ||||||
|  |  | ||||||
| #### With `DISABLE TRIGGER` |  | ||||||
|  |  | ||||||
| This is the default approach. For that use: |  | ||||||
|  |  | ||||||
| ```go |  | ||||||
| &testfixtures.PostgreSQL{} |  | ||||||
| ``` |  | ||||||
|  |  | ||||||
| With the above snippet this package will use `DISABLE TRIGGER` to temporarily |  | ||||||
| disabling foreign key constraints while loading fixtures. This work with any |  | ||||||
| version of PostgreSQL, but it is **required** to be connected in the database |  | ||||||
| as a SUPERUSER. You can make a PostgreSQL user a SUPERUSER with: |  | ||||||
|  |  | ||||||
| ```sql |  | ||||||
| ALTER USER your_user SUPERUSER; |  | ||||||
| ``` |  | ||||||
|  |  | ||||||
| #### With `ALTER CONSTRAINT` |  | ||||||
|  |  | ||||||
| This approach don't require to be connected as a SUPERUSER, but only work with |  | ||||||
| PostgreSQL versions >= 9.4. Try this if you are getting foreign key violation |  | ||||||
| errors with the previous approach. It is as simple as using: |  | ||||||
|  |  | ||||||
| ```go |  | ||||||
| &testfixtures.PostgreSQL{UseAlterConstraint: true} |  | ||||||
| ``` |  | ||||||
|  |  | ||||||
| ### MySQL / MariaDB |  | ||||||
|  |  | ||||||
| Just make sure the connection string have |  | ||||||
| [the multistatement parameter](https://github.com/go-sql-driver/mysql#multistatements) |  | ||||||
| set to true, and use: |  | ||||||
|  |  | ||||||
| ```go |  | ||||||
| &testfixtures.MySQL{} |  | ||||||
| ``` |  | ||||||
|  |  | ||||||
| ### SQLite |  | ||||||
|  |  | ||||||
| SQLite is also supported. It is recommended to create foreign keys as |  | ||||||
| `DEFERRABLE` (the default) to prevent problems. See more |  | ||||||
| [on the SQLite documentation](https://www.sqlite.org/foreignkeys.html#fk_deferred). |  | ||||||
| (Foreign key constraints are no-op by default on SQLite, but enabling it is |  | ||||||
| recommended). |  | ||||||
|  |  | ||||||
| ```go |  | ||||||
| &testfixtures.SQLite{} |  | ||||||
| ``` |  | ||||||
|  |  | ||||||
| ### Microsoft SQL Server |  | ||||||
|  |  | ||||||
| SQL Server support requires SQL Server >= 2008. Inserting on `IDENTITY` columns |  | ||||||
| are handled as well. Just make sure you are logged in with a user with |  | ||||||
| `ALTER TABLE` permission. |  | ||||||
|  |  | ||||||
| ```go |  | ||||||
| &testfixtures.SQLServer{} |  | ||||||
| ``` |  | ||||||
|  |  | ||||||
| ### Oracle |  | ||||||
|  |  | ||||||
| Oracle is supported as well. Use: |  | ||||||
|  |  | ||||||
| ```go |  | ||||||
| &testfixtures.Oracle{} |  | ||||||
| ``` |  | ||||||
|  |  | ||||||
| ## Generating fixtures for a existing database (experimental) |  | ||||||
|  |  | ||||||
| The following code will generate a YAML file for each table of the database in |  | ||||||
| the given folder. It may be useful to boostrap a test scenario from a sample |  | ||||||
| database of your app. |  | ||||||
|  |  | ||||||
| ```go |  | ||||||
| err := testfixtures.GenerateFixtures(db, &testfixtures.PostgreSQL{}, "testdata/fixtures") |  | ||||||
| if err != nil { |  | ||||||
|     log.Fatalf("Error generating fixtures: %v", err) |  | ||||||
| } |  | ||||||
| ``` |  | ||||||
|  |  | ||||||
| Or |  | ||||||
|  |  | ||||||
| ```go |  | ||||||
| err := testfixtures.GenerateFixturesForTables( |  | ||||||
|     db, |  | ||||||
|     []*TableInfo{ |  | ||||||
|         &TableInfo{Name: "table_name", Where: "foo = 'bar'"}, |  | ||||||
|         // ... |  | ||||||
|     }, |  | ||||||
|     &testfixtures.PostgreSQL{}, |  | ||||||
|     "testdata/fixtures", |  | ||||||
| ) |  | ||||||
| if err != nil { |  | ||||||
|     log.Fatalf("Error generating fixtures: %v", err) |  | ||||||
| } |  | ||||||
| ``` |  | ||||||
|  |  | ||||||
| > This was thought to run in small sample databases. It will likely break |  | ||||||
| if run in a production/big database. |  | ||||||
|  |  | ||||||
| ## Contributing |  | ||||||
|  |  | ||||||
| Tests were written to ensure everything work as expected. You can run the tests |  | ||||||
| with: |  | ||||||
|  |  | ||||||
| ```bash |  | ||||||
| # running tests for PostgreSQL |  | ||||||
| go test -tags postgresql |  | ||||||
|  |  | ||||||
| # running test for MySQL |  | ||||||
| go test -tags mysql |  | ||||||
|  |  | ||||||
| # running tests for SQLite |  | ||||||
| go test -tags sqlite |  | ||||||
|  |  | ||||||
| # running tests for SQL Server |  | ||||||
| go test -tags sqlserver |  | ||||||
|  |  | ||||||
| # running tests for Oracle |  | ||||||
| go test -tags oracle |  | ||||||
|  |  | ||||||
| # running test for multiple databases at once |  | ||||||
| go test -tags 'sqlite postgresql mysql' |  | ||||||
|  |  | ||||||
| # running tests + benchmark |  | ||||||
| go test -v -bench=. -tags postgresql |  | ||||||
| ``` |  | ||||||
|  |  | ||||||
| Travis runs tests for PostgreSQL, MySQL and SQLite. AppVeyor run for all |  | ||||||
| these and also Microsoft SQL Server. |  | ||||||
|  |  | ||||||
| To set the connection string of tests for each database, copy the `.sample.env` |  | ||||||
| file as `.env` and edit it according to your environment. |  | ||||||
|  |  | ||||||
| ## Alternatives |  | ||||||
|  |  | ||||||
| If you don't think using fixtures is a good idea, you can try one of these |  | ||||||
| packages instead: |  | ||||||
|  |  | ||||||
| - [factory-go][factorygo]: Factory for Go. Inspired by Python's Factory Boy |  | ||||||
| and Ruby's Factory Girl |  | ||||||
| - [go-txdb (Single transaction SQL driver for Go)][gotxdb]: Use a single |  | ||||||
| database transaction for each functional test, so you can rollback to |  | ||||||
| previous state between tests to have the same database state in all tests |  | ||||||
| - [go-sqlmock][gosqlmock]: A mock for the sql.DB interface. This allow you to |  | ||||||
| unit test database code without having to connect to a real database |  | ||||||
| - [dbcleaner][dbcleaner] - Clean database for testing, inspired by |  | ||||||
| database_cleaner for Ruby |  | ||||||
|  |  | ||||||
| [railstests]: http://guides.rubyonrails.org/testing.html#the-test-database |  | ||||||
| [gotxdb]: https://github.com/DATA-DOG/go-txdb |  | ||||||
| [gosqlmock]: https://github.com/DATA-DOG/go-sqlmock |  | ||||||
| [factorygo]: https://github.com/bluele/factory-go |  | ||||||
| [dbcleaner]: https://github.com/khaiql/dbcleaner |  | ||||||
							
								
								
									
										64
									
								
								vendor/gopkg.in/testfixtures.v2/Taskfile.yml
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										64
									
								
								vendor/gopkg.in/testfixtures.v2/Taskfile.yml
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,64 +0,0 @@ | |||||||
| # github.com/go-task/task |  | ||||||
|  |  | ||||||
| version: '2' |  | ||||||
|  |  | ||||||
| tasks: |  | ||||||
|   dl-deps: |  | ||||||
|     desc: Download cli deps |  | ||||||
|     cmds: |  | ||||||
|       - go get -u github.com/golang/lint/golint |  | ||||||
|  |  | ||||||
|   lint: |  | ||||||
|     desc: Runs golint |  | ||||||
|     cmds: |  | ||||||
|       - golint . |  | ||||||
|  |  | ||||||
|   test-free: |  | ||||||
|     desc: Test free databases (PG, MySQL and SQLite) |  | ||||||
|     cmds: |  | ||||||
|       - task: test-pg |  | ||||||
|       - task: test-mysql |  | ||||||
|       - task: test-sqlite |  | ||||||
|  |  | ||||||
|   test-all: |  | ||||||
|     desc: Test all databases (PG, MySQL, SQLite, SQLServer and Oracle) |  | ||||||
|     cmds: |  | ||||||
|       - task: test-pg |  | ||||||
|       - task: test-mysql |  | ||||||
|       - task: test-sqlite |  | ||||||
|       - task: test-sqlserver |  | ||||||
|       - task: test-oracle |  | ||||||
|  |  | ||||||
|   test-pg: |  | ||||||
|     desc: Test PostgreSQL |  | ||||||
|     cmds: |  | ||||||
|       - task: test-db |  | ||||||
|         vars: {DATABASE: postgresql} |  | ||||||
|  |  | ||||||
|   test-mysql: |  | ||||||
|     desc: Test MySQL |  | ||||||
|     cmds: |  | ||||||
|       - task: test-db |  | ||||||
|         vars: {DATABASE: mysql} |  | ||||||
|  |  | ||||||
|   test-sqlite: |  | ||||||
|     desc: Test SQLite |  | ||||||
|     cmds: |  | ||||||
|       - task: test-db |  | ||||||
|         vars: {DATABASE: sqlite} |  | ||||||
|  |  | ||||||
|   test-sqlserver: |  | ||||||
|     desc: Test SQLServer |  | ||||||
|     cmds: |  | ||||||
|       - task: test-db |  | ||||||
|         vars: {DATABASE: sqlserver} |  | ||||||
|  |  | ||||||
|   test-oracle: |  | ||||||
|     desc: Test Oracle |  | ||||||
|     cmds: |  | ||||||
|       - task: test-db |  | ||||||
|         vars: {DATABASE: oracle} |  | ||||||
|  |  | ||||||
|   test-db: |  | ||||||
|     cmds: |  | ||||||
|       - go test -v -tags {{.DATABASE}} |  | ||||||
							
								
								
									
										51
									
								
								vendor/gopkg.in/testfixtures.v2/appveyor.yml
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										51
									
								
								vendor/gopkg.in/testfixtures.v2/appveyor.yml
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,51 +0,0 @@ | |||||||
| version: '{build}' |  | ||||||
|  |  | ||||||
| clone_folder: C:\GOPATH\src\gopkg.in\testfixtures.v2 |  | ||||||
|  |  | ||||||
| build: false |  | ||||||
| deploy: false |  | ||||||
|  |  | ||||||
| services: |  | ||||||
|   - postgresql96 |  | ||||||
|   - mysql |  | ||||||
|   - mssql2017 |  | ||||||
|  |  | ||||||
| environment: |  | ||||||
|   POSTGRES_PATH: C:\Program Files\PostgreSQL\9.6 |  | ||||||
|   PGUSER: postgres |  | ||||||
|   PGPASSWORD: Password12! |  | ||||||
|   PG_CONN_STRING: 'user=postgres password=Password12! dbname=testfixtures_test sslmode=disable' |  | ||||||
|  |  | ||||||
|   MYSQL_PATH: C:\Program Files\MySql\MySQL Server 5.7 |  | ||||||
|   MYSQL_PWD: Password12! |  | ||||||
|   MYSQL_CONN_STRING: 'root:Password12!@/testfixtures_test?multiStatements=true' |  | ||||||
|  |  | ||||||
|   SQLITE_CONN_STRING: 'testdb.sqlite3' |  | ||||||
|  |  | ||||||
|   SQLSERVER_CONN_STRING: 'server=localhost;database=testfixtures_test;user id=sa;password=Password12!;encrypt=disable' |  | ||||||
|  |  | ||||||
|   MINGW_PATH: C:\MinGW |  | ||||||
|  |  | ||||||
|   GOPATH: C:\GOPATH |  | ||||||
|   GOVERSION: 1.10.3 |  | ||||||
|  |  | ||||||
| install: |  | ||||||
|   - SET PATH=%POSTGRES_PATH%\bin;%MYSQL_PATH%\bin;%MINGW_PATH%\bin;%PATH% |  | ||||||
|  |  | ||||||
|   - rmdir C:\go /s /q |  | ||||||
|   - appveyor DownloadFile https://storage.googleapis.com/golang/go%GOVERSION%.windows-386.msi |  | ||||||
|   - msiexec /i go%GOVERSION%.windows-386.msi /q |  | ||||||
|   - go version |  | ||||||
|  |  | ||||||
| build_script: |  | ||||||
|   - createdb testfixtures_test |  | ||||||
|   - mysql -e "CREATE DATABASE testfixtures_test;" --user=root |  | ||||||
|   - sqlcmd -S localhost,1433 -U sa -P Password12! -Q "CREATE DATABASE testfixtures_test" -d "master" |  | ||||||
|  |  | ||||||
| test_script: |  | ||||||
|   - go get -t -tags "sqlite postgresql mysql sqlserver" ./... |  | ||||||
|   - go install -v ./... |  | ||||||
|   - go test -v -tags postgresql |  | ||||||
|   - go test -v -tags mysql |  | ||||||
|   - go test -v -tags sqlserver |  | ||||||
|   - go test -v -tags sqlite |  | ||||||
							
								
								
									
										75
									
								
								vendor/gopkg.in/testfixtures.v2/deprecated.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										75
									
								
								vendor/gopkg.in/testfixtures.v2/deprecated.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,75 +0,0 @@ | |||||||
| package testfixtures |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	"database/sql" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| type ( |  | ||||||
| 	// DataBaseHelper is the helper interface |  | ||||||
| 	// Deprecated: Use Helper instead |  | ||||||
| 	DataBaseHelper Helper |  | ||||||
|  |  | ||||||
| 	// PostgreSQLHelper is the PostgreSQL helper |  | ||||||
| 	// Deprecated: Use PostgreSQL{} instead |  | ||||||
| 	PostgreSQLHelper struct { |  | ||||||
| 		PostgreSQL |  | ||||||
| 		UseAlterConstraint bool |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// MySQLHelper is the MySQL helper |  | ||||||
| 	// Deprecated: Use MySQL{} instead |  | ||||||
| 	MySQLHelper struct { |  | ||||||
| 		MySQL |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// SQLiteHelper is the SQLite helper |  | ||||||
| 	// Deprecated: Use SQLite{} instead |  | ||||||
| 	SQLiteHelper struct { |  | ||||||
| 		SQLite |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// SQLServerHelper is the SQLServer helper |  | ||||||
| 	// Deprecated: Use SQLServer{} instead |  | ||||||
| 	SQLServerHelper struct { |  | ||||||
| 		SQLServer |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// OracleHelper is the Oracle helper |  | ||||||
| 	// Deprecated: Use Oracle{} instead |  | ||||||
| 	OracleHelper struct { |  | ||||||
| 		Oracle |  | ||||||
| 	} |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| func (h *PostgreSQLHelper) disableReferentialIntegrity(db *sql.DB, loadFn loadFunction) error { |  | ||||||
| 	h.PostgreSQL.UseAlterConstraint = h.UseAlterConstraint |  | ||||||
| 	return h.PostgreSQL.disableReferentialIntegrity(db, loadFn) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // LoadFixtureFiles load all specified fixtures files into database: |  | ||||||
| // 		LoadFixtureFiles(db, &PostgreSQL{}, |  | ||||||
| // 			"fixtures/customers.yml", "fixtures/orders.yml") |  | ||||||
| //			// add as many files you want |  | ||||||
| // |  | ||||||
| // Deprecated: Use NewFiles() and Load() instead. |  | ||||||
| func LoadFixtureFiles(db *sql.DB, helper Helper, files ...string) error { |  | ||||||
| 	c, err := NewFiles(db, helper, files...) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return c.Load() |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // LoadFixtures loads all fixtures in a given folder into the database: |  | ||||||
| // 		LoadFixtures("myfixturesfolder", db, &PostgreSQL{}) |  | ||||||
| // |  | ||||||
| // Deprecated: Use NewFolder() and Load() instead. |  | ||||||
| func LoadFixtures(folderName string, db *sql.DB, helper Helper) error { |  | ||||||
| 	c, err := NewFolder(db, helper, folderName) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return c.Load() |  | ||||||
| } |  | ||||||
							
								
								
									
										41
									
								
								vendor/gopkg.in/testfixtures.v2/errors.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										41
									
								
								vendor/gopkg.in/testfixtures.v2/errors.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,41 +0,0 @@ | |||||||
| package testfixtures |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	"errors" |  | ||||||
| 	"fmt" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| var ( |  | ||||||
| 	// ErrWrongCastNotAMap is returned when a map is not a map[interface{}]interface{} |  | ||||||
| 	ErrWrongCastNotAMap = errors.New("Could not cast record: not a map[interface{}]interface{}") |  | ||||||
|  |  | ||||||
| 	// ErrFileIsNotSliceOrMap is returned the the fixture file is not a slice or map. |  | ||||||
| 	ErrFileIsNotSliceOrMap = errors.New("The fixture file is not a slice or map") |  | ||||||
|  |  | ||||||
| 	// ErrKeyIsNotString is returned when a record is not of type string |  | ||||||
| 	ErrKeyIsNotString = errors.New("Record map key is not string") |  | ||||||
|  |  | ||||||
| 	// ErrNotTestDatabase is returned when the database name doesn't contains "test" |  | ||||||
| 	ErrNotTestDatabase = errors.New(`Loading aborted because the database name does not contains "test"`) |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| // InsertError will be returned if any error happens on database while |  | ||||||
| // inserting the record |  | ||||||
| type InsertError struct { |  | ||||||
| 	Err    error |  | ||||||
| 	File   string |  | ||||||
| 	Index  int |  | ||||||
| 	SQL    string |  | ||||||
| 	Params []interface{} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (e *InsertError) Error() string { |  | ||||||
| 	return fmt.Sprintf( |  | ||||||
| 		"testfixtures: error inserting record: %v, on file: %s, index: %d, sql: %s, params: %v", |  | ||||||
| 		e.Err, |  | ||||||
| 		e.File, |  | ||||||
| 		e.Index, |  | ||||||
| 		e.SQL, |  | ||||||
| 		e.Params, |  | ||||||
| 	) |  | ||||||
| } |  | ||||||
							
								
								
									
										110
									
								
								vendor/gopkg.in/testfixtures.v2/generate.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										110
									
								
								vendor/gopkg.in/testfixtures.v2/generate.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,110 +0,0 @@ | |||||||
| package testfixtures |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	"database/sql" |  | ||||||
| 	"fmt" |  | ||||||
| 	"os" |  | ||||||
| 	"path" |  | ||||||
| 	"unicode/utf8" |  | ||||||
|  |  | ||||||
| 	"gopkg.in/yaml.v2" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| // TableInfo is settings for generating a fixture for table. |  | ||||||
| type TableInfo struct { |  | ||||||
| 	Name  string // Table name |  | ||||||
| 	Where string // A condition for extracting records. If this value is empty, extracts all records. |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (ti *TableInfo) whereClause() string { |  | ||||||
| 	if ti.Where == "" { |  | ||||||
| 		return "" |  | ||||||
| 	} |  | ||||||
| 	return fmt.Sprintf(" WHERE %s", ti.Where) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // GenerateFixtures generates fixtures for the current contents of a database, and saves |  | ||||||
| // them to the specified directory |  | ||||||
| func GenerateFixtures(db *sql.DB, helper Helper, dir string) error { |  | ||||||
| 	tables, err := helper.tableNames(db) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
| 	for _, table := range tables { |  | ||||||
| 		filename := path.Join(dir, table+".yml") |  | ||||||
| 		if err := generateFixturesForTable(db, helper, &TableInfo{Name: table}, filename); err != nil { |  | ||||||
| 			return err |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // GenerateFixturesForTables generates fixtures for the current contents of specified tables in a database, and saves |  | ||||||
| // them to the specified directory |  | ||||||
| func GenerateFixturesForTables(db *sql.DB, tables []*TableInfo, helper Helper, dir string) error { |  | ||||||
| 	for _, table := range tables { |  | ||||||
| 		filename := path.Join(dir, table.Name+".yml") |  | ||||||
| 		if err := generateFixturesForTable(db, helper, table, filename); err != nil { |  | ||||||
| 			return err |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func generateFixturesForTable(db *sql.DB, h Helper, table *TableInfo, filename string) error { |  | ||||||
| 	query := fmt.Sprintf("SELECT * FROM %s%s", h.quoteKeyword(table.Name), table.whereClause()) |  | ||||||
| 	rows, err := db.Query(query) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
| 	defer rows.Close() |  | ||||||
|  |  | ||||||
| 	columns, err := rows.Columns() |  | ||||||
| 	if err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	fixtures := make([]interface{}, 0, 10) |  | ||||||
| 	for rows.Next() { |  | ||||||
| 		entries := make([]interface{}, len(columns)) |  | ||||||
| 		entryPtrs := make([]interface{}, len(entries)) |  | ||||||
| 		for i := range entries { |  | ||||||
| 			entryPtrs[i] = &entries[i] |  | ||||||
| 		} |  | ||||||
| 		if err := rows.Scan(entryPtrs...); err != nil { |  | ||||||
| 			return err |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		entryMap := make(map[string]interface{}, len(entries)) |  | ||||||
| 		for i, column := range columns { |  | ||||||
| 			entryMap[column] = convertValue(entries[i]) |  | ||||||
| 		} |  | ||||||
| 		fixtures = append(fixtures, entryMap) |  | ||||||
| 	} |  | ||||||
| 	if err = rows.Err(); err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	f, err := os.Create(filename) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
| 	defer f.Close() |  | ||||||
|  |  | ||||||
| 	marshaled, err := yaml.Marshal(fixtures) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
| 	_, err = f.Write(marshaled) |  | ||||||
| 	return err |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func convertValue(value interface{}) interface{} { |  | ||||||
| 	switch v := value.(type) { |  | ||||||
| 	case []byte: |  | ||||||
| 		if utf8.Valid(v) { |  | ||||||
| 			return string(v) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return value |  | ||||||
| } |  | ||||||
							
								
								
									
										19
									
								
								vendor/gopkg.in/testfixtures.v2/options.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										19
									
								
								vendor/gopkg.in/testfixtures.v2/options.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,19 +0,0 @@ | |||||||
| package testfixtures |  | ||||||
|  |  | ||||||
| var ( |  | ||||||
| 	skipDatabaseNameCheck bool |  | ||||||
| 	resetSequencesTo      int64 = 10000 |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| // SkipDatabaseNameCheck If true, loading fixtures will not check if the database |  | ||||||
| // name constaint "test". Use with caution! |  | ||||||
| func SkipDatabaseNameCheck(value bool) { |  | ||||||
| 	skipDatabaseNameCheck = value |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // ResetSequencesTo sets the value the sequences will be reset to. |  | ||||||
| // This is used by PostgreSQL and Oracle. |  | ||||||
| // Defaults to 10000. |  | ||||||
| func ResetSequencesTo(value int64) { |  | ||||||
| 	resetSequencesTo = value |  | ||||||
| } |  | ||||||
							
								
								
									
										171
									
								
								vendor/gopkg.in/testfixtures.v2/oracle.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										171
									
								
								vendor/gopkg.in/testfixtures.v2/oracle.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,171 +0,0 @@ | |||||||
| package testfixtures |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	"database/sql" |  | ||||||
| 	"fmt" |  | ||||||
| 	"strings" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| // Oracle is the Oracle database helper for this package |  | ||||||
| type Oracle struct { |  | ||||||
| 	baseHelper |  | ||||||
|  |  | ||||||
| 	enabledConstraints []oracleConstraint |  | ||||||
| 	sequences          []string |  | ||||||
| } |  | ||||||
|  |  | ||||||
| type oracleConstraint struct { |  | ||||||
| 	tableName      string |  | ||||||
| 	constraintName string |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (h *Oracle) init(db *sql.DB) error { |  | ||||||
| 	var err error |  | ||||||
|  |  | ||||||
| 	h.enabledConstraints, err = h.getEnabledConstraints(db) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	h.sequences, err = h.getSequences(db) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (*Oracle) paramType() int { |  | ||||||
| 	return paramTypeColon |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (*Oracle) quoteKeyword(str string) string { |  | ||||||
| 	return fmt.Sprintf("\"%s\"", strings.ToUpper(str)) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (*Oracle) databaseName(q queryable) (string, error) { |  | ||||||
| 	var dbName string |  | ||||||
| 	err := q.QueryRow("SELECT user FROM DUAL").Scan(&dbName) |  | ||||||
| 	return dbName, err |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (*Oracle) tableNames(q queryable) ([]string, error) { |  | ||||||
| 	query := ` |  | ||||||
| 		SELECT TABLE_NAME |  | ||||||
| 		FROM USER_TABLES |  | ||||||
| 	` |  | ||||||
| 	rows, err := q.Query(query) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 	defer rows.Close() |  | ||||||
|  |  | ||||||
| 	var tables []string |  | ||||||
| 	for rows.Next() { |  | ||||||
| 		var table string |  | ||||||
| 		if err = rows.Scan(&table); err != nil { |  | ||||||
| 			return nil, err |  | ||||||
| 		} |  | ||||||
| 		tables = append(tables, table) |  | ||||||
| 	} |  | ||||||
| 	if err = rows.Err(); err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 	return tables, nil |  | ||||||
|  |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (*Oracle) getEnabledConstraints(q queryable) ([]oracleConstraint, error) { |  | ||||||
| 	var constraints []oracleConstraint |  | ||||||
| 	rows, err := q.Query(` |  | ||||||
| 		SELECT table_name, constraint_name |  | ||||||
| 		FROM user_constraints |  | ||||||
| 		WHERE constraint_type = 'R' |  | ||||||
| 		  AND status = 'ENABLED' |  | ||||||
| 	`) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 	defer rows.Close() |  | ||||||
|  |  | ||||||
| 	for rows.Next() { |  | ||||||
| 		var constraint oracleConstraint |  | ||||||
| 		rows.Scan(&constraint.tableName, &constraint.constraintName) |  | ||||||
| 		constraints = append(constraints, constraint) |  | ||||||
| 	} |  | ||||||
| 	if err = rows.Err(); err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 	return constraints, nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (*Oracle) getSequences(q queryable) ([]string, error) { |  | ||||||
| 	var sequences []string |  | ||||||
| 	rows, err := q.Query("SELECT sequence_name FROM user_sequences") |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 	defer rows.Close() |  | ||||||
|  |  | ||||||
| 	for rows.Next() { |  | ||||||
| 		var sequence string |  | ||||||
| 		if err = rows.Scan(&sequence); err != nil { |  | ||||||
| 			return nil, err |  | ||||||
| 		} |  | ||||||
| 		sequences = append(sequences, sequence) |  | ||||||
| 	} |  | ||||||
| 	if err = rows.Err(); err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 	return sequences, nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (h *Oracle) resetSequences(q queryable) error { |  | ||||||
| 	for _, sequence := range h.sequences { |  | ||||||
| 		_, err := q.Exec(fmt.Sprintf("DROP SEQUENCE %s", h.quoteKeyword(sequence))) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return err |  | ||||||
| 		} |  | ||||||
| 		_, err = q.Exec(fmt.Sprintf("CREATE SEQUENCE %s START WITH %d", h.quoteKeyword(sequence), resetSequencesTo)) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return err |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (h *Oracle) disableReferentialIntegrity(db *sql.DB, loadFn loadFunction) (err error) { |  | ||||||
| 	// re-enable after load |  | ||||||
| 	defer func() { |  | ||||||
| 		for _, c := range h.enabledConstraints { |  | ||||||
| 			_, err2 := db.Exec(fmt.Sprintf("ALTER TABLE %s ENABLE CONSTRAINT %s", h.quoteKeyword(c.tableName), h.quoteKeyword(c.constraintName))) |  | ||||||
| 			if err2 != nil && err == nil { |  | ||||||
| 				err = err2 |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	}() |  | ||||||
|  |  | ||||||
| 	// disable foreign keys |  | ||||||
| 	for _, c := range h.enabledConstraints { |  | ||||||
| 		_, err := db.Exec(fmt.Sprintf("ALTER TABLE %s DISABLE CONSTRAINT %s", h.quoteKeyword(c.tableName), h.quoteKeyword(c.constraintName))) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return err |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	tx, err := db.Begin() |  | ||||||
| 	if err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
| 	defer tx.Rollback() |  | ||||||
|  |  | ||||||
| 	if err = loadFn(tx); err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if err = tx.Commit(); err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return h.resetSequences(db) |  | ||||||
| } |  | ||||||
							
								
								
									
										305
									
								
								vendor/gopkg.in/testfixtures.v2/testfixtures.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										305
									
								
								vendor/gopkg.in/testfixtures.v2/testfixtures.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,305 +0,0 @@ | |||||||
| package testfixtures |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	"database/sql" |  | ||||||
| 	"fmt" |  | ||||||
| 	"io/ioutil" |  | ||||||
| 	"path" |  | ||||||
| 	"path/filepath" |  | ||||||
| 	"regexp" |  | ||||||
| 	"strings" |  | ||||||
|  |  | ||||||
| 	"gopkg.in/yaml.v2" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| // Context holds the fixtures to be loaded in the database. |  | ||||||
| type Context struct { |  | ||||||
| 	db            *sql.DB |  | ||||||
| 	helper        Helper |  | ||||||
| 	fixturesFiles []*fixtureFile |  | ||||||
| } |  | ||||||
|  |  | ||||||
| type fixtureFile struct { |  | ||||||
| 	path       string |  | ||||||
| 	fileName   string |  | ||||||
| 	content    []byte |  | ||||||
| 	insertSQLs []insertSQL |  | ||||||
| } |  | ||||||
|  |  | ||||||
| type insertSQL struct { |  | ||||||
| 	sql    string |  | ||||||
| 	params []interface{} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| var ( |  | ||||||
| 	dbnameRegexp = regexp.MustCompile("(?i)test") |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| // NewFolder creates a context for all fixtures in a given folder into the database: |  | ||||||
| //     NewFolder(db, &PostgreSQL{}, "my/fixtures/folder") |  | ||||||
| func NewFolder(db *sql.DB, helper Helper, folderName string) (*Context, error) { |  | ||||||
| 	fixtures, err := fixturesFromFolder(folderName) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	c, err := newContext(db, helper, fixtures) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return c, nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // NewFiles creates a context for all specified fixtures files into database: |  | ||||||
| //     NewFiles(db, &PostgreSQL{}, |  | ||||||
| //         "fixtures/customers.yml", |  | ||||||
| //         "fixtures/orders.yml" |  | ||||||
| //         // add as many files you want |  | ||||||
| //     ) |  | ||||||
| func NewFiles(db *sql.DB, helper Helper, fileNames ...string) (*Context, error) { |  | ||||||
| 	fixtures, err := fixturesFromFiles(fileNames...) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	c, err := newContext(db, helper, fixtures) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return c, nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func newContext(db *sql.DB, helper Helper, fixtures []*fixtureFile) (*Context, error) { |  | ||||||
| 	c := &Context{ |  | ||||||
| 		db:            db, |  | ||||||
| 		helper:        helper, |  | ||||||
| 		fixturesFiles: fixtures, |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if err := c.helper.init(c.db); err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if err := c.buildInsertSQLs(); err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return c, nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // DetectTestDatabase returns nil if databaseName matches regexp |  | ||||||
| //     if err := fixtures.DetectTestDatabase(); err != nil { |  | ||||||
| //         log.Fatal(err) |  | ||||||
| //     } |  | ||||||
| func (c *Context) DetectTestDatabase() error { |  | ||||||
| 	dbName, err := c.helper.databaseName(c.db) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
| 	if !dbnameRegexp.MatchString(dbName) { |  | ||||||
| 		return ErrNotTestDatabase |  | ||||||
| 	} |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Load wipes and after load all fixtures in the database. |  | ||||||
| //     if err := fixtures.Load(); err != nil { |  | ||||||
| //         log.Fatal(err) |  | ||||||
| //     } |  | ||||||
| func (c *Context) Load() error { |  | ||||||
| 	if !skipDatabaseNameCheck { |  | ||||||
| 		if err := c.DetectTestDatabase(); err != nil { |  | ||||||
| 			return err |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	err := c.helper.disableReferentialIntegrity(c.db, func(tx *sql.Tx) error { |  | ||||||
| 		for _, file := range c.fixturesFiles { |  | ||||||
| 			modified, err := c.helper.isTableModified(tx, file.fileNameWithoutExtension()) |  | ||||||
| 			if err != nil { |  | ||||||
| 				return err |  | ||||||
| 			} |  | ||||||
| 			if !modified { |  | ||||||
| 				continue |  | ||||||
| 			} |  | ||||||
| 			if err := file.delete(tx, c.helper); err != nil { |  | ||||||
| 				return err |  | ||||||
| 			} |  | ||||||
|  |  | ||||||
| 			err = c.helper.whileInsertOnTable(tx, file.fileNameWithoutExtension(), func() error { |  | ||||||
| 				for j, i := range file.insertSQLs { |  | ||||||
| 					if _, err := tx.Exec(i.sql, i.params...); err != nil { |  | ||||||
| 						return &InsertError{ |  | ||||||
| 							Err:    err, |  | ||||||
| 							File:   file.fileName, |  | ||||||
| 							Index:  j, |  | ||||||
| 							SQL:    i.sql, |  | ||||||
| 							Params: i.params, |  | ||||||
| 						} |  | ||||||
| 					} |  | ||||||
| 				} |  | ||||||
| 				return nil |  | ||||||
| 			}) |  | ||||||
| 			if err != nil { |  | ||||||
| 				return err |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 		return nil |  | ||||||
| 	}) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
| 	return c.helper.afterLoad(c.db) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (c *Context) buildInsertSQLs() error { |  | ||||||
| 	for _, f := range c.fixturesFiles { |  | ||||||
| 		var records interface{} |  | ||||||
| 		if err := yaml.Unmarshal(f.content, &records); err != nil { |  | ||||||
| 			return err |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		switch records := records.(type) { |  | ||||||
| 		case []interface{}: |  | ||||||
| 			for _, record := range records { |  | ||||||
| 				recordMap, ok := record.(map[interface{}]interface{}) |  | ||||||
| 				if !ok { |  | ||||||
| 					return ErrWrongCastNotAMap |  | ||||||
| 				} |  | ||||||
|  |  | ||||||
| 				sql, values, err := f.buildInsertSQL(c.helper, recordMap) |  | ||||||
| 				if err != nil { |  | ||||||
| 					return err |  | ||||||
| 				} |  | ||||||
|  |  | ||||||
| 				f.insertSQLs = append(f.insertSQLs, insertSQL{sql, values}) |  | ||||||
| 			} |  | ||||||
| 		case map[interface{}]interface{}: |  | ||||||
| 			for _, record := range records { |  | ||||||
| 				recordMap, ok := record.(map[interface{}]interface{}) |  | ||||||
| 				if !ok { |  | ||||||
| 					return ErrWrongCastNotAMap |  | ||||||
| 				} |  | ||||||
|  |  | ||||||
| 				sql, values, err := f.buildInsertSQL(c.helper, recordMap) |  | ||||||
| 				if err != nil { |  | ||||||
| 					return err |  | ||||||
| 				} |  | ||||||
|  |  | ||||||
| 				f.insertSQLs = append(f.insertSQLs, insertSQL{sql, values}) |  | ||||||
| 			} |  | ||||||
| 		default: |  | ||||||
| 			return ErrFileIsNotSliceOrMap |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (f *fixtureFile) fileNameWithoutExtension() string { |  | ||||||
| 	return strings.Replace(f.fileName, filepath.Ext(f.fileName), "", 1) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (f *fixtureFile) delete(tx *sql.Tx, h Helper) error { |  | ||||||
| 	_, err := tx.Exec(fmt.Sprintf("DELETE FROM %s", h.quoteKeyword(f.fileNameWithoutExtension()))) |  | ||||||
| 	return err |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (f *fixtureFile) buildInsertSQL(h Helper, record map[interface{}]interface{}) (sqlStr string, values []interface{}, err error) { |  | ||||||
| 	var ( |  | ||||||
| 		sqlColumns []string |  | ||||||
| 		sqlValues  []string |  | ||||||
| 		i          = 1 |  | ||||||
| 	) |  | ||||||
| 	for key, value := range record { |  | ||||||
| 		keyStr, ok := key.(string) |  | ||||||
| 		if !ok { |  | ||||||
| 			err = ErrKeyIsNotString |  | ||||||
| 			return |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		sqlColumns = append(sqlColumns, h.quoteKeyword(keyStr)) |  | ||||||
|  |  | ||||||
| 		// if string, try convert to SQL or time |  | ||||||
| 		// if map or array, convert to json |  | ||||||
| 		switch v := value.(type) { |  | ||||||
| 		case string: |  | ||||||
| 			if strings.HasPrefix(v, "RAW=") { |  | ||||||
| 				sqlValues = append(sqlValues, strings.TrimPrefix(v, "RAW=")) |  | ||||||
| 				continue |  | ||||||
| 			} |  | ||||||
|  |  | ||||||
| 			if t, err := tryStrToDate(v); err == nil { |  | ||||||
| 				value = t |  | ||||||
| 			} |  | ||||||
| 		case []interface{}, map[interface{}]interface{}: |  | ||||||
| 			value = recursiveToJSON(v) |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		switch h.paramType() { |  | ||||||
| 		case paramTypeDollar: |  | ||||||
| 			sqlValues = append(sqlValues, fmt.Sprintf("$%d", i)) |  | ||||||
| 		case paramTypeQuestion: |  | ||||||
| 			sqlValues = append(sqlValues, "?") |  | ||||||
| 		case paramTypeColon: |  | ||||||
| 			sqlValues = append(sqlValues, fmt.Sprintf(":%d", i)) |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		values = append(values, value) |  | ||||||
| 		i++ |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	sqlStr = fmt.Sprintf( |  | ||||||
| 		"INSERT INTO %s (%s) VALUES (%s)", |  | ||||||
| 		h.quoteKeyword(f.fileNameWithoutExtension()), |  | ||||||
| 		strings.Join(sqlColumns, ", "), |  | ||||||
| 		strings.Join(sqlValues, ", "), |  | ||||||
| 	) |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func fixturesFromFolder(folderName string) ([]*fixtureFile, error) { |  | ||||||
| 	var files []*fixtureFile |  | ||||||
| 	fileinfos, err := ioutil.ReadDir(folderName) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	for _, fileinfo := range fileinfos { |  | ||||||
| 		if !fileinfo.IsDir() && filepath.Ext(fileinfo.Name()) == ".yml" { |  | ||||||
| 			fixture := &fixtureFile{ |  | ||||||
| 				path:     path.Join(folderName, fileinfo.Name()), |  | ||||||
| 				fileName: fileinfo.Name(), |  | ||||||
| 			} |  | ||||||
| 			fixture.content, err = ioutil.ReadFile(fixture.path) |  | ||||||
| 			if err != nil { |  | ||||||
| 				return nil, err |  | ||||||
| 			} |  | ||||||
| 			files = append(files, fixture) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return files, nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func fixturesFromFiles(fileNames ...string) ([]*fixtureFile, error) { |  | ||||||
| 	var ( |  | ||||||
| 		fixtureFiles []*fixtureFile |  | ||||||
| 		err          error |  | ||||||
| 	) |  | ||||||
|  |  | ||||||
| 	for _, f := range fileNames { |  | ||||||
| 		fixture := &fixtureFile{ |  | ||||||
| 			path:     f, |  | ||||||
| 			fileName: filepath.Base(f), |  | ||||||
| 		} |  | ||||||
| 		fixture.content, err = ioutil.ReadFile(fixture.path) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return nil, err |  | ||||||
| 		} |  | ||||||
| 		fixtureFiles = append(fixtureFiles, fixture) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return fixtureFiles, nil |  | ||||||
| } |  | ||||||
							
								
								
									
										34
									
								
								vendor/gopkg.in/testfixtures.v2/time.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										34
									
								
								vendor/gopkg.in/testfixtures.v2/time.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,34 +0,0 @@ | |||||||
| package testfixtures |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	"errors" |  | ||||||
| 	"time" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| var timeFormats = []string{ |  | ||||||
| 	"2006-01-02", |  | ||||||
| 	"2006-01-02 15:04", |  | ||||||
| 	"2006-01-02 15:04:05", |  | ||||||
| 	"20060102", |  | ||||||
| 	"20060102 15:04", |  | ||||||
| 	"20060102 15:04:05", |  | ||||||
| 	"02/01/2006", |  | ||||||
| 	"02/01/2006 15:04", |  | ||||||
| 	"02/01/2006 15:04:05", |  | ||||||
| 	"2006-01-02T15:04-07:00", |  | ||||||
| 	"2006-01-02T15:04:05-07:00", |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // ErrCouldNotConvertToTime is returns when a string is not a reconizable time format |  | ||||||
| var ErrCouldNotConvertToTime = errors.New("Could not convert string to time") |  | ||||||
|  |  | ||||||
| func tryStrToDate(s string) (time.Time, error) { |  | ||||||
| 	for _, f := range timeFormats { |  | ||||||
| 		t, err := time.ParseInLocation(f, s, time.Local) |  | ||||||
| 		if err != nil { |  | ||||||
| 			continue |  | ||||||
| 		} |  | ||||||
| 		return t, nil |  | ||||||
| 	} |  | ||||||
| 	return time.Time{}, ErrCouldNotConvertToTime |  | ||||||
| } |  | ||||||
							
								
								
									
										1
									
								
								vendor/gopkg.in/yaml.v2/apic.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								vendor/gopkg.in/yaml.v2/apic.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -86,6 +86,7 @@ func yaml_emitter_initialize(emitter *yaml_emitter_t) { | |||||||
| 		raw_buffer: make([]byte, 0, output_raw_buffer_size), | 		raw_buffer: make([]byte, 0, output_raw_buffer_size), | ||||||
| 		states:     make([]yaml_emitter_state_t, 0, initial_stack_size), | 		states:     make([]yaml_emitter_state_t, 0, initial_stack_size), | ||||||
| 		events:     make([]yaml_event_t, 0, initial_queue_size), | 		events:     make([]yaml_event_t, 0, initial_queue_size), | ||||||
|  | 		best_width: -1, | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										16
									
								
								vendor/modules.txt
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										16
									
								
								vendor/modules.txt
									
									
									
									
										vendored
									
									
								
							| @@ -333,6 +333,9 @@ github.com/go-swagger/go-swagger/cmd/swagger/commands/initcmd | |||||||
| github.com/go-swagger/go-swagger/codescan | github.com/go-swagger/go-swagger/codescan | ||||||
| github.com/go-swagger/go-swagger/generator | github.com/go-swagger/go-swagger/generator | ||||||
| github.com/go-swagger/go-swagger/scan | github.com/go-swagger/go-swagger/scan | ||||||
|  | # github.com/go-testfixtures/testfixtures/v3 v3.2.0 | ||||||
|  | ## explicit | ||||||
|  | github.com/go-testfixtures/testfixtures/v3 | ||||||
| # github.com/gobwas/glob v0.2.3 | # github.com/gobwas/glob v0.2.3 | ||||||
| ## explicit | ## explicit | ||||||
| github.com/gobwas/glob | github.com/gobwas/glob | ||||||
| @@ -410,8 +413,6 @@ github.com/jbenet/go-context/io | |||||||
| github.com/jessevdk/go-flags | github.com/jessevdk/go-flags | ||||||
| # github.com/jmhodges/levigo v1.0.0 | # github.com/jmhodges/levigo v1.0.0 | ||||||
| ## explicit | ## explicit | ||||||
| # github.com/joho/godotenv v1.3.0 |  | ||||||
| ## explicit |  | ||||||
| # github.com/kballard/go-shellquote v0.0.0-20170619183022-cd60e84ee657 | # github.com/kballard/go-shellquote v0.0.0-20170619183022-cd60e84ee657 | ||||||
| ## explicit | ## explicit | ||||||
| github.com/kballard/go-shellquote | github.com/kballard/go-shellquote | ||||||
| @@ -496,11 +497,9 @@ github.com/mattn/go-colorable | |||||||
| # github.com/mattn/go-isatty v0.0.11 | # github.com/mattn/go-isatty v0.0.11 | ||||||
| ## explicit | ## explicit | ||||||
| github.com/mattn/go-isatty | github.com/mattn/go-isatty | ||||||
| # github.com/mattn/go-oci8 v0.0.0-20190320171441-14ba190cf52d |  | ||||||
| ## explicit |  | ||||||
| # github.com/mattn/go-runewidth v0.0.7 | # github.com/mattn/go-runewidth v0.0.7 | ||||||
| github.com/mattn/go-runewidth | github.com/mattn/go-runewidth | ||||||
| # github.com/mattn/go-sqlite3 v1.11.0 | # github.com/mattn/go-sqlite3 v2.0.2+incompatible | ||||||
| ## explicit | ## explicit | ||||||
| github.com/mattn/go-sqlite3 | github.com/mattn/go-sqlite3 | ||||||
| # github.com/matttproud/golang_protobuf_extensions v1.0.1 | # github.com/matttproud/golang_protobuf_extensions v1.0.1 | ||||||
| @@ -613,7 +612,7 @@ github.com/spf13/afero/mem | |||||||
| github.com/spf13/cast | github.com/spf13/cast | ||||||
| # github.com/spf13/jwalterweatherman v1.1.0 | # github.com/spf13/jwalterweatherman v1.1.0 | ||||||
| github.com/spf13/jwalterweatherman | github.com/spf13/jwalterweatherman | ||||||
| # github.com/spf13/pflag v1.0.3 | # github.com/spf13/pflag v1.0.5 | ||||||
| github.com/spf13/pflag | github.com/spf13/pflag | ||||||
| # github.com/spf13/viper v1.4.0 | # github.com/spf13/viper v1.4.0 | ||||||
| github.com/spf13/viper | github.com/spf13/viper | ||||||
| @@ -861,12 +860,9 @@ gopkg.in/ini.v1 | |||||||
| # gopkg.in/ldap.v3 v3.0.2 | # gopkg.in/ldap.v3 v3.0.2 | ||||||
| ## explicit | ## explicit | ||||||
| gopkg.in/ldap.v3 | gopkg.in/ldap.v3 | ||||||
| # gopkg.in/testfixtures.v2 v2.5.0 |  | ||||||
| ## explicit |  | ||||||
| gopkg.in/testfixtures.v2 |  | ||||||
| # gopkg.in/warnings.v0 v0.1.2 | # gopkg.in/warnings.v0 v0.1.2 | ||||||
| gopkg.in/warnings.v0 | gopkg.in/warnings.v0 | ||||||
| # gopkg.in/yaml.v2 v2.2.8 | # gopkg.in/yaml.v2 v2.3.0 | ||||||
| ## explicit | ## explicit | ||||||
| gopkg.in/yaml.v2 | gopkg.in/yaml.v2 | ||||||
| # mvdan.cc/xurls/v2 v2.1.0 | # mvdan.cc/xurls/v2 v2.1.0 | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 techknowlogick
					techknowlogick