예제 #1
0
// Drops a table.
func (db *Database) Drop(name string) int {
	_, exists := db.Tables[name]
	if !exists {
		return st.TableNotFound
	}
	// db.Tables[name] = nil, false
	delete(db.Tables, name)
	// Remove table files and directories.
	return tablefilemanager.Delete(db.Path, name)
}
예제 #2
0
// Rebuild data file, get rid off removed rows, optionally leaves space for a new column.
func (table *Table) RebuildDataFile(name string, length int) int {
	// Create a temporary table named by an accurate timestamp.
	tempName := strconv.Itoa(time.Now().Nanosecond())
	// tempName := strconv.Itoa(time.Nanosecond)

	tablefilemanager.Create(table.Path, tempName)
	var tempTable *Table
	tempTable, status := Open(table.Path, tempName)
	if status != st.OK {
		return status
	}
	// Put all columns of this table to the temporary table.
	for _, column := range table.ColumnsInOrder {
		tempTable.Add(column.Name, column.Length)
	}
	// Add the new column into the table as well.
	if name != "" {
		tempTable.Add(name, length)
	}
	var numberOfRows int
	numberOfRows, status = table.NumberOfRows()
	if status != st.OK {
		return status
	}
	var everFailed bool
	if name == "" {
		// If no new column, simply copy rows from this table to the temp table.
		for i := 0; i < numberOfRows; i++ {
			row, ret := table.Read(i)
			if ret != st.OK {
				everFailed = true
			}
			if row["~del"] != "y" {
				tempTable.Insert(row)
			}
		}
	} else {
		// If adding new column, not only copy rows from this table to the temporary one.
		// Also leave space for the new column's values.
		for i := 0; i < numberOfRows; i++ {
			row, ret := table.Read(i)
			if ret != st.OK {
				everFailed = true
			}
			if row["~del"] != "y" {
				row[name] = ""
				tempTable.Insert(row)
			}
		}
	}
	// Flush all the changes made to temporary table.
	status = tempTable.Flush()
	if everFailed || status != st.OK {
		return st.FailedToCopyCertainRows
	}
	// Delete the old table (one that is rebuilt), and rename the temporary
	// table to the name of the rebuilt table.
	status = tablefilemanager.Delete(table.Path, table.Name)
	if status == st.OK {
		status = tablefilemanager.Rename(table.Path, tempName, table.Name)
		if status == st.OK {
			// Files have been changed, thus re-open file handles.
			return table.OpenFiles()
		}
	}
	return st.OK
}