Giter VIP home page Giter VIP logo

flexobj's Introduction

FlexObj

Build Status codecov Go Report Card GoDoc

FlexObj makes storing the nested objects as easy as PHP associative array and it maintains the insertion order. It is most useful when handling the SQL database result set in golang.

Why?

I wanted to store the SQL database result set as a list of the nested objects in golang while maintaining the insertion order (especially when generating the reports). Then, outputs the data as a JSON string to the browser (JavaScript). Go's built-in hashmap does not keep the insertion order and require type assertion when retrieving the nested objects (which makes the codes look more verbose). So, I builded this tool to resolve my needs.

Features:

  • Maintain the insertion order
  • Output a FlexObj instance as a JSON string (MarshalJSON implements Marshaler)
  • Decode from a FlexObj instance to a struct (could be used to ensure the correct data type is used)
  • Deep clone from a FlexObj instance
  • Insertion-order iteration over the FlexObj instance
  • No type assertion is required when retrieving a nested object
  • Go 1.11 Modules support

Installation

  1. Download and install FlexObj:
$ go get -u github.com/junxie6/flexobj
  1. Import FlexObj in your code:
import (
	"github.com/junxie6/flexobj"
)

Examples:

Set some primitive type data (boolean, integer, float, string)

exampleSetPrimitiveType.go:

package main

import (
	"fmt"
)
import (
	"github.com/junxie6/flexobj"
)

func main() {
	data := flexobj.New()
	data.Set("ExamID", 1)
	data.Set("ExamName", "this is a 2018 exam")
	data.Set("IsDone", false)

	// Print data in JSON format
	fmt.Printf("Output: %s\n", data.JSONPretty())
}

JSON output:

{
    "ExamID": 1,
    "ExamName": "this is a 2018 exam",
    "IsDone": false
}

Set a hashmap data

exampleSetHashMap.go:

package main

import (
	"fmt"
)
import (
	"github.com/junxie6/flexobj"
)

func main() {
	data := flexobj.New()

	user := flexobj.New()
	user.Set("UserID", 5)
	user.Set("UserName", "Bot 1")

	data.SetObj("User", user)

	// Print data in JSON format
	fmt.Printf("Output: %s\n", data.JSONPretty())
}

JSON output:

{
    "User": {
        "UserID": 5,
        "UserName": "Bot 1"
    }
}

Set a ordered map data

exampleSetOrderedMap.go:

package main

import (
	"fmt"
)
import (
	"github.com/junxie6/flexobj"
)

func main() {
	data := flexobj.New()
	questionArr := flexobj.New()
	data.SetArr("QuestionArr", questionArr)

	q1 := flexobj.New()
	q1.Set("QuestionID", 1)
	q1.Set("QuestionName", "What is the best programming language?")
	questionArr.SetObj("1", q1)

	q2 := flexobj.New()
	q2.Set("QuestionID", 2)
	q2.Set("QuestionName", "What is the best editor?")
	questionArr.SetObj("2", q2)

	// Print data in JSON format
	fmt.Printf("Output: %s\n", data.JSONPretty())
}

JSON output:

{
    "QuestionArr": [
        {
            "QuestionID": 1,
            "QuestionName": "What is the best programming language?"
        },
        {
            "QuestionID": 2,
            "QuestionName": "What is the best editor?"
        }
    ]
}

Store the database result set and output it as a JSON string

exampleDatabaseResultSet.go:

package main

import (
	"fmt"
)
import (
	"github.com/junxie6/flexobj"
)

func main() {
	// Simulating a database result set
	sqlRow := []struct {
		ExamID       uint32
		ExamName     string
		QuestionID   uint32
		QuestionName string
		ChoiceID     uint32
		ChoiceName   string
		IsSelected   uint8
	}{
		{
			ExamID:       1,
			ExamName:     "this is a 2018 exam",
			QuestionID:   1,
			QuestionName: "What is the best programming language?",
			ChoiceID:     1,
			ChoiceName:   "Go",
			IsSelected:   1,
		},
		{
			ExamID:       1,
			ExamName:     "this is a 2018 exam",
			QuestionID:   1,
			QuestionName: "What is the best programming language?",
			ChoiceID:     2,
			ChoiceName:   "PHP",
			IsSelected:   0,
		},
		{
			ExamID:       1,
			ExamName:     "this is a 2018 exam",
			QuestionID:   2,
			QuestionName: "What is the best editor?",
			ChoiceID:     3,
			ChoiceName:   "Vim",
			IsSelected:   1,
		},
		{
			ExamID:       1,
			ExamName:     "this is a 2018 exam",
			QuestionID:   2,
			QuestionName: "What is the best editor?",
			ChoiceID:     4,
			ChoiceName:   "Visual Studio Code",
			IsSelected:   0,
		},
	}

	//
	flexobj.IsDebug = true

	data := flexobj.New()
	examID := ""
	questionID := ""
	choiceID := ""

	for _, row := range sqlRow {
		examID = flexobj.Uint32ToStr(row.ExamID)
		questionID = flexobj.Uint32ToStr(row.QuestionID)
		choiceID = flexobj.Uint32ToStr(row.ChoiceID)

		if data.IsSet(examID) != true {
			// Initialize an exam object
			exam := flexobj.New()
			exam.Set("ExamID", row.ExamID)
			exam.Set("ExamName", row.ExamName)
			exam.SetArr("QuestionArr", flexobj.New())

			data.SetObj(examID, exam)
		}

		if questionArr := data.GetObj(examID).GetArr("QuestionArr"); questionArr.IsSet(questionID) != true {
			// Initialize a question object
			question := flexobj.New()
			question.Set("QuestionID", row.QuestionID)
			question.Set("QuestionName", row.QuestionName)
			question.SetArr("ChoiceArr", flexobj.New())

			questionArr.SetObj(questionID, question)
		}

		if choiceArr := data.GetObj(examID).GetArr("QuestionArr").GetObj(questionID).GetArr("ChoiceArr"); choiceArr.IsSet(choiceID) != true {
			// Initialize a choice object
			choice := flexobj.New()
			choice.Set("ChoiceID", row.ChoiceID)
			choice.Set("ChoiceName", row.ChoiceName)
			choice.Set("IsSelected", row.IsSelected)

			choiceArr.SetObj(choiceID, choice)
		}
	}

	// Print data in JSON format
	fmt.Printf("Output: %s\n", data.JSONPretty())
}

JSON output:

{
    "1": {
        "ExamID": 1,
        "ExamName": "this is a 2018 exam",
        "QuestionArr": [
            {
                "QuestionID": 1,
                "QuestionName": "What is the best programming language?",
                "ChoiceArr": [
                    {
                        "ChoiceID": 1,
                        "ChoiceName": "Go",
                        "IsSelected": 1
                    },
                    {
                        "ChoiceID": 2,
                        "ChoiceName": "PHP",
                        "IsSelected": 0
                    }
                ]
            },
            {
                "QuestionID": 2,
                "QuestionName": "What is the best editor?",
                "ChoiceArr": [
                    {
                        "ChoiceID": 3,
                        "ChoiceName": "Vim",
                        "IsSelected": 1
                    },
                    {
                        "ChoiceID": 4,
                        "ChoiceName": "Visual Studio Code",
                        "IsSelected": 0
                    }
                ]
            }
        ]
    }
}

Store the nested objects and output it as a JSON string

exampleNestedObject.go:

package main

import (
	"fmt"
)
import (
	"github.com/junxie6/flexobj"
)

func main() {
	//
	exam_ExamID := "1"
	exam := flexobj.New()

	exam.Set("ExamID", flexobj.StrToUint32(exam_ExamID))
	exam.Set("ExamName", "this is a 2018 exam")

	// QuestionArr
	questionArr := flexobj.New()
	exam.SetArr("QuestionArr", questionArr)

	// Question 1
	q1_QuestionID := "1"
	q1 := flexobj.New()
	questionArr.SetObj(q1_QuestionID, q1)

	q1.Set("QuestionID", flexobj.StrToUint32(q1_QuestionID))
	q1.Set("QuestionName", "What is the best programming language?")

	// Question 1 - ChoiceArr
	q1_ChoiceArr := flexobj.New()
	q1.SetArr("ChoiceArr", q1_ChoiceArr)

	// Question 1 - Choice 1
	q1c1_ChoiceID := "1"
	q1c1 := flexobj.New()
	q1_ChoiceArr.SetObj(q1c1_ChoiceID, q1c1)

	q1c1.Set("ChoiceID", flexobj.StrToUint32(q1c1_ChoiceID))
	q1c1.Set("ChoiceName", "Go")
	q1c1.Set("IsSelected", 1)

	// Question 1 - Choice 2
	q1c2_ChoiceID := "2"
	q1c2 := flexobj.New()
	q1_ChoiceArr.SetObj(q1c2_ChoiceID, q1c2)

	q1c2.Set("ChoiceID", flexobj.StrToUint32(q1c2_ChoiceID))
	q1c2.Set("ChoiceName", "PHP")
	q1c2.Set("IsSelected", 0)

	// Print exam data in JSON format
	fmt.Printf("Output: %s\n", exam.JSONPretty())
}

JSON output:

{
    "ExamID": 1,
    "ExamName": "this is a 2018 exam",
    "QuestionArr": [
        {
            "QuestionID": 1,
            "QuestionName": "What is the best programming language?",
            "ChoiceArr": [
                {
                    "ChoiceID": 1,
                    "ChoiceName": "Go",
                    "IsSelected": 1
                },
                {
                    "ChoiceID": 2,
                    "ChoiceName": "PHP",
                    "IsSelected": 0
                }
            ]
        }
    ]
}

Clone

exampleClone.go:

package main

import (
	"fmt"
)
import (
	"github.com/junxie6/flexobj"
)

func main() {
	// Exam
	exam := flexobj.New()
	exam.Set("ExamID", 123456)
	exam.Set("ExamName", "this is a 2018 exam")

	// Clone data
	examCloned := flexobj.Clone(exam)

	// Set some value
	exam.Set("ExamName", "this is a 2019 exam")

	// Print exam data in JSON format
	fmt.Printf("exam: %s\n", exam.JSONPretty())
	fmt.Printf("examCloned: %s\n", examCloned.JSONPretty())
}

Output:

exam: {
    "ExamID": 123456,
    "ExamName": "this is a 2019 exam"
}
examCloned: {
    "ExamID": 123456,
    "ExamName": "this is a 2018 exam"
}

Iteration

exampleIteration.go:

package main

import (
	"fmt"
)
import (
	"github.com/junxie6/flexobj"
)

func main() {
	// Exam
	exam := flexobj.New()
	exam.Set("ExamID", 123456)
	exam.Set("ExamName", "this is a 2018 exam")

	// Interation
	for ; exam.Next(); exam.Increase() {
		fmt.Printf("%v: %v\n", exam.Key(), exam.Value())
	}
}

Output:

ExamID: 123456
ExamName: this is a 2018 exam

flexobj's People

Contributors

junxie6 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.