Esempio n. 1
0
        /// <summary>
        /// Get/create a named lock based on 'dbFullPath'
        /// Same 'dbFullPath' will get the same lock
        ///
        /// </summary>
        internal static SqlFsLocker getFsLocker(string dbFullPath)
        {
            lock (typeof(SqlFsLocker))
            {
                if (lockerTable == null)
                {
                    lockerTable = new Dictionary <string, SqlFsLocker>();
                }

                if (refCountTable == null)
                {
                    refCountTable = new Dictionary <string, int?>();
                }

                string      tableKey = SqlFsFunc.genHash(dbFullPath);
                SqlFsLocker locker   = lockerTable[tableKey];
                if (locker == null)
                {
                    locker = new SqlFsLocker(tableKey);
                    lockerTable[tableKey]   = locker;
                    refCountTable[tableKey] = 1;               // reference count 1
                }
                else
                {
                    // increase reference count by 1
                    int?count = refCountTable[tableKey];
                    refCountTable[tableKey] = (int)count + 1;
                }

                return(locker);
            }
        }
Esempio n. 2
0
        /// <summary>
        ///  Get a single info
        /// </summary>
        ///  <returns> info value </returns>
        private string __getInfo(string infoName)
        {
            string value  = null;
            string @where = SqlStr.genWhere(new SqlStr.SqlSimpCond(FSINFO.infoName.ToString(), "=", infoName));

            Cursor c = null;

            try
            {
                c = db.query(DBNAMES.FsInfo.ToString(), new string[] { FSINFO.infoVal.ToString() }, @where, null, null, null, null);

                if (c != null && c.moveToFirst())
                {
                    value = c.getString(0);
                }
            }
            catch (SQLiteException e)
            {
                SqlFsLog.debug(e);
                SqlFsErrCode.CurrentError = FsErr.GetFsInfoErr;
            }
            finally
            {
                SqlFsFunc.close(c);
            }

            return(value);
        }
Esempio n. 3
0
        ///  @param [in] absolute filePath -- e.g. "/path/to/file" </param>
        private SqlFile __getFile(string filePath)
        {
            if (SqlFsFunc.isNullOrEmpty(filePath))
            {
                SqlFsErrCode.CurrentError = FsErr.EmptyString;
                return(null);
            }

            if (!filePath.StartsWith(SqlFsConst.STRPATHSEP))        // must start with '/'
            {
                SqlFsErrCode.CurrentError = FsErr.MustUseAbsolutePath;
                return(null);
            }

            filePath = SqlFsFunc.Trim(filePath, new char[] { SqlFsConst.PATHSEP });

            SqlDir rootDir = RootDir;

            if (rootDir == null)
            {
                SqlFsErrCode.CurrentError = FsErr.CannotAccessRoot;
                return(null);
            }

            return(rootDir.getFile(filePath));
        }
Esempio n. 4
0
        /// <summary>
        ///  Test if a absolute path (dir/file) exists
        /// </summary>
        private bool __exists(string path)
        {
            if (SqlFsFunc.isNullOrEmpty(path))
            {
                SqlFsErrCode.CurrentError = FsErr.EmptyString;
                return(false);
            }

            if (!path.StartsWith(SqlFsConst.STRPATHSEP))        // must start with '/'
            {
                SqlFsErrCode.CurrentError = FsErr.MustUseAbsolutePath;
                return(false);
            }

            path = SqlFsFunc.Trim(path, new char[] { SqlFsConst.PATHSEP });
            if (SqlFsFunc.isNullOrEmpty(path))        // if empty after trim, it refers to root
            {
                return(true);
            }

            SqlDir rootDir = RootDir;

            if (rootDir == null)
            {
                SqlFsErrCode.CurrentError = FsErr.CannotAccessRoot;
                return(false);
            }

            SqlFsNode fsNode = rootDir.getFsNode(path);

            return(fsNode != null);
        }
Esempio n. 5
0
        ///  @param [in] absolute dirPath -- e.g. "/path/to/dir" </param>
        private SqlDir __getDir(string dirPath)
        {
            if (SqlFsFunc.isNullOrEmpty(dirPath))
            {
                SqlFsErrCode.CurrentError = FsErr.EmptyString;
                return(null);
            }

            if (!dirPath.StartsWith(SqlFsConst.STRPATHSEP))        // must start with '/'
            {
                SqlFsErrCode.CurrentError = FsErr.MustUseAbsolutePath;
                return(null);
            }

            dirPath = SqlFsFunc.Trim(dirPath, new char[] { SqlFsConst.PATHSEP });
            SqlDir rootDir = RootDir;

            if (rootDir == null)
            {
                SqlFsErrCode.CurrentError = FsErr.CannotAccessRoot;
                return(null);
            }

            if (SqlFsFunc.isNullOrEmpty(dirPath))        // if empty after trim, it refers to root
            {
                return(rootDir);
            }

            return(rootDir.getDir(dirPath));
        }
Esempio n. 6
0
        /// <summary>
        ///  Get the last (autoIncrement) rowID after a 'INSERT'
        /// </summary>
        internal static FsID getLastInsertID(SQLiteDatabase db)
        {
            // retrieve the ID of the new entry
            FsID   newID = SqlFsConst.INVALIDID;
            string sql   = "SELECT last_insert_rowid() as [id]";
            Cursor c     = null;

            try
            {
                c = db.rawQuery(sql, null);
                if (c.moveToFirst())
                {
                    newID = SqlFsFunc.getID(c, 0);
                }
            }
            catch (Exception e)
            {
                SqlFsLog.debug(e);
                SqlFsErrCode.CurrentError = FsErr.GetLastInsertIDError;
            }
            finally
            {
                SqlFsFunc.close(c);
            }

            return(newID);
        }
Esempio n. 7
0
        //////////////////////////FS operations ///////////////////////////////////

        ///  @param [in] id -- get entry using ID directly </param>
        internal static SqlFsNode getFsNodeByID(SQLiteDatabase db, SqlFsLocker fsLocker, FsID id)
        {
            SqlFsNode fsNode = null;

            string @where = SqlStr.genWhere(new SqlStr.SqlSimpCond(SqlFs.FSBLOCK.fsID.ToString(), "=", id));
            Cursor c      = null;

            try
            {
                c = db.query(SqlFs.DBNAMES.FsBlock.ToString(), new string[] { SqlFs.FSBLOCK.fsID.ToString(), SqlFs.FSBLOCK.fsType.ToString() }, @where, null, null, null, null);

                if (c.moveToFirst())
                {
                    fsNode = SqlFsNode.getFsNode(db, fsLocker, c);
                }
            }
            catch (Exception e)
            {
                SqlFsLog.debug(e);
                SqlFsErrCode.CurrentError = FsErr.GetFieldError;
            }
            finally
            {
                SqlFsFunc.close(c);
            }

            return(fsNode);
        }
Esempio n. 8
0
        /// <summary>
        ///  Check if a dir/file name contains invalid character
        /// </summary>
        ///  @param [in] name -- contains dir/file name to be checked
        ///                      on return, it contains a whitespace-trimmed version
        /// </param>
        ///  <returns> null -- contains invalid characters </returns>
        ///  <returns> String -- may be modified name </returns>
        protected internal virtual string checkInvalidChars(string name)
        {
            if (SqlFsFunc.isNullOrEmpty(name))
            {
                return(null);
            }

            string trimmedStr = SqlFsFunc.Trim(name, SqlFsConst.CHARSTOTRIM);

            if (SqlFsFunc.isNullOrEmpty(trimmedStr))        // check once again
            {
                return(null);
            }

            if (SqlFsFunc.indexOfAny(trimmedStr, SqlFsConst.INVALIDCHARS) >= 0)
            {
                return(null);
            }

            if (trimmedStr.Equals(SqlFsConst.CURDIR))        // can't be '.'
            {
                return(null);
            }

            if (trimmedStr.Equals(SqlFsConst.PARENTDIR))        // can't be '..'
            {
                return(null);
            }

            return(trimmedStr);
        }
Esempio n. 9
0
        /// <summary>
        ///  Create a new entry in FsBlock
        /// </summary>
        ///  <returns> new ID for the inserted node </returns>
        internal static FsID addFsNode(SQLiteDatabase db, SqlFsConst.FSTYPE type, string dirName, FsID parentID)
        {
            long          curTime       = SqlFsFunc.calToFileTime(new DateTime());
            List <object> colsAndValues = new List <object>(10);

            colsAndValues.Add(SqlFs.FSBLOCK.fsCreateTime.ToString());
            colsAndValues.Add(curTime);
            colsAndValues.Add(SqlFs.FSBLOCK.fsLastModTime.ToString());
            colsAndValues.Add(curTime);
            colsAndValues.Add(SqlFs.FSBLOCK.fsFileSize.ToString());
            colsAndValues.Add(0);
            colsAndValues.Add(SqlFs.FSBLOCK.fsType.ToString());
            colsAndValues.Add(type.v());
            colsAndValues.Add(SqlFs.FSBLOCK.fsName.ToString());
            colsAndValues.Add(dirName);
            colsAndValues.Add(SqlFs.FSBLOCK.fsParent.ToString());
            colsAndValues.Add(parentID);

            ContentValues contValues = SqlStr.genContentValues(colsAndValues);

            try
            {
                db.insert(SqlFs.DBNAMES.FsBlock.ToString(), null, contValues);
            }
            catch (Exception e)
            {
                SqlFsLog.debug(e);
                SqlFsErrCode.CurrentError = FsErr.AddFsNodeError;
                return(SqlFsConst.INVALIDID);
            }

            // retrieve the ID of the new entry
            return(SqlFs.getLastInsertID(db));
        }
Esempio n. 10
0
        ///  @param [in] relative filePath -- e.g. "path/to/file" </param>
        private SqlFile __getFile(string filePath)
        {
            if (SqlFsFunc.isNullOrEmpty(filePath))
            {
                SqlFsErrCode.CurrentError = FsErr.EmptyString;
                return(null);
            }

            if (filePath.StartsWith(SqlFsConst.STRPATHSEP) || filePath.EndsWith(SqlFsConst.STRPATHSEP))        // must *NOT* start or end with '/'
            {
                SqlFsErrCode.CurrentError = FsErr.MustNotStartOrEndWithPathSeparator;
                return(null);
            }

            string[] dirSeg = filePath.Split(SqlFsConst.STRPATHSEP, true);
            if (dirSeg == null || dirSeg.Length <= 0)
            {
                SqlFsErrCode.CurrentError = FsErr.SplitPathErr;
                return(null);
            }

            SqlFsNode curNode = this;

            // start looping to target file
            for (int i = 0; i < dirSeg.Length; ++i)
            {
                if (SqlFsFunc.isNullOrEmpty(dirSeg[i]))           // to prevent empty space between separator
                {
                    continue;
                }

                curNode = ((SqlDir)curNode).__getChild(dirSeg[i]);
                if (i == dirSeg.Length - 1)
                {
                    if (curNode == null || curNode.Dir)              // last one must be a file
                    {
                        curNode = null;
                        SqlFsErrCode.CurrentError = FsErr.ChildNotFound;
                        break;
                    }
                }
                else
                {
                    if (curNode == null || !curNode.Dir)              // others' should be dir
                    {
                        curNode = null;
                        SqlFsErrCode.CurrentError = FsErr.NotDirInPath;
                        break;
                    }
                }
            }

            return((SqlFile)curNode);
        }
Esempio n. 11
0
        ///  @param [in] relative dirPath -- e.g. "path/to/dir" </param>
        private SqlFsNode __getFsNode(string path)
        {
            if (SqlFsFunc.isNullOrEmpty(path))
            {
                SqlFsErrCode.CurrentError = FsErr.EmptyString;
                return(null);
            }

            if (path.StartsWith(SqlFsConst.STRPATHSEP))        // must *NOT* start with '/'
            {
                SqlFsErrCode.CurrentError = FsErr.MustUseRelativePath;
                return(null);
            }

            if (path.EndsWith(SqlFsConst.STRPATHSEP))        // trim trailing '/'
            {
                path = SqlFsFunc.trimEnd(path, new char[] { SqlFsConst.PATHSEP });
            }

            string[] pathSeg = path.Split(SqlFsConst.STRPATHSEP, true);
            if (pathSeg == null || pathSeg.Length <= 0)
            {
                SqlFsErrCode.CurrentError = FsErr.SplitPathErr;
                return(null);
            }

            SqlFsNode curNode = this;

            // start looping to target node
            for (int i = 0; i < pathSeg.Length; ++i)
            {
                if (SqlFsFunc.isNullOrEmpty(pathSeg[i]))           // to prevent empty space between separator
                {
                    continue;
                }

                curNode = ((SqlDir)curNode).__getChild(pathSeg[i]);
                if (curNode == null)
                {
                    SqlFsErrCode.CurrentError = FsErr.ChildNotFound;
                    break;
                }

                if (!curNode.Dir && i != pathSeg.Length - 1)           // if a file but not reach the end yet
                {
                    curNode = null;
                    SqlFsErrCode.CurrentError = FsErr.NotDirInPath;
                    break;
                }
            }

            return(curNode);
        }
Esempio n. 12
0
        /// <summary>
        ///  Check existence of tables
        /// </summary>
        ///  <returns> true -- all tables present </returns>
        ///  <returns> false -- should create new tables </returns>
        private bool checkTables()
        {
            int tabCount = 0;

            string @where = SqlStr.genWhere(new SqlStr.SqlSimpCond(DBNAMES.type.ToString(), "=", DBNAMES.table.ToString())
                                            );

            Cursor c = db.query(DBNAMES.SQLITE_MASTER.ToString(), new string[] { DBNAMES.name.ToString() }, @where, null, null, null, null);

            // retrieve all table names and check against our list
            if (c != null && c.moveToFirst())
            {
                do
                {
                    string tabName = c.getString(0);
                    foreach (string n in TABLIST)
                    {
                        if (n.Equals(tabName, StringComparison.CurrentCultureIgnoreCase))
                        {
                            tabCount += 1;
                            break;
                        }
                    }
                } while (c.moveToNext());
            }
            SqlFsFunc.close(c);

            bool isCheckingOK = false;

            do
            {
                // not all tables exists, may be some corruption ...
                if (tabCount < TABLIST.Length)
                {
                    break;
                }

                // may be more checking here ...


                isCheckingOK = true;
            } while (false);

            if (tabCount != 0 && !isCheckingOK)
            {
                close();
                backup();
                open();
            }

            return(isCheckingOK);
        }
Esempio n. 13
0
        ///  @param [in] relative dirPath -- e.g. "path/to/dir" </param>
        private SqlDir __getDir(string dirPath)
        {
            if (SqlFsFunc.isNullOrEmpty(dirPath))
            {
                SqlFsErrCode.CurrentError = FsErr.EmptyString;
                return(null);
            }

            if (dirPath.StartsWith(SqlFsConst.STRPATHSEP))        // must *NOT* start with '/'
            {
                SqlFsErrCode.CurrentError = FsErr.MustUseRelativePath;
                return(null);
            }

            if (dirPath.EndsWith(SqlFsConst.STRPATHSEP))        // trim trailing '/'
            {
                dirPath = SqlFsFunc.trimEnd(dirPath, new char[] { SqlFsConst.PATHSEP });
            }

            string[] dirSeg = dirPath.Split(SqlFsConst.STRPATHSEP, true);
            if (dirSeg == null || dirSeg.Length <= 0)
            {
                SqlFsErrCode.CurrentError = FsErr.SplitPathErr;
                return(null);
            }

            SqlFsNode curNode = this;

            // start looping to target dir
            foreach (string dir in dirSeg)
            {
                if (SqlFsFunc.isNullOrEmpty(dir))           // to prevent empty space between separator
                {
                    continue;
                }

                curNode = ((SqlDir)curNode).__getChild(dir);
                if (curNode == null || !curNode.Dir)
                {
                    curNode = null;
                    SqlFsErrCode.CurrentError = FsErr.ChildNotFound;
                    break;
                }
            }


            return((SqlDir)curNode);
        }
Esempio n. 14
0
        /// <summary>
        ///  Save field to DB using ID
        /// </summary>
        private bool __setField(SqlFs.FSBLOCK field, object val)
        {
            List <object> colsAndValues = new List <object>(4);

            switch (field)
            {
            case com.sss.sqlfs.SqlFs.FSBLOCK.fsFileSize:
            case com.sss.sqlfs.SqlFs.FSBLOCK.fsType:
            case com.sss.sqlfs.SqlFs.FSBLOCK.fsName:
            case com.sss.sqlfs.SqlFs.FSBLOCK.fsParent:
                colsAndValues.Add(field.ToString());
                colsAndValues.Add(val);
                break;

            case com.sss.sqlfs.SqlFs.FSBLOCK.fsChild:
                sbyte[] blob = idList2Blob((List <FsID>)val);
                colsAndValues.Add(field.ToString());
                colsAndValues.Add(blob);
                break;
            }

            // update last mod time as well
            colsAndValues.Add(SqlFs.FSBLOCK.fsLastModTime.ToString());
            colsAndValues.Add(SqlFsFunc.calToFileTime(new DateTime()));
            ContentValues contValues = SqlStr.genContentValues(colsAndValues);

            string @where = SqlStr.genWhere(new SqlStr.SqlSimpCond(SqlFs.FSBLOCK.fsID.ToString(), "=", this.ID));

            int rowAffected = 0;

            try
            {
                rowAffected = db.update(SqlFs.DBNAMES.FsBlock.ToString(), contValues, @where, null);
            }
            catch (Exception e)
            {
                SqlFsLog.debug(e);
                SqlFsErrCode.CurrentError = FsErr.SetFieldError;
            }

            return(rowAffected > 0);
        }
Esempio n. 15
0
        /// <summary>
        ///  Move itself to a destination path (absolute or relative)
        /// </summary>
        private bool __move(string destPath)
        {
            if (SqlFsFunc.isNullOrEmpty(destPath))
            {
                SqlFsErrCode.CurrentError = FsErr.EmptyString;
                return(false);
            }

            // determine destination dir
            SqlDir destDir = null;

            if (destPath.StartsWith(SqlFsConst.STRPATHSEP))
            {
                // absolute path
                SqlDir rootDir = (SqlDir)SqlFs.getFsNodeByID(db, fsLocker, SqlFsConst.ROOTDIRID);           // get root
                destPath = SqlFsFunc.Trim(destPath, new char[] { SqlFsConst.PATHSEP });
                // if empty after trim, it refers to root
                destDir = SqlFsFunc.isNullOrEmpty(destPath) ? rootDir : rootDir.getDir(destPath);
            }
            else
            {
                // relative path
                SqlDir parent = this.Parent;
                if (parent != null)
                {
                    destDir = parent.getDir(destPath);
                }
            }

            if (destDir != null)
            {
                return(__move(destDir));
            }

            SqlFsErrCode.CurrentError = FsErr.DestDirNotFound;
            return(false);
        }
Esempio n. 16
0
        internal static SqlDir getDir(SQLiteDatabase db, SqlFsLocker fsLocker, Cursor c)
        {
            FsID id = SqlFsFunc.getID(c, SqlFs.FSBLOCK.fsID.ordinal());

            return(SqlDir.getDir(db, fsLocker, id));
        }
Esempio n. 17
0
        /// <summary>
        ///  Get a field from DB using ID
        /// </summary>
        private object __getField(SqlFs.FSBLOCK field)
        {
            string @where = SqlStr.genWhere(new SqlStr.SqlSimpCond(SqlFs.FSBLOCK.fsID.ToString(), "=", this.ID));

            // little adjustment
            SqlFs.FSBLOCK tField = (field == SqlFs.FSBLOCK.fsChildCount) ? SqlFs.FSBLOCK.fsChild : field;
            Cursor        c      = null;
            object        val    = null;

            try
            {
                c = db.query(SqlFs.DBNAMES.FsBlock.ToString(), new string[] { tField.ToString() }, @where, null, null, null, null);

                if (c.moveToFirst() && !c.isNull(0))
                {
                    switch (field)
                    {
                    case com.sss.sqlfs.SqlFs.FSBLOCK.fsCreateTime:
                    case com.sss.sqlfs.SqlFs.FSBLOCK.fsLastModTime:
                        val = c.getLong(0);
                        break;

                    case com.sss.sqlfs.SqlFs.FSBLOCK.fsFileSize:
                    case com.sss.sqlfs.SqlFs.FSBLOCK.fsType:
                        val = c.getInt(0);
                        break;

                    case com.sss.sqlfs.SqlFs.FSBLOCK.fsName:
                        val = c.getString(0);
                        break;

                    case com.sss.sqlfs.SqlFs.FSBLOCK.fsParent:
                        val = SqlFsFunc.getID(c, 0);
                        break;

                    case com.sss.sqlfs.SqlFs.FSBLOCK.fsChild:
                    {
                        sbyte[] buf = c.getBlob(0);
                        val = blob2idList(buf);
                    }
                    break;

                    case com.sss.sqlfs.SqlFs.FSBLOCK.fsChildCount:
                    {
                        sbyte[] buf = c.getBlob(0);
                        val = buf.Length / FsID.IDSize;
                    }
                    break;
                    }
                }
                else
                {
                    val = __getDefaultValue(field);
                }
            }
            catch (Exception e)
            {
                SqlFsLog.debug(e);
                SqlFsErrCode.CurrentError = FsErr.GetFieldError;
                val = __getDefaultValue(field);                 // return a default value here
            }
            finally
            {
                SqlFsFunc.close(c);
            }

            return(val);
        }