diff --git a/docs/2022-07-10-bootstrap-go.html b/docs/2022-07-10-bootstrap-go.html index 8560b00..5320c32 100644 --- a/docs/2022-07-10-bootstrap-go.html +++ b/docs/2022-07-10-bootstrap-go.html @@ -224,9 +224,9 @@ internal Example:

-
func main() {
-	s := NewS(WithA(1), WithB("b"))
-	fmt.Printf("%+v\n", s)
+      
func main() {
+	s := NewS(WithA(1), WithB("b"))
+	fmt.Printf("%+v\n", s)
 }
 
 type S struct {
@@ -236,22 +236,22 @@ internal
 
 type OptionS func(s *S)
 
-func WithA(a int) OptionS {
+func WithA(a int) OptionS {
 	return func(s *S) {
 		s.fieldA = a
 	}
 }
 
-func WithB(b string) OptionS {
+func WithB(b string) OptionS {
 	return func(s *S) {
 		s.fieldB = b
 	}
 }
 
-func NewS(opts ...OptionS) *S {
+func NewS(opts ...OptionS) *S {
 	s := &S{}
 	for _, opt := range opts {
-		opt(s)
+		opt(s)
 	}
 	return s
 }
@@ -292,19 +292,19 @@ internal

Example:

-
eg, egCtx := errgroup.WithContext(ctx)
+      
eg, egCtx := errgroup.WithContext(ctx)
 
-eg.Go(func() error {
+eg.Go(func() error {
 	// Do some thing
 	return nil
 })
 
-eg.Go(func() error {
+eg.Go(func() error {
 	// Do other thing
 	return nil
 })
 
-if err := eg.Wait(); err != nil {
+if err := eg.Wait(); err != nil {
 	// Handle error
 }
@@ -346,27 +346,27 @@ internal
var bufPool = sync.Pool{
 	New: func() any {
-		return new(bytes.Buffer)
+		return new(bytes.Buffer)
 	},
 }
 
-func MarshalWithoutEscapeHTML(v any) ([]byte, error) {
-	b, ok := bufPool.Get().(*bytes.Buffer)
+func MarshalWithoutEscapeHTML(v any) ([]byte, error) {
+	b, ok := bufPool.Get().(*bytes.Buffer)
 	if !ok {
 		return nil, ErrBufPoolNotBytesBuffer
 	}
 
-	b.Reset()
-	defer bufPool.Put(b)
+	b.Reset()
+	defer bufPool.Put(b)
 
-	encoder := json.NewEncoder(b)
-	encoder.SetEscapeHTML(false)
-	if err := encoder.Encode(v); err != nil {
+	encoder := json.NewEncoder(b)
+	encoder.SetEscapeHTML(false)
+	if err := encoder.Encode(v); err != nil {
 		return nil, err
 	}
 
-	result := make([]byte, b.Len())
-	copy(result, b.Bytes())
+	result := make([]byte, b.Len())
+	copy(result, b.Bytes())
 	return result, nil
 }
@@ -391,13 +391,13 @@ internal

// Ptr takes in non-pointer and returns a pointer
-func Ptr[T any](v T) *T {
+func Ptr[T any](v T) *T {
 	return &v
 }

Return zero value:

-
func Zero[T any]() T {
+      
func Zero[T any]() T {
   var zero T
   return zero
 }
@@ -584,8 +584,8 @@ internal

Remember to free resources after parse multipart form:

defer func() {
-    if err := c.Request.MultipartForm.RemoveAll(); err != nil {
-        fmt.Println(err)
+    if err := c.Request.MultipartForm.RemoveAll(); err != nil {
+        fmt.Println(err)
     }
 }()
@@ -723,14 +723,14 @@ internal

Example:

-
func (c *client) HSetWithExpire(ctx context.Context, key string, values []any, expired time.Duration) error {
-	cmds := make([]redis.Cmder, 2)
+      
func (c *client) HSetWithExpire(ctx context.Context, key string, values []any, expired time.Duration) error {
+	cmds := make([]redis.Cmder, 2)
 
-	if _, err := c.Pipelined(ctx, func(pipe redis.Pipeliner) error {
-		cmds[0] = pipe.HSet(ctx, key, values...)
+	if _, err := c.Pipelined(ctx, func(pipe redis.Pipeliner) error {
+		cmds[0] = pipe.HSet(ctx, key, values...)
 
 		if expired > 0 {
-			cmds[1] = pipe.Expire(ctx, key, expired)
+			cmds[1] = pipe.Expire(ctx, key, expired)
 		}
 
 		return nil
@@ -743,7 +743,7 @@ internal
 			continue
 		}
 
-		if err := cmd.Err(); err != nil {
+		if err := cmd.Err(); err != nil {
 			return err
 		}
 	}
@@ -884,10 +884,10 @@ internal
     

Don't cast enum:

// Bad
-a := cast.ToInt32(servicev1.ReasonCode_ABC)
+a := cast.ToInt32(servicev1.ReasonCode_ABC)
 
 // Good
-a := int32(servicev1.ReasonCode_ABC)
+a := int32(servicev1.ReasonCode_ABC)

diff --git a/docs/2022-07-31-experiment-go.html b/docs/2022-07-31-experiment-go.html index ca21a6f..f24f1ea 100644 --- a/docs/2022-07-31-experiment-go.html +++ b/docs/2022-07-31-experiment-go.html @@ -83,8 +83,8 @@ } // c is Client -c.GetUser() -c.RemoveAccount()

+c.GetUser() +c.RemoveAccount()

Try:

@@ -104,8 +104,8 @@ } // c is Client -c.User.Get() -c.Account.Remove() +c.User.Get() +c.Account.Remove()

The difference is c.GetUser() -> diff --git a/docs/2022-07-31-sql.html b/docs/2022-07-31-sql.html index b3212b6..f59f83b 100644 --- a/docs/2022-07-31-sql.html +++ b/docs/2022-07-31-sql.html @@ -511,6 +511,15 @@ >

+
  • +

    + SQL best practices – don’t compare count(*) with 0 +

    +
  • diff --git a/docs/2022-12-25-go-test-asap.html b/docs/2022-12-25-go-test-asap.html index a1e7e31..cddb8fe 100644 --- a/docs/2022-12-25-go-test-asap.html +++ b/docs/2022-12-25-go-test-asap.html @@ -141,25 +141,25 @@ verifyService VerifyService } -func (s *service) Upload(ctx context.Context, req Request) error { +func (s *service) Upload(ctx context.Context, req Request) error { // I simplify by omitting the response, only care error for now - if err := s.verifyService.Verify(req); err != nil { + if err := s.verifyService.Verify(req); err != nil { return err } - if err := s.minio.Put(req); err != nil { + if err := s.minio.Put(req); err != nil { return err } - if err := s.redis.Set(req); err != nil { + if err := s.redis.Set(req); err != nil { return err } - if err := s.db.Save(req); err != nil { + if err := s.db.Save(req); err != nil { return err } - if err := s.logService.Save(req); err != nil { + if err := s.logService.Save(req); err != nil { return err } @@ -184,12 +184,12 @@ s service } -func (s *ServiceSuite) SetupTest() { +func (s *ServiceSuite) SetupTest() { // Init mock // Init service } -func (s *ServiceSuite) TestUpload() { +func (s *ServiceSuite) TestUpload() { tests := []struct{ name string req Request @@ -206,15 +206,15 @@ } for _, tc := range tests { - s.Run(tc.name, func(){ + s.Run(tc.name, func(){ // Mock all error depends on test case if tc.verifyErr != nil { - s.verifyService.MockVerify().Return(tc.verifyErr) + s.verifyService.MockVerify().Return(tc.verifyErr) } // ... - gotErr := s.service.Upload(tc.req) - s.Equal(wantErr, gotErr) + gotErr := s.service.Upload(tc.req) + s.Equal(wantErr, gotErr) }) } } @@ -326,36 +326,36 @@
    // Init ServiceSuite as above
     
    -func (s *ServiceSuite) TestUpload() {
    +func (s *ServiceSuite) TestUpload() {
         // Init success request
         req := Request{
             // ...
         }
     
         // Init success action
    -    s.verifyService.MockVerify().Return(nil)
    +    s.verifyService.MockVerify().Return(nil)
         // ...
     
    -    gotErr := s.service.Upload(tc.req)
    -    s.NoError(gotErr)
    +    gotErr := s.service.Upload(tc.req)
    +    s.NoError(gotErr)
     
    -    s.Run("failed", func(){
    +    s.Run("failed", func(){
             // Alter failed request from default
             req := Request{
                 // ...
             }
     
    -        gotErr := s.service.Upload(tc.req)
    -        s.Error(gotErr)
    +        gotErr := s.service.Upload(tc.req)
    +        s.Error(gotErr)
         })
     
    -    s.Run("another failed", func(){
    +    s.Run("another failed", func(){
             // Alter verify return
    -        s.verifyService.MockVerify().Return(someErr)
    +        s.verifyService.MockVerify().Return(someErr)
     
     
    -        gotErr := s.service.Upload(tc.req)
    -        s.Error(gotErr)
    +        gotErr := s.service.Upload(tc.req)
    +        s.Error(gotErr)
         })
     
         // ...
    diff --git a/docs/2023-06-10-incident-context.html b/docs/2023-06-10-incident-context.html
    index 2332103..1b6afa3 100644
    --- a/docs/2023-06-10-incident-context.html
    +++ b/docs/2023-06-10-incident-context.html
    @@ -81,12 +81,12 @@
         

    My buggy code is like this:

    -
    if err := doA(ctx); err != nil {
    -    log.Error(err)
    +      
    if err := doA(ctx); err != nil {
    +    log.Error(err)
         // Skip error
     }
     
    -doB(ctx)
    +doB(ctx)

    The problem is doA taking too long, so ctx is @@ -102,35 +102,35 @@ >):

    -
    func main() {
    -	ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
    -	defer cancel()
    +      
    func main() {
    +	ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
    +	defer cancel()
     
    -	doA(ctx)
    -	doB(ctx)
    +	doA(ctx)
    +	doB(ctx)
     }
     
    -func doA(ctx context.Context) {
    -	ctx, ctxCancel := context.WithTimeout(ctx, 1*time.Second)
    -	defer ctxCancel()
    +func doA(ctx context.Context) {
    +	ctx, ctxCancel := context.WithTimeout(ctx, 1*time.Second)
    +	defer ctxCancel()
     
     	select {
    -	case <-time.After(2 * time.Second):
    -		fmt.Println("doA")
    -	case <-ctx.Done():
    -		fmt.Println("doA", ctx.Err())
    +	case <-time.After(2 * time.Second):
    +		fmt.Println("doA")
    +	case <-ctx.Done():
    +		fmt.Println("doA", ctx.Err())
     	}
     }
     
    -func doB(ctx context.Context) {
    -	ctx, ctxCancel := context.WithTimeout(ctx, 3*time.Second)
    -	defer ctxCancel()
    +func doB(ctx context.Context) {
    +	ctx, ctxCancel := context.WithTimeout(ctx, 3*time.Second)
    +	defer ctxCancel()
     
     	select {
    -	case <-time.After(2 * time.Second):
    -		fmt.Println("doB")
    -	case <-ctx.Done():
    -		fmt.Println("doB", ctx.Err())
    +	case <-time.After(2 * time.Second):
    +		fmt.Println("doB")
    +	case <-ctx.Done():
    +		fmt.Println("doB", ctx.Err())
     	}
     }
    @@ -185,9 +185,9 @@ doB context deadline exceeded
    :

    -
    func DisconnectContext(parent context.Context) context.Context {
    +      
    func DisconnectContext(parent context.Context) context.Context {
     	if parent == nil {
    -		return context.Background()
    +		return context.Background()
     	}
     
     	return disconnectedContext{
    @@ -199,20 +199,20 @@ doB context deadline exceeded
    parent context.Context } -func (ctx disconnectedContext) Deadline() (deadline time.Time, ok bool) { +func (ctx disconnectedContext) Deadline() (deadline time.Time, ok bool) { return } -func (ctx disconnectedContext) Done() <-chan struct{} { +func (ctx disconnectedContext) Done() <-chan struct{} { return nil } -func (ctx disconnectedContext) Err() error { +func (ctx disconnectedContext) Err() error { return nil } -func (ctx disconnectedContext) Value(key any) any { - return ctx.parent.Value(key) +func (ctx disconnectedContext) Value(key any) any { + return ctx.parent.Value(key) }

    @@ -223,34 +223,34 @@ doB context deadline exceeded):

    -
    func main() {
    -	ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
    -	defer cancel()
    -	doA(ctx)
    -	doB(ctx)
    +      
    func main() {
    +	ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
    +	defer cancel()
    +	doA(ctx)
    +	doB(ctx)
     }
     
    -func doA(ctx context.Context) {
    -	ctx, ctxCancel := context.WithTimeout(ctx, 1*time.Second)
    -	defer ctxCancel()
    +func doA(ctx context.Context) {
    +	ctx, ctxCancel := context.WithTimeout(ctx, 1*time.Second)
    +	defer ctxCancel()
     
     	select {
    -	case <-time.After(2 * time.Second):
    -		fmt.Println("doA")
    -	case <-ctx.Done():
    -		fmt.Println("doA", ctx.Err())
    +	case <-time.After(2 * time.Second):
    +		fmt.Println("doA")
    +	case <-ctx.Done():
    +		fmt.Println("doA", ctx.Err())
     	}
     }
     
    -func doB(ctx context.Context) {
    -	ctx, ctxCancel := context.WithTimeout(DisconnectContext(ctx), 3*time.Second)
    -	defer ctxCancel()
    +func doB(ctx context.Context) {
    +	ctx, ctxCancel := context.WithTimeout(DisconnectContext(ctx), 3*time.Second)
    +	defer ctxCancel()
     
     	select {
    -	case <-time.After(2 * time.Second):
    -		fmt.Println("doB")
    -	case <-ctx.Done():
    -		fmt.Println("doB", ctx.Err())
    +	case <-time.After(2 * time.Second):
    +		fmt.Println("doB")
    +	case <-ctx.Done():
    +		fmt.Println("doB", ctx.Err())
     	}
     }
    diff --git a/docs/2023-07-01-pastebin.html b/docs/2023-07-01-pastebin.html index 9183cc8..1bec43b 100644 --- a/docs/2023-07-01-pastebin.html +++ b/docs/2023-07-01-pastebin.html @@ -271,6 +271,11 @@ sudo pkill bluetoothd +
  • + Why always something is running at port 5000 on my mac +
  • Firefox

    diff --git a/docs/2023-08-23-real-world-crypto.html b/docs/2023-08-23-real-world-crypto.html index 332198e..28c92df 100644 --- a/docs/2023-08-23-real-world-crypto.html +++ b/docs/2023-08-23-real-world-crypto.html @@ -132,7 +132,7 @@

    Constant time comparison:

    -
    for i := 0; i < len(x); i++ {
    +      
    for i := 0; i < len(x); i++ {
         // Use XOR instead of compare x[i] == y[i]
         // If x[i] == y[i] -> XOR is 1
         // Otherwise XOR is 0
    diff --git a/posts/2022-07-31-sql.md b/posts/2022-07-31-sql.md
    index 33472de..bfe501f 100644
    --- a/posts/2022-07-31-sql.md
    +++ b/posts/2022-07-31-sql.md
    @@ -192,3 +192,4 @@ FROM information_schema.statistics;
     - [Difference between text and varchar (character varying)](https://stackoverflow.com/a/4849030)
     - [How to get the number of total results when there is LIMIT in query?](https://stackoverflow.com/q/33889922)
     - [Run a query with a LIMIT/OFFSET and also get the total number of rows](https://stackoverflow.com/q/28888375)
    +- [SQL best practices – don’t compare count(*) with 0](https://www.depesz.com/2024/12/01/sql-best-practices-dont-compare-count-with-0/)
    diff --git a/posts/2023-07-01-pastebin.md b/posts/2023-07-01-pastebin.md
    index 8fee2cc..f446e7b 100644
    --- a/posts/2023-07-01-pastebin.md
    +++ b/posts/2023-07-01-pastebin.md
    @@ -136,6 +136,7 @@ Thanks:
     - [Upgrading Homebrew and avoiding the failed to verify attestation error](https://til.simonwillison.net/homebrew/no-verify-attestations)
     - [Use iMac M1 accent colours on any Mac](https://georgegarside.com/blog/macos/imac-m1-accent-colours-any-mac/)
       - https://mahdi.jp/apps/accents
    +- [Why always something is running at port 5000 on my mac](https://stackoverflow.com/q/72369320)
     
     ## Firefox