예제 #1
0
// Load all rows of a table into RA result.
func (r *Result) Load(t *table.Table) (*Result, int) {
	_, exists := r.Tables[t.Name]
	if exists {
		return r, st.TableAlreadyExists
	}
	// rowNumbers = list(range(t.NumberOfRows()))
	rowNumbers := make([]int, 0)
	numberOfRows, status := t.NumberOfRows()
	if status != st.OK {
		return r, status
	}
	for i := 0; i < numberOfRows; i++ {
		rowNumbers = append(rowNumbers[:], i)
	}
	r.Tables[t.Name] = &TableResult{t, rowNumbers}
	// Load columns of the table.
	for columnName, _ := range t.Columns {
		if !strings.HasPrefix(columnName, constant.ThePrefix) {
			_, exists := r.Aliases[columnName]
			if exists {
				logg.Warn("ra", "Load", "Column name "+columnName+" duplicates an existing alias")
			}
			r.Aliases[columnName] = &TableColumn{t.Name, columnName}
		}
	}
	return r, st.OK
}
예제 #2
0
// Returns existing shared and exclusive locks of a table.
func LocksOf(t *table.Table) (*Locks, int) {
	// Read files in .shared directory.
	sharedLocksPath := t.Path + t.Name + ".shared"
	sharedLocksDir, err := os.Open(sharedLocksPath)
	if err != nil {
		return nil, st.CannotReadSharedLocksDir
	}
	defer sharedLocksDir.Close()
	fi, err := sharedLocksDir.Readdir(0)
	if err != nil {
		logg.Err("transaction", "LocksOf", err)
		return nil, st.CannotReadSharedLocksDir
	}
	locks := new(Locks)
	locks.Shared = make([]int64, 0)
	for _, fileInfo := range fi {
		// File name represents a transaction ID (also a timestamp).
		theID, err := strconv.ParseInt(fileInfo.Name(), 10, 64)
		// tt := time.Now().Nanosecond() + constant.LockTimeout
		if err != nil || theID > int64(time.Now().Nanosecond()+constant.LockTimeout) {
			// Remove expired shared lock.
			err = os.Remove(sharedLocksPath + "/" + fileInfo.Name())
			logg.Warn("transaction", "LocksOf", "Expired shared lock ID "+
				fileInfo.Name()+" file "+sharedLocksPath+"/"+fileInfo.Name()+" is removed")
			if err != nil {
				logg.Err("transaction", "LocksOf", err)
				return nil, st.CannotUnlockSharedLock
			}
		} else {
			locks.Shared = append(locks.Shared[:], theID)
		}
	}
	// Read the content of exclusive lock.
	exclusiveLockPath := t.Path + t.Name + ".exclusive"
	exclusiveFile, err := os.Open(exclusiveLockPath)
	if err != nil {
		return locks, st.OK
	}
	fi2, err := exclusiveFile.Stat()
	if err != nil {
		logg.Err("transaction", "LocksOf", err)
		return nil, st.CannotReadExclusiveLocksFile
	}
	// The file content is a transaction ID
	buffer := make([]byte, fi2.Size())
	_, err = exclusiveFile.Read(buffer)
	if err != nil {
		logg.Err("transaction", "LocksOf", err)
		return nil, st.CannotReadExclusiveLocksFile
	}
	theID, err := strconv.ParseInt(string(buffer), 10, 64)

	if err != nil || theID > int64(time.Now().Nanosecond()+constant.LockTimeout) {
		// Remove expired exclusive lock.
		err = os.Remove(exclusiveLockPath)
		logg.Debug("transaction", "LocksOf", err)
		logg.Warn("transaction", "LocksOf", "Expired exclusive lock ID "+
			string(buffer)+" file "+exclusiveLockPath+" is removed")
		if err != nil {
			logg.Err("transaction", "LocksOf", err)
			return nil, st.CannotUnlockExclusiveLock
		}
	} else {
		locks.Exclusive = theID
	}
	return locks, st.OK
}