text:
/**
 *
 * @author qinxuewu
 * @create 19/6/25下午8:28
 * @since 1.0.0
 */
package main

import (
	"github.com/jinzhu/gorm"
	_ "github.com/jinzhu/gorm/dialects/mysql"
	"fmt"
)

type Users struct {
	ID        uint `gorm:"primary_key"`
	Name string
	Age int
}

func main()  {
	dbs,_:=gorm.Open("mysql", "root:870439570@tcp(39.108.144.143:3306)/test?charset=utf8&parseTime=True&loc=Local")
	defer dbs.Close()
	// 检测指定表是否存在
	falg:=dbs.HasTable(&Users{})
	fmt.Println("指定表表名是否存在: ",falg)

	// 自动迁移模式
	dbs.AutoMigrate(&Users{})

	user := Users{Name: "qxw", Age: 18}
	dbs.Create(&user)

	// 获取第一条记录，按主键排序
	dbs.First(&user)
	//// SELECT * FROM users ORDER BY id LIMIT 1;

	fmt.Println("获取第一条记录，按主键排序:",user)

	// 获取最后一条记录，按主键排序
	dbs.Last(&user)
	fmt.Println("获取最后一条记录，按主键排序:",user)
	//// SELECT * FROM users ORDER BY id DESC LIMIT 1;
	users := []Users{}
	// 获取所有记录
	dbs.Find(&users)
	fmt.Println("获取所有记录: ",users)
	//// SELECT * FROM users;

	// 使用主键获取记录
	dbs.First(&user, 1)
	fmt.Println("使用主键获取记录:",user)

	// SELECT * FROM users WHERE id = 1;

	//Where(dbs)
	//WhereStruct(dbs)
	//WherNot(dbs)
	//WhereParms(dbs)
	//WhereOr(dbs)
	//WHereLinkd(dbs)
	//WhereSet(dbs)
	//WhereFirstOrInit(dbs)
	WhereAttrs(dbs)
}

func Where(db *gorm.DB)  {
	user := Users{}
	users := []Users{}

	// 获取第一个匹配记录
	db.Where("name = ?", "jinzhu").First(&user)
	// SELECT * FROM users WHERE name = 'jinzhu' limit 1;

	// 获取所有匹配记录
	db.Where("name = ?", "jinzhu").Find(&users)
	for i, v := range users {
		fmt.Println("index :", i, v.Name)
	}
	// SELECT * FROM users WHERE name = 'jinzhu';

	db.Where("name <> ?", "jinzhu").Find(&users)

	// IN
	db.Where("name in (?)", []string{"jinzhu", "jinzhu 2"}).Find(&users)

	// LIKE
	db.Where("name LIKE ?", "%jin%").Find(&users)

	// AND
	db.Where("name = ? AND age >= ?", "jinzhu", "22").Find(&users)

	// Time
	db.Where("age > ?").Find(&users)

}

// 当使用struct查询时，GORM将只查询那些具有值的字段
func WhereStruct(db *gorm.DB)  {
	user := Users{}
	users := []Users{}

	// 使用Struct查询
	db.Where(&Users{Name:"jinzhu",Age:20}).First(&user)
    // SELECT * FROM users WHERE name = 'jinzhu' AND age=20;
	fmt.Println("使用Struct查询 :",user)

	// 使用Map 查询
	db.Where(map[string]interface{}{"name":"jinzhu","age":20}).First(&user)

	fmt.Println("使用Map 查询 :",user)

	// 主键的Slice

	db.Where([]int64{1,2,3}).Find(&users)
	//	SELECT * FROM users WHERE id IN (1 2, 3);

	fmt.Println("使用主键的Slice查询 :",users)
}

// Not条件查询
func WherNot(db *gorm.DB)  {
	user := Users{}
	users := []Users{}
	db.Not("name","jinzhu").First(&user)
	// SELECT * FROM users WHERE name <> "jinzhu" LIMIT 1

	fmt.Println("使用Not查询 :",user)

	// Not In
	db.Not("name",[]string{"jinzhu","qxw"}).Find(&users)
	// SELECT * FROM users WHERE name NOT IN ("jinzhu", "qxw");

	// 使用主键查询模式的 not in
	db.Not([]int64{1,2,3}).Find(&users)
	// SELECT * FROM users WHERE id NOT IN (1,2,3);

	db.Not([]int64{}).First(&user) // SELECT * FROM users;

	//not和sql拼接查询
	db.Not("name = ?", "jinzhu").First(&user)
	// SELECT * FROM users WHERE NOT(name = "jinzhu");

	// Struct not查询
	db.Not(Users{Name: "jinzhu"}).First(&user)
	// SELECT * FROM users WHERE name <> "jinzhu";
}

// 带内联条件的查询  占位符 参数
// 使用主键查询时，应仔细检查所传递的值是否为有效主键，以避免SQL注入
func WhereParms(db *gorm.DB)  {
	user := Users{}
	users := []Users{}

	// 主键查询
	db.First(&user,23) //  SELECT * FROM users WHERE id = 23 LIMIT 1;

	// 简单sql查询 占位符
	db.Find(&users,"name = ?","jinzhu")
	// SELECT * FROM users WHERE name = "jinzhu";

	db.Find(&users, "name <> ? AND age > ?", "jinzhu", 20)
	// SELECT * FROM users WHERE name <> "jinzhu" AND age > 20;

	db.Find(&users,Users{Age:20})
	// SELECT * FROM users WHERE age = 20;

	// map多条件查询
	db.Find(&users,map[string]interface{}{"age":20})
	// SELECT * FROM users WHERE age = 20;
}
// Or条件查询
func WhereOr(db *gorm.DB)  {

	users := []Users{}
	db.Where("name = ?","jinzhu").Or("name = ?","qxw").Find(&users)
	// select *  from users where name='jinzhu' or name='qxw';

	// Struct结构体查询
	db.Where("name = jinzhu").Or(Users{Name:"qxw"}).Find(&users)
	// SELECT * FROM users WHERE name = 'jinzhu' OR name = 'qxw';

	// Map多条件查询
	db.Where("name = 'jinzhu'").Or(map[string]interface{}{"name":"qxw"}).Find(&users)
}

//  Gorm有一个可链接的API，你可以这样使用它
func WHereLinkd(db *gorm.DB)  {
	users := []Users{}

	db.Where("name <> ?","jinzhu").Where("age >= ? ",20).Find(&users)

//	SELECT * FROM users WHERE name <> 'jinzhu' AND age >= 20 ;

    db.Where("name = ?","jinzhu").Or("age =?",20).Not("name = ?","qxw")
//	 select * from name='jinzhu' or age=20 and name <> 'qxw';
}

// 扩展查询选项
func WhereSet(db *gorm.DB)  {
	user := Users{}

	// 为Select语句添加扩展SQL选项  排它锁
	db.Set("gorm:query_option", "FOR UPDATE").First(&user, 10)
	//// SELECT * FROM users WHERE id = 10 FOR UPDATE;
}

// 获取第一个匹配的记录，或者使用给定的条件初始化一个新的记录（仅适用于struct，map条件）
func WhereFirstOrInit(db *gorm.DB)  {
	user := Users{}
	// 未查询导数据 则返回指定的初始化数据
	db.FirstOrInit(&user,Users{Name:"non_existing"})
	fmt.Println(user)
	// user -> User{Name: "non_existing"}

   //  查询有返回数据 则直接返回
	db.Where(Users{Name:"jinzhu"}).FirstOrInit(&user)
	fmt.Println(user)
	// user -> User{Id: 111, Name: "Jinzhu", Age: 20}

	db.FirstOrInit(&user, map[string]interface{}{"name": "jinzhu"})
	fmt.Println(user)
	// user -> User{Id: 111, Name: "Jinzhu", Age: 20}
}

// 如果未找到记录，则使用参数初始化结构
func WhereAttrs(db *gorm.DB)  {
	user := Users{}

	// 未查询到数据 则返回参数初始化结构
	db.Where(Users{Name:"non_qxwsss"}).Attrs(Users{Age:20}).FirstOrInit(&user)
	// SELECT * FROM USERS WHERE name = 'non_qxwsss';
	// user -> User{Name: "non_qxwsss", Age: 20}

	//或
	db.Where(Users{Name: "non_existing"}).Attrs("age", 20).FirstOrInit(&user)
	// SELECT * FROM USERS WHERE name = 'non_existing';
	// user -> User{Name: "non_existing", Age: 20}

	// 查询到数据。 则直接返回查询的数据 忽略参数初始化的数据
	db.Where(Users{Name: "Jinzhu"}).Attrs(Users{Age: 30}).FirstOrInit(&user)

//	如果未找到记录，则为参数分配结构 也就是创建新记录

   // 未查询到 先添加 然后返回
   db.Where(Users{Name:"non_extisting"}).Attrs(Users{Age:20}).FirstOrCreate(&user)
	// SELECT * FROM users WHERE name = 'non_existing';
	// INSERT INTO "users" (name, age) VALUES ("non_existing", 20);
	// 最后返回数据   user -> User{Id: 112, Name: "non_existing", Age: 20}

	//  查询到数据则直接返回查询的数据
	db.Where(Users{Name: "jinzhu"}).Attrs(Users{Age: 30}).FirstOrCreate(&user)
	// SELECT * FROM users WHERE name = 'jinzhu';
	// user -> User{Id: 111, Name: "jinzhu", Age: 20}
}

//  将参数分配给结果，不管它是否被找到
func WhereAssign(db *gorm.DB)  {
	user := Users{}
	db.Where(Users{Name: "non_existing"}).Assign(Users{Age: 20}).FirstOrInit(&user)
	// user -> User{Name: "non_existing", Age: 20}

	db.Where(Users{Name: "Jinzhu"}).Assign(Users{Age: 30}).FirstOrInit(&user)
	// SELECT * FROM USERS WHERE name = jinzhu';
	// user -> User{Id: 111, Name: "Jinzhu", Age: 30}

	//  将其分配给记录，而不管它是否被找到，并保存回数据库。

	// 未查询到数据 就添加 然后返回
	db.Where(Users{Name: "non_existing"}).Assign(Users{Age: 20}).FirstOrCreate(&user)
	// SELECT * FROM users WHERE name = 'non_existing';
	// INSERT INTO "users" (name, age) VALUES ("non_existing", 20);
	// user -> User{Id: 112, Name: "non_existing", Age: 20}

	// 查询到数据 就更新 并返回更新后的数据
	db.Where(Users{Name: "jinzhu"}).Assign(Users{Age: 30}).FirstOrCreate(&user)
	// SELECT * FROM users WHERE name = 'jinzhu';
	// UPDATE users SET age=30 WHERE id = 111;
	// user -> User{Id: 111, Name: "jinzhu", Age: 30}

}
// 获取第一个匹配的记录，或创建一个具有给定条件的新记录（仅适用于struct, map条件）
func WhereFirstOrCreate(db *gorm.DB)  {
	user := Users{}

	// 未查询到数据 则添加并返回
	db.FirstOrCreate(&user,Users{Name:"non_extisting"})
	// INSERT INTO "users" (name) VALUES ("non_existing");
	// user -> User{Id: 112, Name: "non_existing"}

	//  查询到数据则直接返回
	db.Where(Users{Name: "Jinzhu"}).FirstOrCreate(&user)
	// user -> User{Id: 111, Name: "Jinzhu"}
}

// 指定要从数据库检索的字段，默认情况下，将选择所有字段;
func WhereSelect(db *gorm.DB)  {
	users := []Users{}
	db.Select("name","age").Find(&users);
    //   SELECT name, age FROM users;

    db.Select([]string{"name","age"}).Find(&users)
	//   SELECT name, age FROM users;

	db.Table("users").Select("COALESCE(age,?)",42).Rows()
    //  SELECT COALESCE(age,'42') FROM users;
}

// 在从数据库检索记录时指定顺序，将重排序设置为true以覆盖定义的条件
func WhereOrder(db *gorm.DB)  {
//	 SELECT * FROM users ORDER BY age desc, name;

	users := []Users{}
	db.Order("age desc").Order("name").Find(&users)

	users1 := []Users{}
	users2 := []Users{}
	db.Order("age desc").Find(&users1).Order("age",true).Find(&users2)
	// SELECT * FROM users ORDER BY age desc; (users1)
	// SELECT * FROM users ORDER BY age; (users2)
}
// 指定要检索的记录数
func WhereLimit(db *gorm.DB) {

	users := []Users{}
	db.Limit(3).Find(&users)
	// SELECT * FROM users LIMIT 3;

	users1 := []Users{}
	users2 := []Users{}
	db.Limit(10).Find(&users1).Limit(-1).Find(&users2)
	// SELECT * FROM users LIMIT 10; (users1)
	// SELECT * FROM users; (users2)
}

// 指定在开始返回记录之前要跳过的记录数
func WhereOffset(db *gorm.DB)  {
	users := []Users{}
	db.Offset(3).Find(&users)
	//  SELECT * FROM users OFFSET 3;

	users1 := []Users{}
	users2 := []Users{}
	db.Offset(10).Find(&users1).Offset(-1).Find(&users2)
	// SELECT * FROM users OFFSET 10; (users1)
	// SELECT * FROM users; (users2)
}

func WhereGroupHaving(db *gorm.DB)  {
	rows, _ :=db.Table("users").Select("name,sum(age) as totalAge").Group("name").Rows()
	for rows.Next() {
		var id uint
		var name string
		var age int
		rows.Scan(&id, &name, &age)
		fmt.Println(id,name,age)
	}

	rows2,_:=db.Table("users").Select("name").Group("name").Having("count(name) > ?", 1).Rows()
	for  rows2.Next()  {
		var id uint
		var name string
		var age int
		rows2.Scan(&id, &name, &age)
		fmt.Println(id,name,age)
	}
}

type Result struct {
	Name string
	Email string
}

//  指定连接条件
func WhereJoin(db *gorm.DB)  {
	rows, _ := db.Table("users").Select("users.name, emails.email").Joins("left join emails on emails.user_id = users.id").Rows()
	for rows.Next() {

	}
	results:=[]Result{};
	db.Table("users").Select("users.name, emails.email").Joins("left join emails on emails.user_id = users.id").Scan(&results)

}

//  Save将包括执行更新SQL时的所有字段，即使它没有更改
// 如果只想更新更改的字段，可以使用Update, Updates
func SaveUpdate(db *gorm.DB)  {
	user := Users{}
	db.First(&user)

	user.Name = "jinzhu 2"
	user.Age = 100
	db.Save(&user)

	// UPDATE users SET name='jinzhu 2', age=100 WHERE id=111;

	// 更新单个属性（如果更改）
	db.Model(&user).Update("name", "hello")
	// UPDATE users SET name='hello'  WHERE id=111;

	// 使用组合条件更新单个属性
	db.Model(&user).Where("age = ?", 20).Update("name", "hello")

	// UPDATE users SET name='hello' WHERE id=111 AND age=20;

	// 使用`map`更新多个属性，只会更新这些更改的字段
	db.Model(&user).Updates(map[string]interface{}{"name": "hello", "age": 18,})
	//// UPDATE users SET name='hello', age=18   WHERE id=111;

	// 使用`struct`更新多个属性，只会更新这些更改的和非空白字段
	db.Model(&user).Updates(Users{Name: "hello", Age: 18})
	// UPDATE users SET name='hello', age=18,  WHERE id = 111;

	// 警告:当使用struct更新时，FORM将仅更新具有非空值的字段
	// 对于下面的更新，什么都不会更新为""，0，false是其类型的空白值
	db.Model(&user).Updates(Users{Name: "", Age: 0})

//	 如果您只想在更新时更新或忽略某些字段，可以使用Select, Omit

	db.Model(&user).Select("name").Updates(map[string]interface{}{"name": "hello", "age": 18})
	// UPDATE users SET name='hello'  WHERE id=111;

	db.Model(&user).Omit("name").Updates(map[string]interface{}{"name": "hello", "age": 18})
	// UPDATE users SET age=18  WHERE id=111;

	// 更新更改字段但不进行Callbacks
	// 更新多个属性，与“更新”类似
	db.Model(&user).UpdateColumns(Users{Name: "hello", Age: 18})
	// UPDATE users SET name='hello', age=18 WHERE id = 111;

}

// 指定表名
func WhereTable(db *gorm.DB)  {

	//  使用User结构定义创建`deleted_users`表
	user := Users{}
	db.Table("deleted_users").CreateTable(&user)

	var deleted_users []Users
	db.Table("deleted_users").Find(&deleted_users)
	// SELECT * FROM deleted_users;

	//  Batch Updates 批量更新
	db.Table("users").Where("id IN (?)",[]int{10,11}).Update(map[string]interface{}{"name":"hello","age":18})
	// UPDATE users SET name='hello', age=18 WHERE id IN (10, 11);

	// 使用struct更新仅适用于非零值，或使用map[string]interface{}
	db.Model(Users{}).Updates(Users{Name: "hello", Age: 18})
	// UPDATE users SET name='hello', age=18;

	// 使用`RowsAffected`获取更新记录计数
	count:=db.Model(Users{}).Update(Users{Name:"hello",Age:15}).RowsAffected
	fmt.Println(count)

	// 批量删除
	db.Where("email LIke ?","%jinzhu%").Delete(Users{})
	db.Delete(Users{}, "email LIKE ?", "%jinzhu%")
	// DELETE from emails where email LIKE "%jinhu%";

	// 软删除 如果模型有DeletedAt字段，它将自动获得软删除功能！
	db.Delete(&user)
	// UPDATE users SET deleted_at="2013-10-29 10:23" WHERE id = 111;

	// 批量删除
	db.Where("age = ?", 20).Delete(&Users{})
	// UPDATE users SET deleted_at="2013-10-29 10:23" WHERE age = 20;

	// 软删除的记录将在查询时被忽略
	db.Where("age = 20").Find(&user)
	// SELECT * FROM users WHERE age = 20 AND deleted_at IS NULL;
}

repository: mrqinxw/Go-notes

repo_name: mrqinxw/Go-notes


text:
package timing

import (
	"sort"
	"sync"
	"time"
)

// num define
const (
	OneShot = 1
	Persist = 0
)

// DefaultJobChanSize default job chan size
const (
	DefaultJobChanSize = 2048
)

type mdEntry struct {
	entry    *Entry
	interval time.Duration
}

// Timing keeps track of any number of entries.
type Timing struct {
	entries      []*Entry
	stop         chan struct{}
	add          chan *Entry
	remove       chan *Entry
	active       chan mdEntry
	snapshot     chan chan []Entry
	useGoroutine bool
	pf           func(err interface{})
	jobs         chan Job
	jobsChanSize int
	running      bool
	mu           sync.Mutex
	location     *time.Location
	logger
}

// New new a time with option
func New(opts ...Option) *Timing {
	tim := &Timing{
		entries:      make([]*Entry, 0),
		add:          make(chan *Entry),
		remove:       make(chan *Entry),
		active:       make(chan mdEntry),
		stop:         make(chan struct{}),
		snapshot:     make(chan chan []Entry),
		location:     time.Local,
		pf:           func(err interface{}) {},
		jobsChanSize: DefaultJobChanSize,
		logger:       newLogger("timing: "),
	}

	for _, opt := range opts {
		opt(tim)
	}
	tim.jobs = make(chan Job, tim.jobsChanSize)
	return tim
}

// Location gets the time zone location
func (sf *Timing) Location() *time.Location {
	return sf.location
}

// Close the time
func (sf *Timing) Close() error {
	sf.mu.Lock()
	defer sf.mu.Unlock()
	if sf.running {
		sf.stop <- struct{}{}
		sf.running = false
	}
	return nil
}

// HasRunning 运行状态
func (sf *Timing) HasRunning() bool {
	sf.mu.Lock()
	defer sf.mu.Unlock()
	return sf.running
}

// Entries returns a snapshot of the Timing entries.
func (sf *Timing) Entries() []Entry {
	sf.mu.Lock()
	defer sf.mu.Unlock()
	if sf.running {
		replyChan := make(chan []Entry, 1)
		sf.snapshot <- replyChan
		return <-replyChan
	}
	return sf.entrySnapshot()
}

// AddJob add a job
func (sf *Timing) AddJob(job Job, num uint32, interval time.Duration) *Entry {
	entry := NewEntry(job, num, interval)

	sf.mu.Lock()
	defer sf.mu.Unlock()
	if sf.running {
		sf.add <- entry
	} else {
		sf.entries = append(sf.entries, entry)
	}
	return entry
}

// AddJobFunc add a job function
func (sf *Timing) AddJobFunc(f JobFunc, num uint32, interval time.Duration) *Entry {
	return sf.AddJob(f, num, interval)
}

// AddOneShotJob  add one-shot job
func (sf *Timing) AddOneShotJob(job Job, interval time.Duration) *Entry {
	return sf.AddJob(job, OneShot, interval)
}

// AddOneShotJobFunc add one-shot job function
func (sf *Timing) AddOneShotJobFunc(f JobFunc, interval time.Duration) *Entry {
	return sf.AddJob(f, OneShot, interval)
}

// AddPersistJob add persist job
func (sf *Timing) AddPersistJob(job Job, interval time.Duration) *Entry {
	return sf.AddJob(job, Persist, interval)
}

// AddPersistJobFunc add persist job function
func (sf *Timing) AddPersistJobFunc(f JobFunc, interval time.Duration) *Entry {
	return sf.AddJob(f, Persist, interval)
}

// Start start the entry
func (sf *Timing) Start(e *Entry, newInterval ...time.Duration) {
	if e == nil {
		return
	}

	sf.mu.Lock()
	defer sf.mu.Unlock()

	val := append(newInterval, -1)[0]
	if sf.running {
		sf.active <- mdEntry{e, val}
	} else if val > 0 {
		e.interval = val
		if !sf.hasEntry(e) {
			sf.entries = append(sf.entries, e)
		}
	}
}

// Remove entry form timing
func (sf *Timing) Remove(e *Entry) {
	if e == nil {
		return
	}
	sf.mu.Lock()
	defer sf.mu.Unlock()
	if sf.running {
		sf.remove <- e
	} else {
		sf.removeEntry(e)
	}
}

// Run the timing in its own goroutine, or no-op if already started.
func (sf *Timing) Run() *Timing {
	sf.mu.Lock()
	defer sf.mu.Unlock()
	if sf.running {
		return sf
	}
	sf.running = true
	go sf.run()
	return sf
}

func (sf *Timing) wrapJob(job Job) {
	defer func() {
		if err := recover(); err != nil {
			sf.pf(err)
		}
	}()

	job.Run()
}

func (sf *Timing) run() {
	sf.Debug("run start!")

	Now := func() time.Time { return time.Now().In(sf.location) }

	// Figure out the next activation times for each entry.
	now := Now()
	for _, entry := range sf.entries {
		entry.next = now.Add(entry.interval)
		sf.Debug("next active: now - %s, next - %s", now, entry.next)
	}
	closed := make(chan struct{})
	go func() {
		sf.Debug("work start!")
		for {
			select {
			case f := <-sf.jobs:
				sf.wrapJob(f)
			case <-closed:
				sf.Debug("work stop!")
				return
			}
		}
	}()

	for {
		// Determine the next entry to run.
		sort.Sort(byTime(sf.entries))

		var timer *time.Timer
		if len(sf.entries) == 0 || sf.entries[0].next.IsZero() {
			// If there are no entries yet, just sleep -
			//it still handles new entries and stop requests.
			timer = time.NewTimer(100000 * time.Hour)
		} else {
			timer = time.NewTimer(sf.entries[0].next.Sub(now))
		}

		for {
			select {
			case now = <-timer.C:
				now = now.In(sf.location)
				sf.Debug("wake up: now - %s", now)

				// Run every entry whose next time was less than now
				for _, e := range sf.entries {
					if e.next.After(now) || e.next.IsZero() {
						break
					}
					sf.Debug("run: now - %s, next - %s, entry - %p", now, e.next, e)
					if sf.useGoroutine {
						go e.job.Run()
					} else {
						sf.jobs <- e.job
					}
					e.count++
					if e.number == 0 || e.count < e.number {
						e.prev = e.next
						e.next = now.Add(e.interval)
					} else {
						e.next = time.Time{} // mark it, not work until remove it
					}
				}
			case newEntry := <-sf.add:
				timer.Stop()
				now = Now()
				newEntry.next = now.Add(newEntry.interval)
				sf.entries = append(sf.entries, newEntry)
				sf.Debug("added: now - %s, next - %s, entry - %p",
					now, newEntry.next, newEntry)
			case mdEntry := <-sf.active:
				timer.Stop()
				entry := mdEntry.entry
				if mdEntry.interval > 0 { // if interval < 0 only active entry
					entry.interval = mdEntry.interval
				}
				if !sf.hasEntry(entry) {
					sf.entries = append(sf.entries, entry)
				}
				now = Now()
				entry.next = now.Add(entry.interval)
				sf.Debug("actived: now - %s, next - %s, entry - %p",
					now, entry.next, entry)
			case e := <-sf.remove:
				timer.Stop()
				now = Now()
				sf.removeEntry(e)
				sf.Debug("removed: entry - %p", e)

			case replyChan := <-sf.snapshot:
				replyChan <- sf.entrySnapshot()
				continue

			case <-sf.stop:
				closed <- struct{}{}
				timer.Stop()
				sf.Debug("run stop!")
				return
			}

			break
		}
	}
}

func (sf *Timing) hasEntry(e *Entry) bool {
	for _, v := range sf.entries {
		if e == v {
			return true
		}
	}
	return false
}

func (sf *Timing) removeEntry(e *Entry) {
	entries := make([]*Entry, 0, len(sf.entries))
	for _, v := range sf.entries {
		if e != v {
			entries = append(entries, v)
		}
	}
	sf.entries = entries
}

// entrySnapshot returns a copy of the current cron entry list.
func (sf *Timing) entrySnapshot() []Entry {
	var entries = make([]Entry, len(sf.entries))
	for i, e := range sf.entries {
		entries[i] = *e
	}
	return entries
}

license: MIT

license_type: permissive

branch_name: refs/heads/master

extension: go


text:
DESCRIPTION = "ZIQ"
SECTION = "opie/games"
PRIORITY = "optional"
LICENSE = "GPL"
AUTHOR = "Bill Wetter"
HOMEPAGE = "http://www.linux-solutions.at/projects/zaurus/games-ZIQ.html"

SRC_URI = "http://handhelds.org/~zecke/oe_packages/ziq_V1.1ern.tar.gz \
           file://ziq.patch"

PV = "1.1ern"
PR = "r1"
S = "${WORKDIR}/ziq_V${PV}"

APPNAME = "ziq"
APPTYPE = "binary"
APPDESKTOP = "${S}"

do_install () {
	install -d ${D}${palmtopdir}/apps/Games/
	install -d ${D}${palmtopdir}/pics/${APPNAME}/
	install -d ${D}${palmtopdir}/apps/Games
	install -m 0644 ${S}/*.png ${D}${palmtopdir}/pics/${APPNAME}/
	install -m 0644 ${S}/${APPNAME}.desktop ${D}${palmtopdir}/apps/Games
}

inherit opie

SRC_URI[md5sum] = "f8c6b4b8b5b6f62ec9fc117e4b35fd53"
SRC_URI[sha256sum] = "995a52223365ec41ae72ef781bde2c8f2f34e0e5dd19e17245f5f354ac52fb8b"

repository: overo/overo-oe-natty

repo_name: overo/overo-oe-natty

branch_name: HEAD

extension: bb


text:
Complexity|MSE|Equation
1|1064.938|BR
3|669.0702|(RPM / NOB)
5|634.98334|(RPM / (NOB + -0.51159126))
9|633.2941|((((RPM + 1.1004119) / 0.7932469) / NOB) - NOB)
15|519.1426|((0.26046887 / (((Db * (Dc * Dc)) * NOB) + -1.9892224)) * (RPM + BR))
17|504.72968|(((0.26046887 / (((Db * (Dc * Dc)) * NOB) + -1.9896896)) * (RPM + BR)) + Db)

branch_name: refs/heads/main

extension: bkup


text:
@Book{,
  Title                    = {GMP-Berater},
  Publisher                = {Maas und Peither GMP Verl.},
  Year                     = {2014},
  Address                  = {Schopfheim},
  Number                   = {L - N},
  Volume                   = {Bd. I},
  Editor                   = {Anita Maas},
  Pagetotal                = {Losebl.-Ausg.},
  Ppn_GVK                  = {797485368},
  Subtitle                 = {Nachschlagewerk für Pharmaindustrie und Lieferanten. Die praxisorientierte Loseblattsammlung für die Gute Herstellungspraxis (Good Manufacturing Practice)}
}

repository: JabRef/jabref

repo_name: JabRef/jabref

gha_license_id: MIT

gha_language: Java

extension: bib